HBASE-19260 Add lock back to avoid parallel accessing meta to locate region

This commit is contained in:
Michael Stack 2017-11-17 14:03:56 -08:00
parent e0c4f374b5
commit 50c3bf9feb
No known key found for this signature in database
GPG Key ID: 9816C7FC8ACC93D2
1 changed files with 26 additions and 19 deletions

View File

@ -47,6 +47,7 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -212,6 +213,9 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
*/ */
private final String alternateBufferedMutatorClassName; private final String alternateBufferedMutatorClassName;
/** lock guards against multiple threads trying to query the meta region at the same time */
private final ReentrantLock userRegionLock = new ReentrantLock();
/** /**
* constructor * constructor
* @param conf Configuration object * @param conf Configuration object
@ -788,12 +792,10 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
} }
int maxAttempts = (retry ? numTries : 1); int maxAttempts = (retry ? numTries : 1);
for (int tries = 0; true; tries++) { for (int tries = 0; true; tries++) {
if (tries >= maxAttempts) { if (tries >= maxAttempts) {
throw new NoServerForRegionException("Unable to find region for " throw new NoServerForRegionException("Unable to find region for "
+ Bytes.toStringBinary(row) + " in " + tableName + + Bytes.toStringBinary(row) + " in " + tableName + " after " + tries + " tries.");
" after " + tries + " tries.");
} }
if (useCache) { if (useCache) {
RegionLocations locations = getCachedLocation(tableName, row); RegionLocations locations = getCachedLocation(tableName, row);
@ -809,7 +811,14 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
// Query the meta region // Query the meta region
long pauseBase = this.pause; long pauseBase = this.pause;
userRegionLock.lock();
try { try {
if (useCache) {// re-check cache after get lock
RegionLocations locations = getCachedLocation(tableName, row);
if (locations != null && locations.getRegionLocation(replicaId) != null) {
return locations;
}
}
Result regionInfoRow = null; Result regionInfoRow = null;
s.resetMvccReadPoint(); s.resetMvccReadPoint();
s.setOneRowLimit(); s.setOneRowLimit();
@ -842,23 +851,20 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
"hbase:meta might be damaged."); "hbase:meta might be damaged.");
} }
if (regionInfo.isSplit()) { if (regionInfo.isSplit()) {
throw new RegionOfflineException("the only available region for" + throw new RegionOfflineException(
" the required row is a split parent," + "the only available region for the required row is a split parent,"
" the daughters should be online soon: " + + " the daughters should be online soon: " + regionInfo.getRegionNameAsString());
regionInfo.getRegionNameAsString());
} }
if (regionInfo.isOffline()) { if (regionInfo.isOffline()) {
throw new RegionOfflineException("the region is offline, could" + throw new RegionOfflineException("the region is offline, could"
" be caused by a disable table call: " + + " be caused by a disable table call: " + regionInfo.getRegionNameAsString());
regionInfo.getRegionNameAsString());
} }
ServerName serverName = locations.getRegionLocation(replicaId).getServerName(); ServerName serverName = locations.getRegionLocation(replicaId).getServerName();
if (serverName == null) { if (serverName == null) {
throw new NoServerForRegionException("No server address listed " + throw new NoServerForRegionException("No server address listed in "
"in " + TableName.META_TABLE_NAME + " for region " + + TableName.META_TABLE_NAME + " for region " + regionInfo.getRegionNameAsString()
regionInfo.getRegionNameAsString() + " containing row " + + " containing row " + Bytes.toStringBinary(row));
Bytes.toStringBinary(row));
} }
if (isDeadServer(serverName)){ if (isDeadServer(serverName)){
@ -885,11 +891,10 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
} }
if (tries < maxAttempts - 1) { if (tries < maxAttempts - 1) {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("locateRegionInMeta parentTable=" + LOG.debug("locateRegionInMeta parentTable=" + TableName.META_TABLE_NAME
TableName.META_TABLE_NAME + ", metaLocation=" + + ", metaLocation=" + ", attempt=" + tries + " of " + maxAttempts
", attempt=" + tries + " of " + + " failed; retrying after sleep of "
maxAttempts + " failed; retrying after sleep of " + + ConnectionUtils.getPauseTime(pauseBase, tries) + " because: " + e.getMessage());
ConnectionUtils.getPauseTime(pauseBase, tries) + " because: " + e.getMessage());
} }
} else { } else {
throw e; throw e;
@ -899,6 +904,8 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
e instanceof NoServerForRegionException)) { e instanceof NoServerForRegionException)) {
relocateRegion(TableName.META_TABLE_NAME, metaKey, replicaId); relocateRegion(TableName.META_TABLE_NAME, metaKey, replicaId);
} }
} finally {
userRegionLock.unlock();
} }
try{ try{
Thread.sleep(ConnectionUtils.getPauseTime(pauseBase, tries)); Thread.sleep(ConnectionUtils.getPauseTime(pauseBase, tries));