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.replication.regionserver; 019 020import static org.apache.hadoop.hbase.client.RegionLocator.LOCATOR_META_REPLICAS_MODE; 021import static org.junit.Assert.assertArrayEquals; 022import static org.junit.Assert.assertEquals; 023import static org.junit.Assert.assertFalse; 024import static org.junit.Assert.assertNotNull; 025import static org.junit.Assert.assertTrue; 026import java.io.IOException; 027import java.util.ArrayList; 028import java.util.Arrays; 029import java.util.List; 030import java.util.Objects; 031import org.apache.hadoop.conf.Configuration; 032import org.apache.hadoop.hbase.Cell; 033import org.apache.hadoop.hbase.CellScanner; 034import org.apache.hadoop.hbase.CellUtil; 035import org.apache.hadoop.hbase.HBaseClassTestRule; 036import org.apache.hadoop.hbase.HBaseTestingUtility; 037import org.apache.hadoop.hbase.HConstants; 038import org.apache.hadoop.hbase.HRegionLocation; 039import org.apache.hadoop.hbase.MetaTableAccessor; 040import org.apache.hadoop.hbase.MiniHBaseCluster; 041import org.apache.hadoop.hbase.TableName; 042import org.apache.hadoop.hbase.Waiter; 043import org.apache.hadoop.hbase.client.Connection; 044import org.apache.hadoop.hbase.client.ConnectionFactory; 045import org.apache.hadoop.hbase.client.Get; 046import org.apache.hadoop.hbase.client.RegionInfo; 047import org.apache.hadoop.hbase.client.RegionLocator; 048import org.apache.hadoop.hbase.client.Result; 049import org.apache.hadoop.hbase.client.Scan; 050import org.apache.hadoop.hbase.client.Table; 051import org.apache.hadoop.hbase.regionserver.HRegion; 052import org.apache.hadoop.hbase.regionserver.HRegionServer; 053import org.apache.hadoop.hbase.regionserver.Region; 054import org.apache.hadoop.hbase.regionserver.RegionScanner; 055import org.apache.hadoop.hbase.testclassification.LargeTests; 056import org.apache.hadoop.hbase.util.Bytes; 057import org.apache.hadoop.hbase.util.ServerRegionReplicaUtil; 058import org.junit.After; 059import org.junit.Before; 060import org.junit.ClassRule; 061import org.junit.Rule; 062import org.junit.Test; 063import org.junit.experimental.categories.Category; 064import org.junit.rules.TestName; 065import org.slf4j.Logger; 066import org.slf4j.LoggerFactory; 067 068/** 069 * Tests RegionReplicaReplicationEndpoint class for hbase:meta by setting up region replicas and 070 * verifying async wal replication replays the edits to the secondary region in various scenarios. 071 * 072 * @see TestRegionReplicaReplicationEndpoint 073 */ 074@Category({LargeTests.class}) 075public class TestMetaRegionReplicaReplicationEndpoint { 076 @ClassRule 077 public static final HBaseClassTestRule CLASS_RULE = 078 HBaseClassTestRule.forClass(TestMetaRegionReplicaReplicationEndpoint.class); 079 private static final Logger LOG = 080 LoggerFactory.getLogger(TestMetaRegionReplicaReplicationEndpoint.class); 081 private static final int NB_SERVERS = 4; 082 private final HBaseTestingUtility HTU = new HBaseTestingUtility(); 083 private int numOfMetaReplica = NB_SERVERS - 1; 084 private static byte[] VALUE = Bytes.toBytes("value"); 085 086 @Rule 087 public TestName name = new TestName(); 088 089 @Before 090 public void before() throws Exception { 091 Configuration conf = HTU.getConfiguration(); 092 conf.setFloat("hbase.regionserver.logroll.multiplier", 0.0003f); 093 conf.setInt("replication.source.size.capacity", 10240); 094 conf.setLong("replication.source.sleepforretries", 100); 095 conf.setInt("hbase.regionserver.maxlogs", 10); 096 conf.setLong("hbase.master.logcleaner.ttl", 10); 097 conf.setInt("zookeeper.recovery.retry", 1); 098 conf.setInt("zookeeper.recovery.retry.intervalmill", 10); 099 conf.setLong(HConstants.THREAD_WAKE_FREQUENCY, 100); 100 conf.setInt("replication.stats.thread.period.seconds", 5); 101 conf.setBoolean("hbase.tests.use.shortcircuit.reads", false); 102 conf.setInt(HConstants.HBASE_CLIENT_SERVERSIDE_RETRIES_MULTIPLIER, 1); 103 // Enable hbase:meta replication. 104 conf.setBoolean(ServerRegionReplicaUtil.REGION_REPLICA_REPLICATION_CATALOG_CONF_KEY, 105 true); 106 // Set hbase:meta replicas to be 3. 107 // conf.setInt(HConstants.META_REPLICAS_NUM, numOfMetaReplica); 108 HTU.startMiniCluster(NB_SERVERS); 109 // Enable hbase:meta replication. 110 HBaseTestingUtility.setReplicas(HTU.getAdmin(), TableName.META_TABLE_NAME, numOfMetaReplica); 111 112 HTU.waitFor(30000, 113 () -> HTU.getMiniHBaseCluster().getRegions(TableName.META_TABLE_NAME).size() 114 >= numOfMetaReplica); 115 } 116 117 @After 118 public void after() throws Exception { 119 HTU.shutdownMiniCluster(); 120 } 121 122 /** 123 * Assert that the ReplicationSource for hbase:meta gets created when hbase:meta is opened. 124 */ 125 @Test 126 public void testHBaseMetaReplicationSourceCreatedOnOpen() throws Exception { 127 MiniHBaseCluster cluster = HTU.getMiniHBaseCluster(); 128 HRegionServer hrs = cluster.getRegionServer(cluster.getServerHoldingMeta()); 129 // Replicate a row to prove all working. 130 testHBaseMetaReplicatesOneRow(0); 131 assertTrue(isMetaRegionReplicaReplicationSource(hrs)); 132 // Now move the hbase:meta and make sure the ReplicationSource is in both places. 133 HRegionServer hrsOther = null; 134 for (int i = 0; i < cluster.getNumLiveRegionServers(); i++) { 135 hrsOther = cluster.getRegionServer(i); 136 if (hrsOther.getServerName().equals(hrs.getServerName())) { 137 hrsOther = null; 138 continue; 139 } 140 break; 141 } 142 assertNotNull(hrsOther); 143 assertFalse(isMetaRegionReplicaReplicationSource(hrsOther)); 144 Region meta = null; 145 for (Region region : hrs.getOnlineRegionsLocalContext()) { 146 if (region.getRegionInfo().isMetaRegion()) { 147 meta = region; 148 break; 149 } 150 } 151 assertNotNull(meta); 152 HTU.moveRegionAndWait(meta.getRegionInfo(), hrsOther.getServerName()); 153 // Assert that there is a ReplicationSource in both places now. 154 assertTrue(isMetaRegionReplicaReplicationSource(hrs)); 155 assertTrue(isMetaRegionReplicaReplicationSource(hrsOther)); 156 // Replicate to show stuff still works. 157 testHBaseMetaReplicatesOneRow(1); 158 // Now pretend a few hours have gone by... roll the meta WAL in original location... Move the 159 // meta back and retry replication. See if it works. 160 hrs.getWAL(meta.getRegionInfo()).rollWriter(true); 161 testHBaseMetaReplicatesOneRow(2); 162 hrs.getWAL(meta.getRegionInfo()).rollWriter(true); 163 testHBaseMetaReplicatesOneRow(3); 164 } 165 166 /** 167 * Test meta region replica replication. Create some tables and see if replicas pick up the 168 * additions. 169 */ 170 private void testHBaseMetaReplicatesOneRow(int i) throws Exception { 171 waitForMetaReplicasToOnline(); 172 try (Table table = HTU.createTable(TableName.valueOf(this.name.getMethodName() + "_" + i), 173 HConstants.CATALOG_FAMILY)) { 174 verifyReplication(TableName.META_TABLE_NAME, numOfMetaReplica, getMetaCells(table.getName())); 175 } 176 } 177 178 /** 179 * @return Whether the special meta region replica peer is enabled on <code>hrs</code> 180 */ 181 private boolean isMetaRegionReplicaReplicationSource(HRegionServer hrs) { 182 return hrs.getReplicationSourceService().getReplicationManager(). 183 catalogReplicationSource.get() != null; 184 } 185 186 /** 187 * Test meta region replica replication. Create some tables and see if replicas pick up the 188 * additions. 189 */ 190 @Test 191 public void testHBaseMetaReplicates() throws Exception { 192 try (Table table = HTU 193 .createTable(TableName.valueOf(this.name.getMethodName() + "_0"), HConstants.CATALOG_FAMILY, 194 Arrays.copyOfRange(HBaseTestingUtility.KEYS, 1, HBaseTestingUtility.KEYS.length))) { 195 verifyReplication(TableName.META_TABLE_NAME, numOfMetaReplica, getMetaCells(table.getName())); 196 } 197 try (Table table = HTU 198 .createTable(TableName.valueOf(this.name.getMethodName() + "_1"), HConstants.CATALOG_FAMILY, 199 Arrays.copyOfRange(HBaseTestingUtility.KEYS, 1, HBaseTestingUtility.KEYS.length))) { 200 verifyReplication(TableName.META_TABLE_NAME, numOfMetaReplica, getMetaCells(table.getName())); 201 // Try delete. 202 HTU.deleteTableIfAny(table.getName()); 203 verifyDeletedReplication(TableName.META_TABLE_NAME, numOfMetaReplica, table.getName()); 204 } 205 } 206 207 @Test 208 public void testCatalogReplicaReplicationWithFlushAndCompaction() throws Exception { 209 Connection connection = ConnectionFactory.createConnection(HTU.getConfiguration()); 210 TableName tableName = TableName.valueOf("hbase:meta"); 211 Table table = connection.getTable(tableName); 212 try { 213 // load the data to the table 214 for (int i = 0; i < 5; i++) { 215 LOG.info("Writing data from " + i * 1000 + " to " + (i * 1000 + 1000)); 216 HTU.loadNumericRows(table, HConstants.CATALOG_FAMILY, i * 1000, i * 1000 + 1000); 217 LOG.info("flushing table"); 218 HTU.flush(tableName); 219 LOG.info("compacting table"); 220 if (i < 4) { 221 HTU.compact(tableName, false); 222 } 223 } 224 225 verifyReplication(tableName, numOfMetaReplica, 0, 5000, HConstants.CATALOG_FAMILY); 226 } finally { 227 table.close(); 228 connection.close(); 229 } 230 } 231 232 @Test 233 public void testCatalogReplicaReplicationWithReplicaMoved() throws Exception { 234 MiniHBaseCluster cluster = HTU.getMiniHBaseCluster(); 235 HRegionServer hrs = cluster.getRegionServer(cluster.getServerHoldingMeta()); 236 237 HRegionServer hrsMetaReplica = null; 238 HRegionServer hrsNoMetaReplica = null; 239 HRegionServer server = null; 240 Region metaReplica = null; 241 boolean hostingMeta; 242 243 for (int i = 0; i < cluster.getNumLiveRegionServers(); i++) { 244 server = cluster.getRegionServer(i); 245 hostingMeta = false; 246 if (server == hrs) { 247 continue; 248 } 249 for (Region region : server.getOnlineRegionsLocalContext()) { 250 if (region.getRegionInfo().isMetaRegion()) { 251 if (metaReplica == null) { 252 metaReplica = region; 253 } 254 hostingMeta = true; 255 break; 256 } 257 } 258 if (!hostingMeta) { 259 hrsNoMetaReplica = server; 260 } 261 } 262 263 Connection connection = ConnectionFactory.createConnection(HTU.getConfiguration()); 264 TableName tableName = TableName.valueOf("hbase:meta"); 265 Table table = connection.getTable(tableName); 266 try { 267 // load the data to the table 268 for (int i = 0; i < 5; i++) { 269 LOG.info("Writing data from " + i * 1000 + " to " + (i * 1000 + 1000)); 270 HTU.loadNumericRows(table, HConstants.CATALOG_FAMILY, i * 1000, i * 1000 + 1000); 271 if (i == 0) { 272 HTU.moveRegionAndWait(metaReplica.getRegionInfo(), hrsNoMetaReplica.getServerName()); 273 } 274 } 275 276 verifyReplication(tableName, numOfMetaReplica, 0, 5000, HConstants.CATALOG_FAMILY); 277 } finally { 278 table.close(); 279 connection.close(); 280 } 281 } 282 283 protected void verifyReplication(TableName tableName, int regionReplication, final int startRow, 284 final int endRow, final byte[] family) throws Exception { 285 verifyReplication(tableName, regionReplication, startRow, endRow, family, true); 286 } 287 288 private void verifyReplication(TableName tableName, int regionReplication, final int startRow, 289 final int endRow, final byte[] family, final boolean present) throws Exception { 290 // find the regions 291 final Region[] regions = new Region[regionReplication]; 292 293 for (int i = 0; i < NB_SERVERS; i++) { 294 HRegionServer rs = HTU.getMiniHBaseCluster().getRegionServer(i); 295 List<HRegion> onlineRegions = rs.getRegions(tableName); 296 for (HRegion region : onlineRegions) { 297 regions[region.getRegionInfo().getReplicaId()] = region; 298 } 299 } 300 301 for (Region region : regions) { 302 assertNotNull(region); 303 } 304 305 for (int i = 1; i < regionReplication; i++) { 306 final Region region = regions[i]; 307 // wait until all the data is replicated to all secondary regions 308 Waiter.waitFor(HTU.getConfiguration(), 90000, 1000, new Waiter.Predicate<Exception>() { 309 @Override 310 public boolean evaluate() throws Exception { 311 LOG.info("verifying replication for region replica:" + region.getRegionInfo()); 312 try { 313 HTU.verifyNumericRows(region, family, startRow, endRow, present); 314 } catch (Throwable ex) { 315 LOG.warn("Verification from secondary region is not complete yet", ex); 316 // still wait 317 return false; 318 } 319 return true; 320 } 321 }); 322 } 323 } 324 325 /** 326 * Replicas come online after primary. 327 */ 328 private void waitForMetaReplicasToOnline() throws IOException { 329 final RegionLocator regionLocator = 330 HTU.getConnection().getRegionLocator(TableName.META_TABLE_NAME); 331 HTU.waitFor(10000, 332 // getRegionLocations returns an entry for each replica but if unassigned, entry is null. 333 // Pass reload to force us to skip cache else it just keeps returning default. 334 () -> regionLocator.getRegionLocations(HConstants.EMPTY_START_ROW, true).stream(). 335 filter(Objects::nonNull).count() >= numOfMetaReplica); 336 List<HRegionLocation> locations = regionLocator.getRegionLocations(HConstants.EMPTY_START_ROW); 337 LOG.info("Found locations {}", locations); 338 assertEquals(numOfMetaReplica, locations.size()); 339 } 340 341 /** 342 * Scan hbase:meta for <code>tableName</code> content. 343 */ 344 private List<Result> getMetaCells(TableName tableName) throws IOException { 345 final List<Result> results = new ArrayList<>(); 346 MetaTableAccessor.Visitor visitor = new MetaTableAccessor.Visitor() { 347 @Override public boolean visit(Result r) throws IOException { 348 results.add(r); 349 return true; 350 } 351 }; 352 MetaTableAccessor.scanMetaForTableRegions(HTU.getConnection(), visitor, tableName); 353 return results; 354 } 355 356 /** 357 * @return All Regions for tableName including Replicas. 358 */ 359 private Region[] getAllRegions(TableName tableName, int replication) { 360 final Region[] regions = new Region[replication]; 361 for (int i = 0; i < NB_SERVERS; i++) { 362 HRegionServer rs = HTU.getMiniHBaseCluster().getRegionServer(i); 363 List<HRegion> onlineRegions = rs.getRegions(tableName); 364 for (HRegion region : onlineRegions) { 365 regions[region.getRegionInfo().getReplicaId()] = region; 366 } 367 } 368 for (Region region : regions) { 369 assertNotNull(region); 370 } 371 return regions; 372 } 373 374 private Region getOneRegion(TableName tableName) { 375 for (int i = 0; i < NB_SERVERS; i++) { 376 HRegionServer rs = HTU.getMiniHBaseCluster().getRegionServer(i); 377 List<HRegion> onlineRegions = rs.getRegions(tableName); 378 if (onlineRegions.size() > 1) { 379 return onlineRegions.get(0); 380 } 381 } 382 return null; 383 } 384 385 /** 386 * Verify when a Table is deleted from primary, then there are no references in replicas 387 * (because they get the delete of the table rows too). 388 */ 389 private void verifyDeletedReplication(TableName tableName, int regionReplication, 390 final TableName deletedTableName) { 391 final Region[] regions = getAllRegions(tableName, regionReplication); 392 393 // Start count at '1' so we skip default, primary replica and only look at secondaries. 394 for (int i = 1; i < regionReplication; i++) { 395 final Region region = regions[i]; 396 // wait until all the data is replicated to all secondary regions 397 Waiter.waitFor(HTU.getConfiguration(), 30000, 1000, new Waiter.Predicate<Exception>() { 398 @Override 399 public boolean evaluate() throws Exception { 400 LOG.info("Verifying replication for region replica {}", region.getRegionInfo()); 401 try (RegionScanner rs = region.getScanner(new Scan())) { 402 List<Cell> cells = new ArrayList<>(); 403 while (rs.next(cells)) { 404 continue; 405 } 406 return doesNotContain(cells, deletedTableName); 407 } catch (Throwable ex) { 408 LOG.warn("Verification from secondary region is not complete yet", ex); 409 // still wait 410 return false; 411 } 412 } 413 }); 414 } 415 } 416 417 /** 418 * Cells are from hbase:meta replica so will start w/ 'tableName,'; i.e. the tablename followed 419 * by HConstants.DELIMITER. Make sure the deleted table is no longer present in passed 420 * <code>cells</code>. 421 */ 422 private boolean doesNotContain(List<Cell> cells, TableName tableName) { 423 for (Cell cell : cells) { 424 String row = Bytes.toString(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength()); 425 if (row.startsWith(tableName.toString() + HConstants.DELIMITER)) { 426 return false; 427 } 428 } 429 return true; 430 } 431 432 /** 433 * Verify Replicas have results (exactly). 434 */ 435 private void verifyReplication(TableName tableName, int regionReplication, 436 List<Result> contains) { 437 final Region[] regions = getAllRegions(tableName, regionReplication); 438 439 // Start count at '1' so we skip default, primary replica and only look at secondaries. 440 for (int i = 1; i < regionReplication; i++) { 441 final Region region = regions[i]; 442 // wait until all the data is replicated to all secondary regions 443 Waiter.waitFor(HTU.getConfiguration(), 30000, 1000, new Waiter.Predicate<Exception>() { 444 @Override 445 public boolean evaluate() throws Exception { 446 LOG.info("Verifying replication for region replica {}", region.getRegionInfo()); 447 try (RegionScanner rs = region.getScanner(new Scan())) { 448 List<Cell> cells = new ArrayList<>(); 449 while (rs.next(cells)) { 450 continue; 451 } 452 return contains(contains, cells); 453 } catch (Throwable ex) { 454 LOG.warn("Verification from secondary region is not complete yet", ex); 455 // still wait 456 return false; 457 } 458 } 459 }); 460 } 461 } 462 463 /** 464 * Presumes sorted Cells. Verify that <code>cells</code> has <code>contains</code> at least. 465 */ 466 static boolean contains(List<Result> contains, List<Cell> cells) throws IOException { 467 CellScanner containsScanner = CellUtil.createCellScanner(contains); 468 CellScanner cellsScanner = CellUtil.createCellScanner(cells); 469 int matches = 0; 470 int count = 0; 471 while (containsScanner.advance()) { 472 while (cellsScanner.advance()) { 473 count++; 474 LOG.info("{} {}", containsScanner.current(), cellsScanner.current()); 475 if (containsScanner.current().equals(cellsScanner.current())) { 476 matches++; 477 break; 478 } 479 } 480 } 481 return !containsScanner.advance() && matches >= 1 && count >= matches && count == cells.size(); 482 } 483 484 private void doNGets(final Table table, final byte[][] keys) throws Exception { 485 for (byte[] key : keys) { 486 Result r = table.get(new Get(key)); 487 assertArrayEquals(VALUE, r.getValue(HConstants.CATALOG_FAMILY, HConstants.CATALOG_FAMILY)); 488 } 489 } 490 491 private void primaryNoChangeReplicaIncrease(final long[] before, final long[] after) { 492 assertEquals(before[RegionInfo.DEFAULT_REPLICA_ID], 493 after[RegionInfo.DEFAULT_REPLICA_ID]); 494 495 for (int i = 1; i < after.length; i ++) { 496 assertTrue(after[i] > before[i]); 497 } 498 } 499 500 private void primaryIncreaseReplicaNoChange(final long[] before, final long[] after) { 501 // There are read requests increase for primary meta replica. 502 assertTrue(after[RegionInfo.DEFAULT_REPLICA_ID] > 503 before[RegionInfo.DEFAULT_REPLICA_ID]); 504 505 // No change for replica regions 506 for (int i = 1; i < after.length; i ++) { 507 assertEquals(before[i], after[i]); 508 } 509 } 510 511 private void primaryMayIncreaseReplicaNoChange(final long[] before, final long[] after) { 512 // For primary meta replica, scan request may increase. No change for replica meta regions. 513 assertTrue(after[RegionInfo.DEFAULT_REPLICA_ID] >= 514 before[RegionInfo.DEFAULT_REPLICA_ID]); 515 516 // No change for replica regions 517 for (int i = 1; i < after.length; i ++) { 518 assertEquals(before[i], after[i]); 519 } 520 } 521 522 private void getMetaReplicaReadRequests(final Region[] metaRegions, final long[] counters) { 523 int i = 0; 524 for (Region r : metaRegions) { 525 LOG.info("read request for region {} is {}", r, r.getReadRequestsCount()); 526 counters[i] = r.getReadRequestsCount(); 527 i ++; 528 } 529 } 530 531 @Test 532 public void testHBaseMetaReplicaGets() throws Exception { 533 534 TableName tn = TableName.valueOf(this.name.getMethodName()); 535 final Region[] metaRegions = getAllRegions(TableName.META_TABLE_NAME, numOfMetaReplica); 536 long[] readReqsForMetaReplicas = new long[numOfMetaReplica]; 537 long[] readReqsForMetaReplicasAfterGet = new long[numOfMetaReplica]; 538 long[] readReqsForMetaReplicasAfterMove = new long[numOfMetaReplica]; 539 long[] readReqsForMetaReplicasAfterSecondMove = new long[numOfMetaReplica]; 540 long[] readReqsForMetaReplicasAfterThirdGet = new long[numOfMetaReplica]; 541 Region userRegion = null; 542 HRegionServer srcRs = null; 543 HRegionServer destRs = null; 544 545 try (Table table = HTU.createTable(tn, HConstants.CATALOG_FAMILY, 546 Arrays.copyOfRange(HBaseTestingUtility.KEYS, 1, HBaseTestingUtility.KEYS.length))) { 547 verifyReplication(TableName.META_TABLE_NAME, numOfMetaReplica, getMetaCells(table.getName())); 548 // load different values 549 HTU.loadTable(table, new byte[][] { HConstants.CATALOG_FAMILY }, VALUE); 550 for (int i = 0; i < NB_SERVERS; i++) { 551 HRegionServer rs = HTU.getMiniHBaseCluster().getRegionServer(i); 552 List<HRegion> onlineRegions = rs.getRegions(tn); 553 if (onlineRegions.size() > 0) { 554 userRegion = onlineRegions.get(0); 555 srcRs = rs; 556 if (i > 0) { 557 destRs = HTU.getMiniHBaseCluster().getRegionServer(0); 558 } else { 559 destRs = HTU.getMiniHBaseCluster().getRegionServer(1); 560 } 561 } 562 } 563 564 getMetaReplicaReadRequests(metaRegions, readReqsForMetaReplicas); 565 566 Configuration c = new Configuration(HTU.getConfiguration()); 567 c.set(LOCATOR_META_REPLICAS_MODE, "LoadBalance"); 568 Connection connection = ConnectionFactory.createConnection(c); 569 Table tableForGet = connection.getTable(tn); 570 byte[][] getRows = new byte[HBaseTestingUtility.KEYS.length][]; 571 572 int i = 0; 573 for (byte[] key : HBaseTestingUtility.KEYS) { 574 getRows[i] = key; 575 i++; 576 } 577 getRows[0] = Bytes.toBytes("aaa"); 578 doNGets(tableForGet, getRows); 579 580 getMetaReplicaReadRequests(metaRegions, readReqsForMetaReplicasAfterGet); 581 582 // There is no read requests increase for primary meta replica. 583 // For rest of meta replicas, there are more reads against them. 584 primaryNoChangeReplicaIncrease(readReqsForMetaReplicas, readReqsForMetaReplicasAfterGet); 585 586 // move one of regions so it meta cache may be invalid. 587 HTU.moveRegionAndWait(userRegion.getRegionInfo(), destRs.getServerName()); 588 589 doNGets(tableForGet, getRows); 590 591 getMetaReplicaReadRequests(metaRegions, readReqsForMetaReplicasAfterMove); 592 593 // There are read requests increase for primary meta replica. 594 // For rest of meta replicas, there is no change as regionMove will tell the new location 595 primaryIncreaseReplicaNoChange(readReqsForMetaReplicasAfterGet, 596 readReqsForMetaReplicasAfterMove); 597 // Move region again. 598 HTU.moveRegionAndWait(userRegion.getRegionInfo(), srcRs.getServerName()); 599 600 // Wait until moveRegion cache timeout. 601 while (destRs.getMovedRegion(userRegion.getRegionInfo().getEncodedName()) != null) { 602 Thread.sleep(1000); 603 } 604 605 getMetaReplicaReadRequests(metaRegions, readReqsForMetaReplicasAfterSecondMove); 606 607 // There may be read requests increase for primary meta replica. 608 // For rest of meta replicas, there is no change. 609 primaryMayIncreaseReplicaNoChange(readReqsForMetaReplicasAfterMove, 610 readReqsForMetaReplicasAfterSecondMove); 611 612 doNGets(tableForGet, getRows); 613 614 getMetaReplicaReadRequests(metaRegions, readReqsForMetaReplicasAfterThirdGet); 615 616 // Since it gets RegionNotServedException, it will go to primary for the next lookup. 617 // There are read requests increase for primary meta replica. 618 // For rest of meta replicas, there is no change. 619 primaryIncreaseReplicaNoChange(readReqsForMetaReplicasAfterSecondMove, 620 readReqsForMetaReplicasAfterThirdGet); 621 } 622 } 623}