7878import org .apache .hadoop .hbase .TableNotDisabledException ;
7979import org .apache .hadoop .hbase .TableNotFoundException ;
8080import org .apache .hadoop .hbase .UnknownRegionException ;
81+ import org .apache .hadoop .hbase .client .Admin ;
8182import org .apache .hadoop .hbase .client .ColumnFamilyDescriptor ;
8283import org .apache .hadoop .hbase .client .MasterSwitchType ;
8384import org .apache .hadoop .hbase .client .RegionInfo ;
220221import org .apache .hbase .thirdparty .com .google .common .collect .ImmutableSet ;
221222import org .apache .hbase .thirdparty .com .google .common .collect .Lists ;
222223import org .apache .hbase .thirdparty .com .google .common .collect .Maps ;
224+ import org .apache .hbase .thirdparty .org .apache .commons .collections4 .CollectionUtils ;
223225
224226import org .apache .hadoop .hbase .shaded .protobuf .ProtobufUtil ;
225227import org .apache .hadoop .hbase .shaded .protobuf .generated .AdminProtos .GetRegionInfoResponse .CompactionState ;
@@ -364,7 +366,7 @@ public void run() {
364366 volatile boolean serviceStarted = false ;
365367
366368 // Maximum time we should run balancer for
367- private final int maxBlancingTime ;
369+ private final int maxBalancingTime ;
368370 // Maximum percent of regions in transition when balancing
369371 private final double maxRitPercent ;
370372
@@ -524,7 +526,7 @@ public HMaster(final Configuration conf)
524526 // preload table descriptor at startup
525527 this .preLoadTableDescriptors = conf .getBoolean ("hbase.master.preload.tabledescriptors" , true );
526528
527- this .maxBlancingTime = getMaxBalancingTime ();
529+ this .maxBalancingTime = getMaxBalancingTime ();
528530 this .maxRitPercent = conf .getDouble (HConstants .HBASE_MASTER_BALANCER_MAX_RIT_PERCENT ,
529531 HConstants .DEFAULT_HBASE_MASTER_BALANCER_MAX_RIT_PERCENT );
530532
@@ -1638,21 +1640,36 @@ public boolean balance() throws IOException {
16381640 return balance (false );
16391641 }
16401642
1641- public boolean balance (boolean force ) throws IOException {
1642- // if master not initialized, don't run balancer.
1643+ /**
1644+ * Checks master state before initiating action over region topology.
1645+ * @param action the name of the action under consideration, for logging.
1646+ * @return {@code true} when the caller should exit early, {@code false} otherwise.
1647+ */
1648+ private boolean skipRegionManagementAction (final String action ) {
16431649 if (!isInitialized ()) {
1644- LOG .debug ("Master has not been initialized, don't run balancer." );
1645- return false ;
1650+ LOG .debug ("Master has not been initialized, don't run {}." , action );
1651+ return true ;
1652+ }
1653+ if (this .getServerManager ().isClusterShutdown ()) {
1654+ LOG .info ("Cluster is shutting down, don't run {}." , action );
1655+ return true ;
16461656 }
1647-
16481657 if (isInMaintenanceMode ()) {
1649- LOG .info ("Master is in maintenanceMode mode, don't run balancer." );
1658+ LOG .info ("Master is in maintenance mode, don't run {}." , action );
1659+ return true ;
1660+ }
1661+ return false ;
1662+ }
1663+
1664+ public boolean balance (boolean force ) throws IOException {
1665+ if (loadBalancerTracker == null || !loadBalancerTracker .isBalancerOn ()) {
1666+ return false ;
1667+ }
1668+ if (skipRegionManagementAction ("balancer" )) {
16501669 return false ;
16511670 }
16521671
16531672 synchronized (this .balancer ) {
1654- // If balance not true, don't run balancer.
1655- if (!this .loadBalancerTracker .isBalancerOn ()) return false ;
16561673 // Only allow one balance run at at time.
16571674 if (this .assignmentManager .hasRegionsInTransition ()) {
16581675 List <RegionStateNode > regionsInTransition = assignmentManager .getRegionsInTransition ();
@@ -1701,6 +1718,11 @@ public boolean balance(boolean force) throws IOException {
17011718
17021719 List <RegionPlan > plans = this .balancer .balanceCluster (assignments );
17031720
1721+ if (skipRegionManagementAction ("balancer" )) {
1722+ // make one last check that the cluster isn't shutting down before proceeding.
1723+ return false ;
1724+ }
1725+
17041726 List <RegionPlan > sucRPs = executeRegionPlansWithThrottling (plans );
17051727
17061728 if (this .cpHost != null ) {
@@ -1721,10 +1743,10 @@ public List<RegionPlan> executeRegionPlansWithThrottling(List<RegionPlan> plans)
17211743 List <RegionPlan > sucRPs = new ArrayList <>();
17221744 int maxRegionsInTransition = getMaxRegionsInTransition ();
17231745 long balanceStartTime = System .currentTimeMillis ();
1724- long cutoffTime = balanceStartTime + this .maxBlancingTime ;
1746+ long cutoffTime = balanceStartTime + this .maxBalancingTime ;
17251747 int rpCount = 0 ; // number of RegionPlans balanced so far
17261748 if (plans != null && !plans .isEmpty ()) {
1727- int balanceInterval = this .maxBlancingTime / plans .size ();
1749+ int balanceInterval = this .maxBalancingTime / plans .size ();
17281750 LOG .info ("Balancer plans size is " + plans .size () + ", the balance interval is "
17291751 + balanceInterval + " ms, and the max number regions in transition is "
17301752 + maxRegionsInTransition );
@@ -1742,18 +1764,18 @@ public List<RegionPlan> executeRegionPlansWithThrottling(List<RegionPlan> plans)
17421764 //rpCount records balance plans processed, does not care if a plan succeeds
17431765 rpCount ++;
17441766
1745- if (this .maxBlancingTime > 0 ) {
1767+ if (this .maxBalancingTime > 0 ) {
17461768 balanceThrottling (balanceStartTime + rpCount * balanceInterval , maxRegionsInTransition ,
17471769 cutoffTime );
17481770 }
17491771
17501772 // if performing next balance exceeds cutoff time, exit the loop
1751- if (this .maxBlancingTime > 0 && rpCount < plans .size ()
1773+ if (this .maxBalancingTime > 0 && rpCount < plans .size ()
17521774 && System .currentTimeMillis () > cutoffTime ) {
17531775 // TODO: After balance, there should not be a cutoff time (keeping it as
17541776 // a security net for now)
17551777 LOG .debug ("No more balancing till next balance run; maxBalanceTime="
1756- + this .maxBlancingTime );
1778+ + this .maxBalancingTime );
17571779 break ;
17581780 }
17591781 }
@@ -1775,47 +1797,47 @@ public RegionNormalizer getRegionNormalizer() {
17751797 * is globally disabled)
17761798 */
17771799 public boolean normalizeRegions () throws IOException {
1778- if (!isInitialized ()) {
1779- LOG .debug ("Master has not been initialized, don't run region normalizer." );
1780- return false ;
1781- }
1782- if (this .getServerManager ().isClusterShutdown ()) {
1783- LOG .info ("Cluster is shutting down, don't run region normalizer." );
1800+ if (regionNormalizerTracker == null || !regionNormalizerTracker .isNormalizerOn ()) {
1801+ LOG .debug ("Region normalization is disabled, don't run region normalizer." );
17841802 return false ;
17851803 }
1786- if (isInMaintenanceMode ()) {
1787- LOG .info ("Master is in maintenance mode, don't run region normalizer." );
1804+ if (skipRegionManagementAction ("region normalizer" )) {
17881805 return false ;
17891806 }
1790- if (!this .regionNormalizerTracker .isNormalizerOn ()) {
1791- LOG .debug ("Region normalization is disabled, don't run region normalizer." );
1807+ if (assignmentManager .hasRegionsInTransition ()) {
17921808 return false ;
17931809 }
17941810
17951811 synchronized (this .normalizer ) {
17961812 // Don't run the normalizer concurrently
1813+
17971814 List <TableName > allEnabledTables = new ArrayList <>(
17981815 this .tableStateManager .getTablesInStates (TableState .State .ENABLED ));
17991816
18001817 Collections .shuffle (allEnabledTables );
18011818
18021819 for (TableName table : allEnabledTables ) {
1803- if (isInMaintenanceMode ()) {
1804- LOG .debug ("Master is in maintenance mode, stop running region normalizer." );
1805- return false ;
1806- }
1807-
18081820 TableDescriptor tblDesc = getTableDescriptors ().get (table );
18091821 if (table .isSystemTable () || (tblDesc != null &&
18101822 !tblDesc .isNormalizationEnabled ())) {
18111823 LOG .trace ("Skipping normalization for {}, as it's either system"
18121824 + " table or doesn't have auto normalization turned on" , table );
18131825 continue ;
18141826 }
1815- List <NormalizationPlan > plans = this .normalizer .computePlanForTable (table );
1816- if (plans != null ) {
1827+
1828+ // make one last check that the cluster isn't shutting down before proceeding.
1829+ if (skipRegionManagementAction ("region normalizer" )) {
1830+ return false ;
1831+ }
1832+
1833+ final List <NormalizationPlan > plans = this .normalizer .computePlanForTable (table );
1834+ if (CollectionUtils .isEmpty (plans )) {
1835+ return true ;
1836+ }
1837+
1838+ try (final Admin admin = clusterConnection .getAdmin ()) {
18171839 for (NormalizationPlan plan : plans ) {
1818- plan .execute (clusterConnection . getAdmin () );
1840+ plan .execute (admin );
18191841 if (plan .getType () == PlanType .SPLIT ) {
18201842 splitPlanCount ++;
18211843 } else if (plan .getType () == PlanType .MERGE ) {
0 commit comments