HBASE-22700 refactor isMetaClearingException (#578)

This commit is contained in:
johnhomsea 2019-09-17 01:31:52 +08:00 committed by Michael Stack
parent cfce7a7604
commit 5ccab83d6c
5 changed files with 37 additions and 17 deletions

View File

@ -19,6 +19,7 @@ package org.apache.hadoop.hbase.client;
import static org.apache.hadoop.hbase.exceptions.ClientExceptionsUtil.findException; import static org.apache.hadoop.hbase.exceptions.ClientExceptionsUtil.findException;
import static org.apache.hadoop.hbase.exceptions.ClientExceptionsUtil.isMetaClearingException; import static org.apache.hadoop.hbase.exceptions.ClientExceptionsUtil.isMetaClearingException;
import static org.apache.hadoop.hbase.exceptions.ClientExceptionsUtil.isRegionServerOverloadedException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Optional; import java.util.Optional;
@ -67,7 +68,8 @@ final class AsyncRegionLocatorHelper {
LOG.debug("The actual exception when updating {} is {}", loc, LOG.debug("The actual exception when updating {} is {}", loc,
cause != null ? cause.toString() : "none"); cause != null ? cause.toString() : "none");
} }
if (cause == null || !isMetaClearingException(cause)) { if (cause == null || !isMetaClearingException(cause)
|| isRegionServerOverloadedException(cause)) {
LOG.debug("Will not update {} because the exception is null or not the one we care about", LOG.debug("Will not update {} because the exception is null or not the one we care about",
loc); loc);
return; return;

View File

@ -711,7 +711,8 @@ class AsyncRequestFutureImpl<CResult> implements AsyncRequestFuture {
// Do not use the exception for updating cache because it might be coming from // Do not use the exception for updating cache because it might be coming from
// any of the regions in the MultiAction. // any of the regions in the MultiAction.
updateCachedLocations(server, regionName, row, updateCachedLocations(server, regionName, row,
ClientExceptionsUtil.isMetaClearingException(t) ? null : t); ClientExceptionsUtil.isMetaClearingException(t) &&
!ClientExceptionsUtil.isRegionServerOverloadedException(t) ? null : t);
for (Action action : e.getValue()) { for (Action action : e.getValue()) {
Retry retry = manageError( Retry retry = manageError(
action.getOriginalIndex(), action.getAction(), canRetry, t, server); action.getOriginalIndex(), action.getAction(), canRetry, t, server);
@ -913,7 +914,8 @@ class AsyncRequestFutureImpl<CResult> implements AsyncRequestFuture {
} }
private void cleanServerCache(ServerName server, Throwable regionException) { private void cleanServerCache(ServerName server, Throwable regionException) {
if (ClientExceptionsUtil.isMetaClearingException(regionException)) { if (ClientExceptionsUtil.isMetaClearingException(regionException)
&& !ClientExceptionsUtil.isRegionServerOverloadedException(regionException)) {
// We want to make sure to clear the cache in case there were location-related exceptions. // We want to make sure to clear the cache in case there were location-related exceptions.
// We don't to clear the cache for every possible exception that comes through, however. // We don't to clear the cache for every possible exception that comes through, however.
asyncProcess.connection.clearCaches(server); asyncProcess.connection.clearCaches(server);

View File

@ -1932,7 +1932,8 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
RegionInfo regionInfo = oldLocation.getRegion(); RegionInfo regionInfo = oldLocation.getRegion();
Throwable cause = ClientExceptionsUtil.findException(exception); Throwable cause = ClientExceptionsUtil.findException(exception);
if (cause != null) { if (cause != null) {
if (!ClientExceptionsUtil.isMetaClearingException(cause)) { if (!ClientExceptionsUtil.isMetaClearingException(cause)
|| ClientExceptionsUtil.isRegionServerOverloadedException(cause)) {
// We know that the region is still on this region server // We know that the region is still on this region server
return; return;
} }

View File

@ -32,7 +32,6 @@ import java.util.concurrent.TimeoutException;
import org.apache.hadoop.hbase.CallDroppedException; import org.apache.hadoop.hbase.CallDroppedException;
import org.apache.hadoop.hbase.CallQueueTooBigException; import org.apache.hadoop.hbase.CallQueueTooBigException;
import org.apache.hadoop.hbase.DoNotRetryIOException; import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.MultiActionResultTooLarge;
import org.apache.hadoop.hbase.NotServingRegionException; import org.apache.hadoop.hbase.NotServingRegionException;
import org.apache.hadoop.hbase.RegionTooBusyException; import org.apache.hadoop.hbase.RegionTooBusyException;
import org.apache.hadoop.hbase.RetryImmediatelyException; import org.apache.hadoop.hbase.RetryImmediatelyException;
@ -59,18 +58,28 @@ public final class ClientExceptionsUtil {
if (cur == null) { if (cur == null) {
return true; return true;
} }
return !isSpecialException(cur) || (cur instanceof RegionMovedException) return !isMetaCachePreservingException(cur);
|| cur instanceof NotServingRegionException;
} }
public static boolean isSpecialException(Throwable cur) { public static boolean isRegionServerOverloadedException(Throwable t) {
return (cur instanceof RegionMovedException || cur instanceof RegionOpeningException t = findException(t);
|| cur instanceof RegionTooBusyException || cur instanceof RpcThrottlingException return isInstanceOfRegionServerOverloadedException(t);
|| cur instanceof MultiActionResultTooLarge || cur instanceof RetryImmediatelyException
|| cur instanceof CallQueueTooBigException || cur instanceof CallDroppedException
|| cur instanceof NotServingRegionException || cur instanceof RequestTooBigException);
} }
private static boolean isInstanceOfRegionServerOverloadedException(Throwable t) {
return t instanceof CallQueueTooBigException || t instanceof CallDroppedException;
}
private static boolean isMetaCachePreservingException(Throwable t) {
return t instanceof RegionOpeningException || t instanceof RegionTooBusyException
|| t instanceof RpcThrottlingException || t instanceof RetryImmediatelyException
|| t instanceof RequestTooBigException;
}
private static boolean isExceptionWeCare(Throwable t) {
return isMetaCachePreservingException(t) || isInstanceOfRegionServerOverloadedException(t)
|| t instanceof NotServingRegionException;
}
/** /**
* Look for an exception we know in the remote exception: * Look for an exception we know in the remote exception:
@ -87,7 +96,7 @@ public final class ClientExceptionsUtil {
} }
Throwable cur = (Throwable) exception; Throwable cur = (Throwable) exception;
while (cur != null) { while (cur != null) {
if (isSpecialException(cur)) { if (isExceptionWeCare(cur)) {
return cur; return cur;
} }
if (cur instanceof RemoteException) { if (cur instanceof RemoteException) {

View File

@ -27,6 +27,7 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.CallDroppedException;
import org.apache.hadoop.hbase.CallQueueTooBigException; import org.apache.hadoop.hbase.CallQueueTooBigException;
import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HBaseTestingUtility;
@ -40,6 +41,7 @@ import org.apache.hadoop.hbase.RetryImmediatelyException;
import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.exceptions.ClientExceptionsUtil; import org.apache.hadoop.hbase.exceptions.ClientExceptionsUtil;
import org.apache.hadoop.hbase.exceptions.RegionOpeningException; import org.apache.hadoop.hbase.exceptions.RegionOpeningException;
import org.apache.hadoop.hbase.exceptions.RequestTooBigException;
import org.apache.hadoop.hbase.quotas.RpcThrottlingException; import org.apache.hadoop.hbase.quotas.RpcThrottlingException;
import org.apache.hadoop.hbase.regionserver.HRegionServer; import org.apache.hadoop.hbase.regionserver.HRegionServer;
import org.apache.hadoop.hbase.regionserver.RSRpcServices; import org.apache.hadoop.hbase.regionserver.RSRpcServices;
@ -143,12 +145,14 @@ public class TestMetaCache {
table.mutateRow(mutations); table.mutateRow(mutations);
} catch (IOException ex) { } catch (IOException ex) {
// Only keep track of the last exception that updated the meta cache // Only keep track of the last exception that updated the meta cache
if (ClientExceptionsUtil.isMetaClearingException(ex) || success) { if ((ClientExceptionsUtil.isMetaClearingException(ex)
&& !ClientExceptionsUtil.isRegionServerOverloadedException(ex)) || success) {
exp = ex; exp = ex;
} }
} }
// Do not test if we did not touch the meta cache in this iteration. // Do not test if we did not touch the meta cache in this iteration.
if (exp != null && ClientExceptionsUtil.isMetaClearingException(exp)) { if (exp != null && ClientExceptionsUtil.isMetaClearingException(exp)
&& !ClientExceptionsUtil.isRegionServerOverloadedException(exp)) {
assertNull(conn.getCachedLocation(TABLE_NAME, row)); assertNull(conn.getCachedLocation(TABLE_NAME, row));
} else if (success) { } else if (success) {
assertNotNull(conn.getCachedLocation(TABLE_NAME, row)); assertNotNull(conn.getCachedLocation(TABLE_NAME, row));
@ -207,7 +211,9 @@ public class TestMetaCache {
add(new RpcThrottlingException(" ")); add(new RpcThrottlingException(" "));
add(new MultiActionResultTooLarge(" ")); add(new MultiActionResultTooLarge(" "));
add(new RetryImmediatelyException(" ")); add(new RetryImmediatelyException(" "));
add(new RequestTooBigException());
add(new CallQueueTooBigException()); add(new CallQueueTooBigException());
add(new CallDroppedException());
}}; }};
} }