HBASE-18035 Meta replica does not give any primaryOperationTimeout to primary meta region (huaxiang sun)

This commit is contained in:
tedyu 2017-05-18 15:56:41 -07:00
parent d137991ccc
commit 958cd2d1b7
4 changed files with 109 additions and 6 deletions

View File

@ -40,6 +40,7 @@ public class ConnectionConfiguration {
private final long scannerMaxResultSize;
private final int primaryCallTimeoutMicroSecond;
private final int replicaCallTimeoutMicroSecondScan;
private final int metaReplicaCallTimeoutMicroSecondScan;
private final int retries;
private final int maxKeyValueSize;
private final int rpcTimeout;
@ -55,9 +56,8 @@ public class ConnectionConfiguration {
ConnectionConfiguration(Configuration conf) {
this.writeBufferSize = conf.getLong(WRITE_BUFFER_SIZE_KEY, WRITE_BUFFER_SIZE_DEFAULT);
this.metaOperationTimeout = conf.getInt(
HConstants.HBASE_CLIENT_META_OPERATION_TIMEOUT,
HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT);
this.metaOperationTimeout = conf.getInt(HConstants.HBASE_CLIENT_META_OPERATION_TIMEOUT,
HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT);
this.operationTimeout = conf.getInt(
HConstants.HBASE_CLIENT_OPERATION_TIMEOUT, HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT);
@ -67,7 +67,7 @@ public class ConnectionConfiguration {
this.scannerMaxResultSize =
conf.getLong(HConstants.HBASE_CLIENT_SCANNER_MAX_RESULT_SIZE_KEY,
HConstants.DEFAULT_HBASE_CLIENT_SCANNER_MAX_RESULT_SIZE);
HConstants.DEFAULT_HBASE_CLIENT_SCANNER_MAX_RESULT_SIZE);
this.primaryCallTimeoutMicroSecond =
conf.getInt("hbase.client.primaryCallTimeout.get", 10000); // 10ms
@ -75,6 +75,10 @@ public class ConnectionConfiguration {
this.replicaCallTimeoutMicroSecondScan =
conf.getInt("hbase.client.replicaCallTimeout.scan", 1000000); // 1000 ms
this.metaReplicaCallTimeoutMicroSecondScan =
conf.getInt(HConstants.HBASE_CLIENT_MEAT_REPLICA_SCAN_TIMEOUT,
HConstants.HBASE_CLIENT_MEAT_REPLICA_SCAN_TIMEOUT_DEFAULT);
this.retries = conf.getInt(
HConstants.HBASE_CLIENT_RETRIES_NUMBER, HConstants.DEFAULT_HBASE_CLIENT_RETRIES_NUMBER);
@ -107,6 +111,8 @@ public class ConnectionConfiguration {
this.scannerMaxResultSize = HConstants.DEFAULT_HBASE_CLIENT_SCANNER_MAX_RESULT_SIZE;
this.primaryCallTimeoutMicroSecond = 10000;
this.replicaCallTimeoutMicroSecondScan = 1000000;
this.metaReplicaCallTimeoutMicroSecondScan =
HConstants.HBASE_CLIENT_MEAT_REPLICA_SCAN_TIMEOUT_DEFAULT;
this.retries = HConstants.DEFAULT_HBASE_CLIENT_RETRIES_NUMBER;
this.clientScannerAsyncPrefetch = Scan.DEFAULT_HBASE_CLIENT_SCANNER_ASYNC_PREFETCH;
this.maxKeyValueSize = MAX_KEYVALUE_SIZE_DEFAULT;
@ -147,6 +153,10 @@ public class ConnectionConfiguration {
return replicaCallTimeoutMicroSecondScan;
}
public int getMetaReplicaCallTimeoutMicroSecondScan() {
return metaReplicaCallTimeoutMicroSecondScan;
}
public int getRetriesNumber() {
return retries;
}

View File

@ -139,7 +139,8 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
private final boolean hostnamesCanChange;
private final long pause;
private final long pauseForCQTBE;// pause for CallQueueTooBigException, if specified
private final boolean useMetaReplicas;
private boolean useMetaReplicas;
private final int metaReplicaCallTimeoutScanInMicroSecond;
private final int numTries;
final int rpcTimeout;
@ -235,6 +236,9 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
}
this.useMetaReplicas = conf.getBoolean(HConstants.USE_META_REPLICAS,
HConstants.DEFAULT_USE_META_REPLICAS);
this.metaReplicaCallTimeoutScanInMicroSecond =
connectionConfig.getMetaReplicaCallTimeoutMicroSecondScan();
// how many times to try, one more than max *retry* time
this.numTries = retries2Attempts(connectionConfig.getRetriesNumber());
this.rpcTimeout = conf.getInt(
@ -305,6 +309,14 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
}
}
/**
* @param useMetaReplicas
*/
@VisibleForTesting
void setUseMetaReplicas(final boolean useMetaReplicas) {
this.useMetaReplicas = useMetaReplicas;
}
/**
* @param conn The connection for which to replace the generator.
* @param cnm Replaces the nonce generator used, for testing.
@ -820,7 +832,7 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
s.resetMvccReadPoint();
try (ReversedClientScanner rcs =
new ReversedClientScanner(conf, s, TableName.META_TABLE_NAME, this, rpcCallerFactory,
rpcControllerFactory, getMetaLookupPool(), 0)) {
rpcControllerFactory, getMetaLookupPool(), metaReplicaCallTimeoutScanInMicroSecond)) {
regionInfoRow = rcs.next();
}

View File

@ -307,6 +307,13 @@ public final class HConstants {
/** Default HBase client operation timeout, which is tantamount to a blocking call */
public static final int DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT = 1200000;
/** Parameter name for HBase client meta replica scan call timeout. */
public static final String HBASE_CLIENT_MEAT_REPLICA_SCAN_TIMEOUT =
"hbase.client.meta.replica.scan.timeout";
/** Default HBase client meta replica scan call timeout, 1 second */
public static final int HBASE_CLIENT_MEAT_REPLICA_SCAN_TIMEOUT_DEFAULT = 1000000;
/** Used to construct the name of the log directory for a region server */
public static final String HREGION_LOGDIR_NAME = "WALs";

View File

@ -39,6 +39,7 @@ import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.RegionLocations;
import org.apache.hadoop.hbase.Waiter;
import org.apache.hadoop.hbase.client.replication.ReplicationAdmin;
@ -75,6 +76,7 @@ public class TestReplicaWithCluster {
private static final byte[] f = HConstants.CATALOG_FAMILY;
private final static int REFRESH_PERIOD = 1000;
private final static int META_SCAN_TIMEOUT_IN_MILLISEC = 200;
/**
* This copro is used to synchronize the tests.
@ -157,6 +159,34 @@ public class TestReplicaWithCluster {
}
}
/**
* This copro is used to slow down the primary meta region scan a bit
*/
public static class RegionServerHostingPrimayMetaRegionSlowCopro implements RegionObserver {
static boolean slowDownPrimaryMetaScan = false;
@Override
public RegionScanner preScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> e,
final Scan scan, final RegionScanner s) throws IOException {
int replicaId = e.getEnvironment().getRegion().getRegionInfo().getReplicaId();
// Slow down with the primary meta region scan
if (slowDownPrimaryMetaScan && (e.getEnvironment().getRegion().getRegionInfo().isMetaRegion()
&& (replicaId == 0))) {
LOG.info("Scan with primary meta region, slow down a bit");
try {
Thread.sleep(META_SCAN_TIMEOUT_IN_MILLISEC - 50);
} catch (InterruptedException ie) {
// Ingore
}
}
return null;
}
}
@BeforeClass
public static void beforeClass() throws Exception {
// enable store file refreshing
@ -178,6 +208,19 @@ public class TestReplicaWithCluster {
// Retry less so it can fail faster
HTU.getConfiguration().setInt("hbase.client.retries.number", 1);
// Enable meta replica at server side
HTU.getConfiguration().setInt("hbase.meta.replica.count", 2);
// Make sure master does not host system tables.
HTU.getConfiguration().set("hbase.balancer.tablesOnMaster", "none");
// Set system coprocessor so it can be applied to meta regions
HTU.getConfiguration().set("hbase.coprocessor.region.classes",
RegionServerHostingPrimayMetaRegionSlowCopro.class.getName());
HTU.getConfiguration().setInt(HConstants.HBASE_CLIENT_MEAT_REPLICA_SCAN_TIMEOUT,
META_SCAN_TIMEOUT_IN_MILLISEC * 1000);
HTU.startMiniCluster(NB_SERVERS);
HTU.getHBaseCluster().startMaster();
}
@ -570,4 +613,35 @@ public class TestReplicaWithCluster {
HTU.deleteTable(hdt.getTableName());
}
}
// This test is to test when hbase.client.metaReplicaCallTimeout.scan is configured, meta table
// scan will always get the result from primary meta region as long as the result is returned
// within configured hbase.client.metaReplicaCallTimeout.scan from primary meta region.
@Test
public void testGetRegionLocationFromPrimaryMetaRegion() throws IOException, InterruptedException {
HTU.getAdmin().setBalancerRunning(false, true);
((ConnectionImplementation) HTU.getAdmin().getConnection()).setUseMetaReplicas(true);
// Create table then get the single region for our new table.
HTableDescriptor hdt = HTU.createTableDescriptor("testGetRegionLocationFromPrimaryMetaRegion");
hdt.setRegionReplication(2);
try {
HTU.createTable(hdt, new byte[][] { f }, null);
RegionServerHostingPrimayMetaRegionSlowCopro.slowDownPrimaryMetaScan = true;
// Get user table location, always get it from the primary meta replica
RegionLocations url = ((ClusterConnection) HTU.getConnection())
.locateRegion(hdt.getTableName(), row, false, false);
} finally {
RegionServerHostingPrimayMetaRegionSlowCopro.slowDownPrimaryMetaScan = false;
((ConnectionImplementation) HTU.getAdmin().getConnection()).setUseMetaReplicas(false);
HTU.getAdmin().setBalancerRunning(true, true);
HTU.getAdmin().disableTable(hdt.getTableName());
HTU.deleteTable(hdt.getTableName());
}
}
}