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 public MasterAnnotationReadingPriorityFunction(final RSRpcServices rpcServices) { 053 this(rpcServices, rpcServices.getClass()); 054 } 055 056 057 public MasterAnnotationReadingPriorityFunction(RSRpcServices rpcServices, 058 Class<? extends RSRpcServices> clz) { 059 super(rpcServices, clz); 060 } 061 062 @Override 063 public int getPriority(RPCProtos.RequestHeader header, Message param, User user) { 064 // Yes this is copy pasted from the base class but it keeps from having to look in the 065 // annotatedQos table twice something that could get costly since this is called for 066 // every single RPC request. 067 int priorityByAnnotation = getAnnotatedPriority(header); 068 if (priorityByAnnotation >= 0) { 069 return priorityByAnnotation; 070 } 071 072 // If meta is moving then all the other of reports of state transitions will be 073 // un able to edit meta. Those blocked reports should not keep the report that opens meta from 074 // running. Hence all reports of meta transitioning should always be in a different thread. 075 // This keeps from deadlocking the cluster. 076 if (param instanceof RegionServerStatusProtos.ReportRegionStateTransitionRequest) { 077 // Regions are moving. Lets see which ones. 078 RegionServerStatusProtos.ReportRegionStateTransitionRequest 079 tRequest = (RegionServerStatusProtos.ReportRegionStateTransitionRequest) param; 080 for (RegionServerStatusProtos.RegionStateTransition rst : tRequest.getTransitionList()) { 081 if (rst.getRegionInfoList() != null) { 082 for (HBaseProtos.RegionInfo info : rst.getRegionInfoList()) { 083 TableName tn = ProtobufUtil.toTableName(info.getTableName()); 084 if (TableName.META_TABLE_NAME.equals(tn)) { 085 return HConstants.META_QOS; 086 } 087 } 088 } 089 } 090 return HConstants.HIGH_QOS; 091 } 092 093 // Handle the rest of the different reasons to change priority. 094 return getBasePriority(header, param); 095 } 096}