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 edu.umd.cs.findbugs.annotations.NonNull; 021import java.io.IOException; 022import java.time.Duration; 023import java.util.List; 024import java.util.Map; 025import org.apache.hadoop.conf.Configuration; 026import org.apache.hadoop.hbase.ClusterMetrics; 027import org.apache.hadoop.hbase.ServerName; 028import org.apache.hadoop.hbase.Stoppable; 029import org.apache.hadoop.hbase.TableName; 030import org.apache.hadoop.hbase.client.RegionInfo; 031import org.apache.hadoop.hbase.conf.ConfigurationObserver; 032import org.apache.hadoop.hbase.master.balancer.ClusterInfoProvider; 033import org.apache.yetus.audience.InterfaceAudience; 034 035/** 036 * Makes decisions about the placement and movement of Regions across RegionServers. 037 * <p/> 038 * Cluster-wide load balancing will occur only when there are no regions in transition and according 039 * to a fixed period of a time using {@link #balanceCluster(Map)}. 040 * <p/> 041 * On cluster startup, bulk assignment can be used to determine locations for all Regions in a 042 * cluster. 043 * <p/> 044 * This class produces plans for the {@code AssignmentManager} to execute. 045 * <p/> 046 * About locking: 047 * <ul> 048 * <li>We will first call {@link #setClusterInfoProvider(ClusterInfoProvider)} and then 049 * {@link #initialize()} to initialize the balancer, and before calling {@link #initialize()}, we 050 * will never call any methods of this balancer. So these two methods do not need to be 051 * synchronized.</li> 052 * <li>The {@link #balanceCluster(Map)} method will use the {@link ClusterMetrics} which is set by 053 * {@link #updateClusterMetrics(ClusterMetrics)}, and also lots of configurations, which could be 054 * changed by {@link #onConfigurationChange(Configuration)}, so the easier way is to make these 055 * three methods synchronized. And since there will be only one balancing thread, this will not 056 * impact performance too much.</li> 057 * <li>The {@link #roundRobinAssignment(List, List)}, {@link #retainAssignment(Map, List)} and 058 * {@link #randomAssignment(RegionInfo, List)} could be called from multiple threads concurrently, 059 * so these three methods should not be synchronized, the implementation classes need to make sure 060 * that they are thread safe.</li> 061 * </ul> 062 */ 063@InterfaceAudience.Private 064public interface LoadBalancer extends Stoppable, ConfigurationObserver { 065 066 // Used to signal to the caller that the region(s) cannot be assigned 067 // We deliberately use 'localhost' so the operation will fail fast 068 ServerName BOGUS_SERVER_NAME = ServerName.valueOf("localhost,1,1"); 069 070 /** 071 * Config for pluggable load balancers. 072 * @deprecated since 3.0.0, will be removed in 4.0.0. In the new implementation, as the base load 073 * balancer will always be the rs group based one, you should just use 074 * {@link org.apache.hadoop.hbase.HConstants#HBASE_MASTER_LOADBALANCER_CLASS} to 075 * config the per group load balancer. 076 */ 077 @Deprecated 078 String HBASE_RSGROUP_LOADBALANCER_CLASS = "hbase.rsgroup.grouploadbalancer.class"; 079 080 /** 081 * Configuration to determine the time to sleep when throttling (if throttling is implemented by 082 * the underlying implementation). 083 */ 084 String MOVE_THROTTLING = "hbase.master.balancer.move.throttlingMillis"; 085 086 /** 087 * The default value, in milliseconds, for the hbase.master.balancer.move.throttlingMillis if 088 * throttling is implemented. 089 */ 090 Duration MOVE_THROTTLING_DEFAULT = Duration.ofMillis(60 * 1000); 091 092 /** 093 * Set the current cluster status. This allows a LoadBalancer to map host name to a server 094 */ 095 void updateClusterMetrics(ClusterMetrics metrics); 096 097 /** 098 * Set the cluster info provider. Usually it is just a wrapper of master. 099 */ 100 void setClusterInfoProvider(ClusterInfoProvider provider); 101 102 /** 103 * Perform the major balance operation for cluster. 104 * @param loadOfAllTable region load of servers for all table 105 * @return a list of regions to be moved, including source and destination, or null if cluster is 106 * already balanced 107 */ 108 List<RegionPlan> balanceCluster(Map<TableName, Map<ServerName, List<RegionInfo>>> loadOfAllTable) 109 throws IOException; 110 111 /** 112 * Perform a Round Robin assignment of regions. 113 * @return Map of servername to regioninfos 114 */ 115 @NonNull 116 Map<ServerName, List<RegionInfo>> roundRobinAssignment(List<RegionInfo> regions, 117 List<ServerName> servers) throws IOException; 118 119 /** 120 * Assign regions to the previously hosting region server 121 * @return List of plans 122 */ 123 @NonNull 124 Map<ServerName, List<RegionInfo>> retainAssignment(Map<RegionInfo, ServerName> regions, 125 List<ServerName> servers) throws IOException; 126 127 /** 128 * Get a random region server from the list 129 * @param regionInfo Region for which this selection is being done. 130 */ 131 ServerName randomAssignment(RegionInfo regionInfo, List<ServerName> servers) throws IOException; 132 133 /** 134 * Initialize the load balancer. Must be called after setters. 135 */ 136 void initialize() throws IOException; 137 138 /** 139 * Marks the region as online at balancer. 140 */ 141 void regionOnline(RegionInfo regionInfo, ServerName sn); 142 143 /** 144 * Marks the region as offline at balancer. 145 */ 146 void regionOffline(RegionInfo regionInfo); 147 148 /** 149 * Notification that config has changed 150 */ 151 @Override 152 void onConfigurationChange(Configuration conf); 153 154 /** 155 * If balancer needs to do initialization after Master has started up, lets do that here. 156 */ 157 void postMasterStartupInitialize(); 158 159 /* Updates balancer status tag reported to JMX */ 160 void updateBalancerStatus(boolean status); 161 162 /** 163 * In some scenarios, Balancer needs to update internal status or information according to the 164 * current tables load 165 * @param loadOfAllTable region load of servers for all table 166 */ 167 default void 168 updateBalancerLoadInfo(Map<TableName, Map<ServerName, List<RegionInfo>>> loadOfAllTable) { 169 } 170 171 default void throttle(RegionPlan plan) throws Exception { 172 // noop 173 } 174}