2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org
.apache
.hadoop
.hbase
.client
;
20 import static org
.junit
.Assert
.assertEquals
;
21 import static org
.junit
.Assert
.assertFalse
;
22 import static org
.junit
.Assert
.assertTrue
;
24 import java
.util
.ArrayList
;
25 import java
.util
.Collections
;
26 import java
.util
.List
;
27 import org
.apache
.hadoop
.conf
.Configuration
;
28 import org
.apache
.hadoop
.hbase
.HBaseClassTestRule
;
29 import org
.apache
.hadoop
.hbase
.HBaseTestingUtil
;
30 import org
.apache
.hadoop
.hbase
.HConstants
;
31 import org
.apache
.hadoop
.hbase
.HRegionLocation
;
32 import org
.apache
.hadoop
.hbase
.MetaRegionLocationCache
;
33 import org
.apache
.hadoop
.hbase
.MultithreadedTestUtil
;
34 import org
.apache
.hadoop
.hbase
.ServerName
;
35 import org
.apache
.hadoop
.hbase
.TableName
;
36 import org
.apache
.hadoop
.hbase
.master
.HMaster
;
37 import org
.apache
.hadoop
.hbase
.master
.RegionState
;
38 import org
.apache
.hadoop
.hbase
.testclassification
.MasterTests
;
39 import org
.apache
.hadoop
.hbase
.testclassification
.SmallTests
;
40 import org
.apache
.hadoop
.hbase
.util
.JVMClusterUtil
;
41 import org
.apache
.hadoop
.hbase
.zookeeper
.MetaTableLocator
;
42 import org
.apache
.hadoop
.hbase
.zookeeper
.ZKUtil
;
43 import org
.apache
.hadoop
.hbase
.zookeeper
.ZKWatcher
;
44 import org
.apache
.hadoop
.hbase
.zookeeper
.ZNodePaths
;
45 import org
.junit
.AfterClass
;
46 import org
.junit
.BeforeClass
;
47 import org
.junit
.ClassRule
;
48 import org
.junit
.Test
;
49 import org
.junit
.experimental
.categories
.Category
;
51 import org
.apache
.hbase
.thirdparty
.com
.google
.common
.io
.Closeables
;
53 @Category({SmallTests
.class, MasterTests
.class })
54 public class TestMetaRegionLocationCache
{
56 public static final HBaseClassTestRule CLASS_RULE
=
57 HBaseClassTestRule
.forClass(TestMetaRegionLocationCache
.class);
59 private static final HBaseTestingUtil TEST_UTIL
= new HBaseTestingUtil();
60 private static ConnectionRegistry REGISTRY
;
63 public static void setUp() throws Exception
{
64 TEST_UTIL
.startMiniCluster(3);
65 HBaseTestingUtil
.setReplicas(TEST_UTIL
.getAdmin(), TableName
.META_TABLE_NAME
, 3);
66 REGISTRY
= ConnectionRegistryFactory
.getRegistry(TEST_UTIL
.getConfiguration());
67 RegionReplicaTestHelper
.waitUntilAllMetaReplicasAreReady(TEST_UTIL
, REGISTRY
);
68 TEST_UTIL
.getAdmin().balancerSwitch(false, true);
72 public static void cleanUp() throws Exception
{
73 Closeables
.close(REGISTRY
, true);
74 TEST_UTIL
.shutdownMiniCluster();
77 private List
<HRegionLocation
> getCurrentMetaLocations(ZKWatcher zk
) throws Exception
{
78 List
<HRegionLocation
> result
= new ArrayList
<>();
79 for (String znode
: zk
.getMetaReplicaNodes()) {
80 String path
= ZNodePaths
.joinZNode(zk
.getZNodePaths().baseZNode
, znode
);
81 int replicaId
= zk
.getZNodePaths().getMetaReplicaIdFromPath(path
);
82 RegionState state
= MetaTableLocator
.getMetaRegionState(zk
, replicaId
);
83 result
.add(new HRegionLocation(state
.getRegion(), state
.getServerName()));
88 // Verifies that the cached meta locations in the given master are in sync with what is in ZK.
89 private void verifyCachedMetaLocations(HMaster master
) throws Exception
{
90 // Wait until initial meta locations are loaded.
92 while (master
.getMetaRegionLocationCache().getMetaRegionLocations().isEmpty()) {
94 if (++retries
== 10) {
98 ZKWatcher zk
= master
.getZooKeeper();
99 List
<String
> metaZnodes
= zk
.getMetaReplicaNodes();
100 // Wait till all replicas available.
102 while (master
.getMetaRegionLocationCache().getMetaRegionLocations().size() != metaZnodes
105 if (++retries
== 10) {
109 List
<HRegionLocation
> metaHRLs
= master
.getMetaRegionLocationCache().getMetaRegionLocations();
110 assertFalse(metaHRLs
.isEmpty());
111 assertEquals(metaZnodes
.size(), metaHRLs
.size());
112 List
<HRegionLocation
> actualHRLs
= getCurrentMetaLocations(zk
);
113 Collections
.sort(metaHRLs
);
114 Collections
.sort(actualHRLs
);
115 assertEquals(actualHRLs
, metaHRLs
);
119 public void testInitialMetaLocations() throws Exception
{
120 verifyCachedMetaLocations(TEST_UTIL
.getMiniHBaseCluster().getMaster());
124 public void testStandByMetaLocations() throws Exception
{
125 HMaster standBy
= TEST_UTIL
.getMiniHBaseCluster().startMaster().getMaster();
126 verifyCachedMetaLocations(standBy
);
130 * Shuffles the meta region replicas around the cluster and makes sure the cache is not stale.
132 @Test public void testMetaLocationsChange() throws Exception
{
133 List
<HRegionLocation
> currentMetaLocs
=
134 getCurrentMetaLocations(TEST_UTIL
.getMiniHBaseCluster().getMaster().getZooKeeper());
135 // Move these replicas to random servers.
136 for (HRegionLocation location
: currentMetaLocs
) {
137 RegionReplicaTestHelper
.moveRegion(TEST_UTIL
, location
);
139 RegionReplicaTestHelper
.waitUntilAllMetaReplicasAreReady(TEST_UTIL
, REGISTRY
);
140 for (JVMClusterUtil
.MasterThread masterThread
:
141 TEST_UTIL
.getMiniHBaseCluster().getMasterThreads()) {
142 verifyCachedMetaLocations(masterThread
.getMaster());
147 * Tests MetaRegionLocationCache's init procedure to make sure that it correctly watches the base
148 * znode for notifications.
150 @Test public void testMetaRegionLocationCache() throws Exception
{
151 final String parentZnodeName
= "/randomznodename";
152 Configuration conf
= new Configuration(TEST_UTIL
.getConfiguration());
153 conf
.set(HConstants
.ZOOKEEPER_ZNODE_PARENT
, parentZnodeName
);
154 ServerName sn
= ServerName
.valueOf("localhost", 1234, 5678);
155 try (ZKWatcher zkWatcher
= new ZKWatcher(conf
, null, null, true)) {
156 // A thread that repeatedly creates and drops an unrelated child znode. This is to simulate
157 // some ZK activity in the background.
158 MultithreadedTestUtil
.TestContext ctx
= new MultithreadedTestUtil
.TestContext(conf
);
159 ctx
.addThread(new MultithreadedTestUtil
.RepeatingTestThread(ctx
) {
160 @Override public void doAnAction() throws Exception
{
161 final String testZnode
= parentZnodeName
+ "/child";
162 ZKUtil
.createNodeIfNotExistsAndWatch(zkWatcher
, testZnode
, testZnode
.getBytes());
163 ZKUtil
.deleteNode(zkWatcher
, testZnode
);
168 MetaRegionLocationCache metaCache
= new MetaRegionLocationCache(zkWatcher
);
169 // meta znodes do not exist at this point, cache should be empty.
170 assertTrue(metaCache
.getMetaRegionLocations().isEmpty());
171 // Set the meta locations for a random meta replicas, simulating an active hmaster meta
173 for (int i
= 0; i
< 3; i
++) {
174 // Updates the meta znodes.
175 MetaTableLocator
.setMetaLocation(zkWatcher
, sn
, i
, RegionState
.State
.OPEN
);
177 // Wait until the meta cache is populated.
179 while (iters
++ < 10) {
180 if (metaCache
.getMetaRegionLocations().size() == 3) {
185 List
<HRegionLocation
> metaLocations
= metaCache
.getMetaRegionLocations();
186 assertEquals(3, metaLocations
.size());
187 for (HRegionLocation location
: metaLocations
) {
188 assertEquals(sn
, location
.getServerName());
193 ZKUtil
.deleteChildrenRecursively(zkWatcher
, parentZnodeName
);