001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.master; 019 020import org.apache.hadoop.hbase.HConstants; 021import org.apache.hadoop.hbase.TableName; 022import org.apache.hadoop.hbase.regionserver.AnnotationReadingPriorityFunction; 023import org.apache.hadoop.hbase.regionserver.RSRpcServices; 024import org.apache.hadoop.hbase.security.User; 025import org.apache.yetus.audience.InterfaceAudience; 026 027import org.apache.hbase.thirdparty.com.google.protobuf.Message; 028 029import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 030import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos; 031import org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos; 032import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos; 033 034/** 035 * Priority function specifically for the master. This doesn't make the super users always priority 036 * since that would make everything to the master into high priority. Specifically when reporting 037 * that a region is in transition master will try and edit the meta table. That edit will block the 038 * thread until successful. However if at the same time meta is also moving then we need to ensure 039 * that the regular region that's moving isn't blocking processing of the request to online meta. To 040 * accomplish this this priority function makes sure that all requests to transition meta are 041 * handled in different threads from other report region in transition calls. After HBASE-21754, 042 * ReportRegionStateTransitionRequest for meta region will be assigned a META_QOS , a separate 043 * executor called metaTransitionExecutor will execute it. Other transition request will be executed 044 * in priorityExecutor to prevent being mixed with normal requests 045 */ 046@InterfaceAudience.Private 047public class MasterAnnotationReadingPriorityFunction extends AnnotationReadingPriorityFunction { 048 049 public static final int META_TRANSITION_QOS = 300; 050 051 public MasterAnnotationReadingPriorityFunction(final RSRpcServices rpcServices) { 052 this(rpcServices, rpcServices.getClass()); 053 } 054 055 public MasterAnnotationReadingPriorityFunction(RSRpcServices rpcServices, 056 Class<? extends RSRpcServices> clz) { 057 super(rpcServices, clz); 058 } 059 060 @Override 061 public int getPriority(RPCProtos.RequestHeader header, Message param, User user) { 062 // Yes this is copy pasted from the base class but it keeps from having to look in the 063 // annotatedQos table twice something that could get costly since this is called for 064 // every single RPC request. 065 int priorityByAnnotation = getAnnotatedPriority(header); 066 if (priorityByAnnotation >= 0) { 067 // no one can have higher priority than meta transition. 068 if (priorityByAnnotation >= META_TRANSITION_QOS) { 069 return META_TRANSITION_QOS - 1; 070 } else { 071 return priorityByAnnotation; 072 } 073 } 074 075 // If meta is moving then all the other of reports of state transitions will be 076 // un able to edit meta. Those blocked reports should not keep the report that opens meta from 077 // running. Hence all reports of meta transition should always be in a different thread. 078 // This keeps from deadlocking the cluster. 079 if (param instanceof RegionServerStatusProtos.ReportRegionStateTransitionRequest) { 080 // Regions are moving. Lets see which ones. 081 RegionServerStatusProtos.ReportRegionStateTransitionRequest tRequest = 082 (RegionServerStatusProtos.ReportRegionStateTransitionRequest) param; 083 for (RegionServerStatusProtos.RegionStateTransition rst : tRequest.getTransitionList()) { 084 if (rst.getRegionInfoList() != null) { 085 for (HBaseProtos.RegionInfo info : rst.getRegionInfoList()) { 086 TableName tn = ProtobufUtil.toTableName(info.getTableName()); 087 if (TableName.META_TABLE_NAME.equals(tn)) { 088 return META_TRANSITION_QOS; 089 } 090 } 091 } 092 } 093 return HConstants.HIGH_QOS; 094 } 095 // also use HIGH_QOS for region server report 096 if (param instanceof RegionServerStatusProtos.RegionServerReportRequest) { 097 return HConstants.HIGH_QOS; 098 } 099 100 // Handle the rest of the different reasons to change priority. 101 return getBasePriority(header, param); 102 } 103}