Skip to content

Commit 012ee7f

Browse files
author
Huaxiang Sun
committed
HBASE-26649 Support meta replica LoadBalance mode for RegionLocator#getAllRegionLocations()
Signed-off-by: Duo Zhang <[email protected]>
1 parent 836f9be commit 012ee7f

File tree

7 files changed

+104
-13
lines changed

7 files changed

+104
-13
lines changed

hbase-client/src/main/java/org/apache/hadoop/hbase/AsyncMetaTableAccessor.java

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.Optional;
3030
import java.util.SortedMap;
3131
import java.util.concurrent.CompletableFuture;
32+
import java.util.concurrent.ThreadLocalRandom;
3233
import java.util.regex.Matcher;
3334
import java.util.regex.Pattern;
3435
import java.util.stream.Collectors;
@@ -53,6 +54,8 @@
5354
import org.slf4j.Logger;
5455
import org.slf4j.LoggerFactory;
5556

57+
import static org.apache.hadoop.hbase.client.RegionLocator.LOCATOR_META_REPLICAS_MODE;
58+
5659
/**
5760
* The asynchronous meta table accessor. Used to read/write region and assignment information store
5861
* in <code>hbase:meta</code>.
@@ -366,10 +369,40 @@ private static Scan getMetaScan(AsyncTable<?> metaTable, int rowUpperLimit) {
366369
Scan scan = new Scan();
367370
int scannerCaching = metaTable.getConfiguration().getInt(HConstants.HBASE_META_SCANNER_CACHING,
368371
HConstants.DEFAULT_HBASE_META_SCANNER_CACHING);
369-
if (metaTable.getConfiguration().getBoolean(HConstants.USE_META_REPLICAS,
370-
HConstants.DEFAULT_USE_META_REPLICAS)) {
371-
scan.setConsistency(Consistency.TIMELINE);
372+
373+
// Get the region locator's meta replica mode.
374+
CatalogReplicaMode metaReplicaMode = CatalogReplicaMode.fromString(metaTable.getConfiguration()
375+
.get(LOCATOR_META_REPLICAS_MODE, CatalogReplicaMode.NONE.toString()));
376+
377+
switch (metaReplicaMode) {
378+
case LOAD_BALANCE:
379+
int numOfReplicas = 1;
380+
try {
381+
numOfReplicas = metaTable.getDescriptor().get().getRegionReplication();
382+
} catch (Exception e) {
383+
LOG.warn("Failed to get region replication for meta table");
384+
}
385+
if (numOfReplicas > 1) {
386+
int replicaId = ThreadLocalRandom.current().nextInt(numOfReplicas);
387+
388+
// When the replicaId is 0, do not set to Consistency.TIMELINE
389+
if (replicaId > 0) {
390+
scan.setReplicaId(replicaId);
391+
scan.setConsistency(Consistency.TIMELINE);
392+
}
393+
}
394+
break;
395+
case NONE:
396+
// If user does not configure LOCATOR_META_REPLICAS_MODE, let's check the legacy config.
397+
if (metaTable.getConfiguration().getBoolean(HConstants.USE_META_REPLICAS, HConstants.DEFAULT_USE_META_REPLICAS)) {
398+
scan.setConsistency(Consistency.TIMELINE);
399+
}
400+
break;
401+
402+
default:
403+
// Do nothing
372404
}
405+
373406
if (rowUpperLimit <= scannerCaching) {
374407
scan.setLimit(rowUpperLimit);
375408
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package org.apache.hadoop.hbase.client;
16+
package org.apache.hadoop.hbase;
1717

1818
import org.apache.yetus.audience.InterfaceAudience;
1919

@@ -33,7 +33,7 @@
3333
* </ol>
3434
*/
3535
@InterfaceAudience.Private
36-
enum CatalogReplicaMode {
36+
public enum CatalogReplicaMode {
3737
NONE {
3838
@Override
3939
public String toString() {

hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.NavigableMap;
3434
import java.util.SortedMap;
3535
import java.util.TreeMap;
36+
import java.util.concurrent.ThreadLocalRandom;
3637
import java.util.regex.Matcher;
3738
import java.util.regex.Pattern;
3839
import java.util.stream.Collectors;
@@ -76,6 +77,7 @@
7677
import org.apache.yetus.audience.InterfaceAudience;
7778
import org.slf4j.Logger;
7879
import org.slf4j.LoggerFactory;
80+
import static org.apache.hadoop.hbase.client.RegionLocator.LOCATOR_META_REPLICAS_MODE;
7981

8082
/**
8183
* <p>
@@ -357,7 +359,7 @@ public static Result scanByRegionEncodedName(Connection connection,
357359
String regionEncodedName) throws IOException {
358360
RowFilter rowFilter = new RowFilter(CompareOperator.EQUAL,
359361
new SubstringComparator(regionEncodedName));
360-
Scan scan = getMetaScan(connection.getConfiguration(), 1);
362+
Scan scan = getMetaScan(connection, connection.getConfiguration(), 1);
361363
scan.setFilter(rowFilter);
362364
try (Table table = getMetaHTable(connection);
363365
ResultScanner resultScanner = table.getScanner(scan)) {
@@ -567,19 +569,55 @@ public static Scan getScanForTableName(Configuration conf, TableName tableName)
567569
// Stop key appends the smallest possible char to the table name
568570
byte[] stopKey = getTableStopRowForMeta(tableName, QueryType.REGION);
569571

570-
Scan scan = getMetaScan(conf, -1);
572+
Scan scan = getMetaScan(null, conf, -1);
571573
scan.setStartRow(startKey);
572574
scan.setStopRow(stopKey);
573575
return scan;
574576
}
575577

576-
private static Scan getMetaScan(Configuration conf, int rowUpperLimit) {
578+
private static Scan getMetaScan(Connection conn, Configuration conf, int rowUpperLimit) {
577579
Scan scan = new Scan();
578580
int scannerCaching = conf.getInt(HConstants.HBASE_META_SCANNER_CACHING,
579581
HConstants.DEFAULT_HBASE_META_SCANNER_CACHING);
580-
if (conf.getBoolean(HConstants.USE_META_REPLICAS, HConstants.DEFAULT_USE_META_REPLICAS)) {
581-
scan.setConsistency(Consistency.TIMELINE);
582+
583+
// Get the region locator's meta replica mode.
584+
CatalogReplicaMode metaReplicaMode = CatalogReplicaMode.fromString(
585+
conf.get(LOCATOR_META_REPLICAS_MODE, CatalogReplicaMode.NONE.toString()));
586+
587+
switch (metaReplicaMode) {
588+
case LOAD_BALANCE:
589+
int numOfReplicas = 1;
590+
if (conn != null) {
591+
try {
592+
try (Table metaTable = getMetaHTable(conn)) {
593+
numOfReplicas = metaTable.getDescriptor().getRegionReplication();
594+
}
595+
} catch (IOException ioe) {
596+
LOG.warn("Failed to get region replication for meta table");
597+
}
598+
}
599+
600+
if (numOfReplicas > 1) {
601+
int replicaId = ThreadLocalRandom.current().nextInt(numOfReplicas);
602+
603+
// When the replicaId is 0, do not set to Consistency.TIMELINE
604+
if (replicaId > 0) {
605+
scan.setReplicaId(replicaId);
606+
scan.setConsistency(Consistency.TIMELINE);
607+
}
608+
}
609+
break;
610+
case NONE:
611+
// If user does not configure LOCATOR_META_REPLICAS_MODE, let's check the legacy config.
612+
if (conf.getBoolean(HConstants.USE_META_REPLICAS, HConstants.DEFAULT_USE_META_REPLICAS)) {
613+
scan.setConsistency(Consistency.TIMELINE);
614+
}
615+
break;
616+
617+
default:
618+
// Do nothing
582619
}
620+
583621
if (rowUpperLimit > 0) {
584622
scan.setLimit(rowUpperLimit);
585623
scan.setReadType(Scan.ReadType.PREAD);
@@ -771,7 +809,7 @@ private static void scanMeta(Connection connection, @Nullable final byte[] start
771809
@Nullable final byte[] stopRow, QueryType type, @Nullable Filter filter, int maxRows,
772810
final Visitor visitor) throws IOException {
773811
int rowUpperLimit = maxRows > 0 ? maxRows : Integer.MAX_VALUE;
774-
Scan scan = getMetaScan(connection.getConfiguration(), rowUpperLimit);
812+
Scan scan = getMetaScan(connection, connection.getConfiguration(), rowUpperLimit);
775813

776814
for (byte[] family : type.getFamilies()) {
777815
scan.addFamily(family);
@@ -821,7 +859,7 @@ private static void scanMeta(Connection connection, @Nullable final byte[] start
821859
private static RegionInfo getClosestRegionInfo(Connection connection,
822860
@NonNull final TableName tableName, @NonNull final byte[] row) throws IOException {
823861
byte[] searchRow = RegionInfo.createRegionName(tableName, row, HConstants.NINES, false);
824-
Scan scan = getMetaScan(connection.getConfiguration(), 1);
862+
Scan scan = getMetaScan(connection, connection.getConfiguration(), 1);
825863
scan.setReversed(true);
826864
scan.withStartRow(searchRow);
827865
try (ResultScanner resultScanner = getMetaHTable(connection).getScanner(scan)) {

hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncNonMetaRegionLocator.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import java.util.concurrent.ConcurrentSkipListMap;
5050
import java.util.concurrent.TimeUnit;
5151
import org.apache.commons.lang3.ObjectUtils;
52+
import org.apache.hadoop.hbase.CatalogReplicaMode;
5253
import org.apache.hadoop.hbase.HBaseIOException;
5354
import org.apache.hadoop.hbase.HConstants;
5455
import org.apache.hadoop.hbase.HRegionLocation;

hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import org.apache.hadoop.conf.Configuration;
5555
import org.apache.hadoop.hbase.AuthUtil;
5656
import org.apache.hadoop.hbase.CallQueueTooBigException;
57+
import org.apache.hadoop.hbase.CatalogReplicaMode;
5758
import org.apache.hadoop.hbase.ChoreService;
5859
import org.apache.hadoop.hbase.DoNotRetryIOException;
5960
import org.apache.hadoop.hbase.HConstants;

hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocator.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import java.util.concurrent.ThreadLocalRandom;
3737
import java.util.stream.IntStream;
3838
import org.apache.hadoop.conf.Configuration;
39+
import org.apache.hadoop.hbase.CatalogReplicaMode;
3940
import org.apache.hadoop.hbase.HBaseClassTestRule;
4041
import org.apache.hadoop.hbase.HBaseTestingUtility;
4142
import org.apache.hadoop.hbase.HRegionLocation;

hbase-server/src/test/java/org/apache/hadoop/hbase/replication/regionserver/TestMetaRegionReplicaReplicationEndpoint.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,12 @@ private void primaryMayIncreaseReplicaNoChange(final long[] before, final long[]
519519
}
520520
}
521521

522+
private void PrimaryIncreaseReplicaIncrease(final long[] before, final long[] after) {
523+
for (int i = 0; i < after.length; i++) {
524+
assertTrue(after[i] > before[i]);
525+
}
526+
}
527+
522528
private void getMetaReplicaReadRequests(final Region[] metaRegions, final long[] counters) {
523529
int i = 0;
524530
for (Region r : metaRegions) {
@@ -535,6 +541,7 @@ public void testHBaseMetaReplicaGets() throws Exception {
535541
final Region[] metaRegions = getAllRegions(TableName.META_TABLE_NAME, numOfMetaReplica);
536542
long[] readReqsForMetaReplicas = new long[numOfMetaReplica];
537543
long[] readReqsForMetaReplicasAfterGet = new long[numOfMetaReplica];
544+
long[] readReqsForMetaReplicasAfterGetAllLocations = new long[numOfMetaReplica];
538545
long[] readReqsForMetaReplicasAfterMove = new long[numOfMetaReplica];
539546
long[] readReqsForMetaReplicasAfterSecondMove = new long[numOfMetaReplica];
540547
long[] readReqsForMetaReplicasAfterThirdGet = new long[numOfMetaReplica];
@@ -583,6 +590,16 @@ public void testHBaseMetaReplicaGets() throws Exception {
583590
// For rest of meta replicas, there are more reads against them.
584591
primaryNoChangeReplicaIncrease(readReqsForMetaReplicas, readReqsForMetaReplicasAfterGet);
585592

593+
RegionLocator locator = tableForGet.getRegionLocator();
594+
595+
for (int j = 0; j < numOfMetaReplica * 3; j ++) {
596+
locator.getAllRegionLocations();
597+
}
598+
599+
getMetaReplicaReadRequests(metaRegions, readReqsForMetaReplicasAfterGetAllLocations);
600+
PrimaryIncreaseReplicaIncrease(readReqsForMetaReplicasAfterGet,
601+
readReqsForMetaReplicasAfterGetAllLocations);
602+
586603
// move one of regions so it meta cache may be invalid.
587604
HTU.moveRegionAndWait(userRegion.getRegionInfo(), destRs.getServerName());
588605

@@ -592,7 +609,7 @@ public void testHBaseMetaReplicaGets() throws Exception {
592609

593610
// There are read requests increase for primary meta replica.
594611
// For rest of meta replicas, there is no change as regionMove will tell the new location
595-
primaryIncreaseReplicaNoChange(readReqsForMetaReplicasAfterGet,
612+
primaryIncreaseReplicaNoChange(readReqsForMetaReplicasAfterGetAllLocations,
596613
readReqsForMetaReplicasAfterMove);
597614
// Move region again.
598615
HTU.moveRegionAndWait(userRegion.getRegionInfo(), srcRs.getServerName());

0 commit comments

Comments
 (0)