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. 036 * 037 * This doesn't make the super users always priority since that would make everything 038 * to the master into high priority. 039 * 040 * Specifically when reporting that a region is in transition master will try and edit the meta 041 * table. That edit will block the thread until successful. However if at the same time meta is 042 * also moving then we need to ensure that the regular region that's moving isn't blocking 043 * processing of the request to online meta. To accomplish this this priority function makes sure 044 * that all requests to transition meta are handled in different threads from other report region 045 * in transition calls. 046 * After HBASE-21754, ReportRegionStateTransitionRequest for meta region will be assigned a META_QOS 047 * , a separate executor called metaTransitionExecutor will execute it. Other transition request 048 * will be executed in priorityExecutor to prevent being mixed with normal requests 049 */ 050@InterfaceAudience.Private 051public class MasterAnnotationReadingPriorityFunction extends AnnotationReadingPriorityFunction { 052 053 public static final int META_TRANSITION_QOS = 300; 054 055 public MasterAnnotationReadingPriorityFunction(final RSRpcServices rpcServices) { 056 this(rpcServices, rpcServices.getClass()); 057 } 058 059 060 public MasterAnnotationReadingPriorityFunction(RSRpcServices rpcServices, 061 Class<? extends RSRpcServices> clz) { 062 super(rpcServices, clz); 063 } 064 065 @Override 066 public int getPriority(RPCProtos.RequestHeader header, Message param, User user) { 067 // Yes this is copy pasted from the base class but it keeps from having to look in the 068 // annotatedQos table twice something that could get costly since this is called for 069 // every single RPC request. 070 int priorityByAnnotation = getAnnotatedPriority(header); 071 if (priorityByAnnotation >= 0) { 072 // no one can have higher priority than meta transition. 073 if (priorityByAnnotation >= META_TRANSITION_QOS) { 074 return META_TRANSITION_QOS - 1; 075 } else { 076 return priorityByAnnotation; 077 } 078 } 079 080 // If meta is moving then all the other of reports of state transitions will be 081 // un able to edit meta. Those blocked reports should not keep the report that opens meta from 082 // running. Hence all reports of meta transition should always be in a different thread. 083 // This keeps from deadlocking the cluster. 084 if (param instanceof RegionServerStatusProtos.ReportRegionStateTransitionRequest) { 085 // Regions are moving. Lets see which ones. 086 RegionServerStatusProtos.ReportRegionStateTransitionRequest tRequest = 087 (RegionServerStatusProtos.ReportRegionStateTransitionRequest) param; 088 for (RegionServerStatusProtos.RegionStateTransition rst : tRequest.getTransitionList()) { 089 if (rst.getRegionInfoList() != null) { 090 for (HBaseProtos.RegionInfo info : rst.getRegionInfoList()) { 091 TableName tn = ProtobufUtil.toTableName(info.getTableName()); 092 if (TableName.META_TABLE_NAME.equals(tn)) { 093 return META_TRANSITION_QOS; 094 } 095 } 096 } 097 } 098 return HConstants.HIGH_QOS; 099 } 100 // also use HIGH_QOS for region server report 101 if (param instanceof RegionServerStatusProtos.RegionServerReportRequest) { 102 return HConstants.HIGH_QOS; 103 } 104 105 // Handle the rest of the different reasons to change priority. 106 return getBasePriority(header, param); 107 } 108}