You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@hbase.apache.org by GitBox <gi...@apache.org> on 2020/11/11 16:37:39 UTC

[GitHub] [hbase] huaxiangsun edited a comment on pull request #2645: HBASE-25272 Support scan on a specific replica

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.
   `
   @@ -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();
         }`


----------------------------------------------------------------
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:
users@infra.apache.org