[
https://issues.apache.org/jira/browse/HBASE-25272?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17230087#comment-17230087
]
Huaxiang Sun edited comment on HBASE-25272 at 11/11/20, 4:45 PM:
-----------------------------------------------------------------
add the diff here as it is hard to keep the right format in github comments.
{code:java}
diff --git
a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ScannerCallableWithReplicas.java
b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ScannerCallableWithReplicas.java
index 5fcc440096..6edaa83d11 100644
---
a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ScannerCallableWithReplicas.java
+++
b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ScannerCallableWithReplicas.java
@@ -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 @@ import org.apache.hadoop.hbase.util.Pair;
/**
* 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 @@ class ScannerCallableWithReplicas implements
RetryingCallable<Result[]> {
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 @@ class ScannerCallableWithReplicas implements
RetryingCallable<Result[]> {
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 @@ class ScannerCallableWithReplicas implements
RetryingCallable<Result[]> {
// 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 @@ class ScannerCallableWithReplicas implements
RetryingCallable<Result[]> {
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();
}
/**
* Tell if the input scan targets for a specific replica region in TIMELINE
mode.
* @param scan Scan object
* @return
*/
public static boolean isScanForSpecificReplicaRegion(final Scan scan) {
return (scan.getConsistency() == Consistency.TIMELINE) &&
(scan.getReplicaId() >= 0);
}
{code}
was (Author: huaxiangsun):
add the diff here as it is hard to keep the right format in github comments.
{code:java}
diff --git
a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ScannerCallableWithReplicas.java
b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ScannerCallableWithReplicas.java
index 5fcc440096..6edaa83d11 100644
---
a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ScannerCallableWithReplicas.java
+++
b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ScannerCallableWithReplicas.java
@@ -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 @@ import org.apache.hadoop.hbase.util.Pair;
/**
* 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 @@ class ScannerCallableWithReplicas implements
RetryingCallable<Result[]> {
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 @@ class ScannerCallableWithReplicas implements
RetryingCallable<Result[]> {
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 @@ class ScannerCallableWithReplicas implements
RetryingCallable<Result[]> {
// 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 @@ class ScannerCallableWithReplicas implements
RetryingCallable<Result[]> {
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}
> Support scan on a specific replica
> ----------------------------------
>
> Key: HBASE-25272
> URL: https://issues.apache.org/jira/browse/HBASE-25272
> Project: HBase
> Issue Type: Improvement
> Components: Client, scan
> Reporter: Duo Zhang
> Assignee: Duo Zhang
> Priority: Critical
> Fix For: 2.4.0
>
>
> This is a missing part of the client library for sync client on branch-2, and
> it is necessary when implementing meta replicas read.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)