diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManagerImpl.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManagerImpl.java index 3ef9365456fd..67cb0b64e763 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManagerImpl.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManagerImpl.java @@ -32,7 +32,9 @@ import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; @@ -661,12 +663,14 @@ private synchronized void flushConfig(Map newGroupMap) thro return; } + // Make changes visible + resetRSGroupMap(newGroupMap); + /* For online mode, persist to hbase:rsgroup and Zookeeper */ flushConfigTable(newGroupMap); - - // Make changes visible after having been persisted to the source of truth - resetRSGroupMap(newGroupMap); saveRSGroupMapToZK(newGroupMap); + + // Update previous map updateCacheOfRSGroups(newGroupMap.keySet()); } @@ -825,6 +829,20 @@ private void createRSGroupTable() throws IOException { } public boolean isOnline() { + if (isMasterRunning(masterServices)) { + try { + // try reading from the table + CompletableFuture read = conn.getTable(RSGROUP_TABLE_NAME).get(new Get(ROW_KEY)); + if (read.get(10000, TimeUnit.MILLISECONDS) != null) { + online = true; + } + } catch (Exception e) { + LOG.warn("Failed to read from " + RSGROUP_TABLE_NAME+ "; setting online = false"); + online = false; + } + } else { + online = false; + } return online; } } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/rsgroup/EnableRSGroupsTestBase.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/rsgroup/EnableRSGroupsTestBase.java index 9611bafc2c9e..516975dc91ec 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/rsgroup/EnableRSGroupsTestBase.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/rsgroup/EnableRSGroupsTestBase.java @@ -18,6 +18,7 @@ package org.apache.hadoop.hbase.rsgroup; import static java.lang.Thread.sleep; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.IOException; @@ -25,6 +26,7 @@ import org.apache.hadoop.hbase.HBaseTestingUtil; import org.apache.hadoop.hbase.coprocessor.CoprocessorHost; import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; +import org.apache.hadoop.hbase.util.JVMClusterUtil; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -72,7 +74,25 @@ public void testEnableRSGroup() throws IOException, InterruptedException { (RSGroupBasedLoadBalancer) TEST_UTIL.getMiniHBaseCluster().getMaster().getLoadBalancer(); long start = EnvironmentEdgeManager.currentTime(); while (EnvironmentEdgeManager.currentTime() - start <= 60000 && !loadBalancer.isOnline()) { - LOG.info("waiting for rsgroup load balancer onLine..."); + LOG.info("Waiting for rsgroup load balancer online..."); + sleep(200); + } + + assertTrue(loadBalancer.isOnline()); + + // kill all RS, RSGroupBasedLoadBalancer should now be offline since rsgroup table unavailable + for (JVMClusterUtil.RegionServerThread t: + TEST_UTIL.getMiniHBaseCluster().getRegionServerThreads()) { + TEST_UTIL.getMiniHBaseCluster().killRegionServer( + t.getRegionServer().getServerName()); + } + + assertFalse(loadBalancer.isOnline()); + + TEST_UTIL.getMiniHBaseCluster().startRegionServer(); + start = EnvironmentEdgeManager.currentTime(); + while (EnvironmentEdgeManager.currentTime() - start <= 60000 && !loadBalancer.isOnline()) { + LOG.info("Waiting for rsgroup load balancer online..."); sleep(200); }