huaxiangsun edited a comment on pull request #2645:
URL: https://github.com/apache/hbase/pull/2645#issuecomment-725527074
In ScannerCallableWithReplicas, there is more logic needed in Call(). This
is my patch in backport meta replica client.
{code}
`@@ -18,6 +18,8 @@
package org.apache.hadoop.hbase.client;
import static
org.apache.hadoop.hbase.client.RegionReplicaUtil.DEFAULT_REPLICA_ID;
import static
org.apache.hadoop.hbase.client.RegionReplicaUtil.isScanForSpecificReplicaRegion;
import
org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;
import java.io.IOException;
@@ -45,10 +47,11 @@
/**
* This class has the logic for handling scanners for regions with and
without replicas.
* 1. A scan is attempted on the default (primary) region
* 2. The scanner sends all the RPCs to the default region until it is done,
or, there
* is a timeout on the default (a timeout of zero is disallowed).
* 3. If there is a timeout in (2) above, scanner(s) is opened on the
non-default replica(s)
* 1. A scan is attempted on the default (primary) region, or a specific
region.
* 2. The scanner sends all the RPCs to the default/specific region until it
is done, or, there
* is a timeout on the default/specific region (a timeout of zero is
disallowed).
* 3. If there is a timeout in (2) above, scanner(s) is opened on the
non-default replica(s) only
* for Consistency.TIMELINE without specific replica id specified.
* 4. The results from the first successful scanner are taken, and it is
stored which server
* returned the results.
* 5. The next RPCs are done on the above stored server until it is done or
there is a timeout,
@@ -160,7 +163,7 @@ public MoreResults moreResultsForScan() {
RegionLocations rl = null;
try {
rl = RpcRetryingCallerWithReadReplicas.getRegionLocations(true,
RegionReplicaUtil.DEFAULT_REPLICA_ID, cConnection, tableName,
DEFAULT_REPLICA_ID, cConnection, tableName,
currentScannerCallable.getRow());
} catch (RetriesExhaustedException | DoNotRetryIOException e) {
// We cannot get the primary replica region location, it is possible
that the region server
@@ -209,9 +212,10 @@ public MoreResults moreResultsForScan() {
LOG.debug("Scan with primary region returns " + e.getCause());
}
// If rl's size is 1 or scan's consitency is strong, it needs to throw
// out the exception from the primary replica
if ((regionReplication == 1) || (scan.getConsistency() ==
Consistency.STRONG)) {
// If rl's size is 1 or scan's consitency is strong, or scan is over
specific replica,
// it needs to throw out the exception from the primary replica
if ((regionReplication == 1) || (scan.getConsistency() ==
Consistency.STRONG) ||
isScanForSpecificReplicaRegion(scan)) {
// Rethrow the first exception
RpcRetryingCallerWithReadReplicas.throwEnrichedException(e, retries);
}
@@ -225,8 +229,9 @@ public MoreResults moreResultsForScan() {
// submit call for the all of the secondaries at once
int endIndex = regionReplication;
if (scan.getConsistency() == Consistency.STRONG) {
// When scan's consistency is strong, do not send to the secondaries
if ((scan.getConsistency() == Consistency.STRONG) ||
isScanForSpecificReplicaRegion(scan)){
// When scan's consistency is strong or scan is over specific replica
region,
// do not send to other replica regions.
endIndex = 1;
} else {
// TODO: this may be an overkill for large region replication
@@ -376,11 +381,13 @@ boolean isAnyRPCcancelled() {
this.callable = callable;
// For the Consistency.STRONG (default case), we reuse the caller
// to keep compatibility with what is done in the past
// For the Consistency.TIMELINE case, we can't reuse the caller
// For the Consistency.TIMELINE case, there are two cases. The first
case is that
// caller targets to a specific replica region, it can reuse the
caller.
// Otherwise, we can't reuse the caller
// since we could be making parallel RPCs (caller.callWithRetries is
synchronized
// and we can't invoke it multiple times at the same time)
this.caller = ScannerCallableWithReplicas.this.caller;
if (scan.getConsistency() == Consistency.TIMELINE) {
if (!isScanForSpecificReplicaRegion(scan)) {
this.caller =
RpcRetryingCallerFactory.instantiate(ScannerCallableWithReplicas.this.conf)
.<Result[]>newCaller();
}`
{code}
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]