HBASE-18004 getRegionLocations needs to be called once in

ScannerCallableWithReplicas#call() (Huaxiang Sun)
This commit is contained in:
Michael Stack 2017-06-15 13:41:01 -07:00
parent d023508b5b
commit 4184ae7563
2 changed files with 29 additions and 24 deletions

View File

@ -72,6 +72,7 @@ class ScannerCallableWithReplicas implements RetryingCallable<Result[]> {
private int scannerTimeout;
private Set<ScannerCallable> outstandingCallables = new HashSet<>();
private boolean someRPCcancelled = false; //required for testing purposes only
private int regionReplication = 0;
public ScannerCallableWithReplicas(TableName tableName, ClusterConnection cConnection,
ScannerCallable baseCallable, ExecutorService pool, int timeBeforeReplicas, Scan scan,
@ -143,36 +144,42 @@ class ScannerCallableWithReplicas implements RetryingCallable<Result[]> {
//2. We should close the "losing" scanners (scanners other than the ones we hear back
// from first)
//
RegionLocations rl = null;
try {
rl = RpcRetryingCallerWithReadReplicas.getRegionLocations(true,
RegionReplicaUtil.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
// hosting meta table is down, it needs to proceed to try cached replicas directly.
if (cConnection instanceof ConnectionImplementation) {
rl = ((ConnectionImplementation) cConnection)
.getCachedLocation(tableName, currentScannerCallable.getRow());
if (rl == null) {
// Since RegionReplication is a table attribute, it wont change as long as table is enabled,
// it just needs to be set once.
if (regionReplication <= 0) {
RegionLocations rl = null;
try {
rl = RpcRetryingCallerWithReadReplicas.getRegionLocations(true,
RegionReplicaUtil.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
// hosting meta table is down, it needs to proceed to try cached replicas directly.
if (cConnection instanceof ConnectionImplementation) {
rl = ((ConnectionImplementation) cConnection)
.getCachedLocation(tableName, currentScannerCallable.getRow());
if (rl == null) {
throw e;
}
} else {
// For completeness
throw e;
}
} else {
// For completeness
throw e;
}
regionReplication = rl.size();
}
// allocate a boundedcompletion pool of some multiple of number of replicas.
// We want to accomodate some RPCs for redundant replica scans (but are still in progress)
ResultBoundedCompletionService<Pair<Result[], ScannerCallable>> cs =
new ResultBoundedCompletionService<>(
RpcRetryingCallerFactory.instantiate(ScannerCallableWithReplicas.this.conf), pool,
rl.size() * 5);
regionReplication * 5);
AtomicBoolean done = new AtomicBoolean(false);
replicaSwitched.set(false);
// submit call for the primary replica.
addCallsForCurrentReplica(cs, rl);
addCallsForCurrentReplica(cs);
int startIndex = 0;
try {
@ -195,7 +202,7 @@ class ScannerCallableWithReplicas implements RetryingCallable<Result[]> {
// If rl's size is 1 or scan's consitency is strong, it needs to throw
// out the exception from the primary replica
if ((rl.size() == 1) || (scan.getConsistency() == Consistency.STRONG)) {
if ((regionReplication == 1) || (scan.getConsistency() == Consistency.STRONG)) {
// Rethrow the first exception
RpcRetryingCallerWithReadReplicas.throwEnrichedException(e, retries);
}
@ -208,13 +215,13 @@ class ScannerCallableWithReplicas implements RetryingCallable<Result[]> {
}
// submit call for the all of the secondaries at once
int endIndex = rl.size();
int endIndex = regionReplication;
if (scan.getConsistency() == Consistency.STRONG) {
// When scan's consistency is strong, do not send to the secondaries
endIndex = 1;
} else {
// TODO: this may be an overkill for large region replication
addCallsForOtherReplicas(cs, rl, 0, rl.size() - 1);
addCallsForOtherReplicas(cs, 0, regionReplication - 1);
}
try {
@ -307,15 +314,14 @@ class ScannerCallableWithReplicas implements RetryingCallable<Result[]> {
}
private void addCallsForCurrentReplica(
ResultBoundedCompletionService<Pair<Result[], ScannerCallable>> cs, RegionLocations rl) {
ResultBoundedCompletionService<Pair<Result[], ScannerCallable>> cs) {
RetryingRPC retryingOnReplica = new RetryingRPC(currentScannerCallable);
outstandingCallables.add(currentScannerCallable);
cs.submit(retryingOnReplica, scannerTimeout, currentScannerCallable.id);
}
private void addCallsForOtherReplicas(
ResultBoundedCompletionService<Pair<Result[], ScannerCallable>> cs, RegionLocations rl,
int min, int max) {
ResultBoundedCompletionService<Pair<Result[], ScannerCallable>> cs, int min, int max) {
for (int id = min; id <= max; id++) {
if (currentScannerCallable.id == id) {

View File

@ -27,7 +27,6 @@ import java.lang.reflect.Constructor;
import java.net.BindException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;