Skip to content
Permalink
Browse files
HBASE-26649 Support meta replica LoadBalance mode for RegionLocator#g…
…etAllRegionLocations() (#4044)

Signed-off-by: Duo Zhang <zhangduo@apache.org>
  • Loading branch information
huaxiangsun committed Jan 28, 2022
1 parent 056e8fb commit 8c607397c19a828a1be89eb3a1325f774f772c2a
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 6 deletions.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase.client;
package org.apache.hadoop.hbase;

import org.apache.yetus.audience.InterfaceAudience;

@@ -33,7 +33,7 @@
* </ol>
*/
@InterfaceAudience.Private
enum CatalogReplicaMode {
public enum CatalogReplicaMode {
NONE {
@Override
public String toString() {
@@ -17,6 +17,7 @@
*/
package org.apache.hadoop.hbase;

import static org.apache.hadoop.hbase.client.RegionLocator.LOCATOR_META_REPLICAS_MODE;
import static org.apache.hadoop.hbase.util.FutureUtils.addListener;

import java.io.Closeable;
@@ -26,6 +27,7 @@
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import org.apache.hadoop.hbase.client.AdvancedScanResultConsumer;
import org.apache.hadoop.hbase.client.AsyncTable;
@@ -416,10 +418,40 @@ private static Scan getMetaScan(AsyncTable<?> metaTable, int rowUpperLimit) {
Scan scan = new Scan();
int scannerCaching = metaTable.getConfiguration().getInt(HConstants.HBASE_META_SCANNER_CACHING,
HConstants.DEFAULT_HBASE_META_SCANNER_CACHING);
if (metaTable.getConfiguration().getBoolean(HConstants.USE_META_REPLICAS,
HConstants.DEFAULT_USE_META_REPLICAS)) {
scan.setConsistency(Consistency.TIMELINE);
// Get the region locator's meta replica mode.
CatalogReplicaMode metaReplicaMode = CatalogReplicaMode.fromString(metaTable.getConfiguration()
.get(LOCATOR_META_REPLICAS_MODE, CatalogReplicaMode.NONE.toString()));

switch (metaReplicaMode) {
case LOAD_BALANCE:
int numOfReplicas = 1;
try {
numOfReplicas = metaTable.getDescriptor().get().getRegionReplication();
} catch (Exception e) {
LOG.warn("Failed to get region replication for meta table");
}
if (numOfReplicas > 1) {
int replicaId = ThreadLocalRandom.current().nextInt(numOfReplicas);

// When the replicaId is 0, do not set to Consistency.TIMELINE
if (replicaId > 0) {
scan.setReplicaId(replicaId);
scan.setConsistency(Consistency.TIMELINE);
}
}
break;
case NONE:
// If user does not configure LOCATOR_META_REPLICAS_MODE, let's check the legacy config.
if (metaTable.getConfiguration().getBoolean(HConstants.USE_META_REPLICAS,
HConstants.DEFAULT_USE_META_REPLICAS)) {
scan.setConsistency(Consistency.TIMELINE);
}
break;

default:
// Do nothing
}

if (rowUpperLimit <= scannerCaching) {
scan.setLimit(rowUpperLimit);
}
@@ -50,6 +50,7 @@
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.hadoop.hbase.CatalogFamilyFormat;
import org.apache.hadoop.hbase.CatalogReplicaMode;
import org.apache.hadoop.hbase.HBaseIOException;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionLocation;
@@ -36,6 +36,7 @@
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.IntStream;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.CatalogReplicaMode;
import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseTestingUtil;
import org.apache.hadoop.hbase.HRegionLocation;
@@ -43,6 +43,7 @@
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.client.RegionLocator;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
@@ -385,6 +386,12 @@ private void primaryNoChangeReplicaIncrease(final long[] before, final long[] af
}
}

private void PrimaryIncreaseReplicaIncrease(final long[] before, final long[] after) {
for (int i = 0; i < after.length; i++) {
assertTrue(after[i] > before[i]);
}
}

private void primaryIncreaseReplicaNoChange(final long[] before, final long[] after) {
// There are read requests increase for primary meta replica.
assertTrue(after[RegionInfo.DEFAULT_REPLICA_ID] > before[RegionInfo.DEFAULT_REPLICA_ID]);
@@ -410,6 +417,7 @@ public void testHBaseMetaReplicaGets() throws Exception {
final Region[] metaRegions = getAllRegions(TableName.META_TABLE_NAME, numOfMetaReplica);
long[] readReqsForMetaReplicas = new long[numOfMetaReplica];
long[] readReqsForMetaReplicasAfterGet = new long[numOfMetaReplica];
long[] readReqsForMetaReplicasAfterGetAllLocations = new long[numOfMetaReplica];
long[] readReqsForMetaReplicasAfterMove = new long[numOfMetaReplica];
long[] readReqsForMetaReplicasAfterSecondMove = new long[numOfMetaReplica];
long[] readReqsForMetaReplicasAfterThirdGet = new long[numOfMetaReplica];
@@ -459,6 +467,16 @@ public void testHBaseMetaReplicaGets() throws Exception {
// For rest of meta replicas, there are more reads against them.
primaryNoChangeReplicaIncrease(readReqsForMetaReplicas, readReqsForMetaReplicasAfterGet);

RegionLocator locator = tableForGet.getRegionLocator();

for (int j = 0; j < numOfMetaReplica * 3; j ++) {
locator.getAllRegionLocations();
}

getMetaReplicaReadRequests(metaRegions, readReqsForMetaReplicasAfterGetAllLocations);
PrimaryIncreaseReplicaIncrease(readReqsForMetaReplicasAfterGet,
readReqsForMetaReplicasAfterGetAllLocations);

// move one of regions so it meta cache may be invalid.
HTU.moveRegionAndWait(userRegion.getRegionInfo(), destRs.getServerName());

@@ -468,7 +486,7 @@ public void testHBaseMetaReplicaGets() throws Exception {

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

0 comments on commit 8c60739

Please sign in to comment.