From dba878051c64ffe06368eaee1d9eda453915b983 Mon Sep 17 00:00:00 2001 From: Richard Marscher Date: Thu, 23 Dec 2021 14:03:45 -0500 Subject: [PATCH 1/3] HBASE-26623 Report CallDroppedException in exception metrics `CallDroppedException` can be thrown with `CallRunner.drop()` by queue implementations that decide to drop calls to groom the RPC call backlog. The LifoCoDel queue does this I believe and with Pluggable queue it's possible for 3rd party queue implementations to be using `drop()` for similar reasons. It would be nice for the server to be tracking these exceptions in metrics since otherwise you might have to do some extra lifting on the client side. --- .../hadoop/hbase/metrics/ExceptionTrackingSource.java | 2 ++ .../hadoop/hbase/metrics/ExceptionTrackingSourceImpl.java | 8 ++++++++ .../org/apache/hadoop/hbase/ipc/MetricsHBaseServer.java | 3 +++ .../java/org/apache/hadoop/hbase/ipc/TestRpcMetrics.java | 5 ++++- .../hadoop/hbase/thrift/ErrorThrowingGetObserver.java | 6 +++++- 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/metrics/ExceptionTrackingSource.java b/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/metrics/ExceptionTrackingSource.java index 6d72d85289aa..2407a7337015 100644 --- a/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/metrics/ExceptionTrackingSource.java +++ b/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/metrics/ExceptionTrackingSource.java @@ -43,6 +43,7 @@ public interface ExceptionTrackingSource extends BaseSource { String EXCEPTIONS_CALL_QUEUE_TOO_BIG_DESC = "Call queue is full"; String EXCEPTIONS_QUOTA_EXCEEDED = "exceptions.quotaExceeded"; String EXCEPTIONS_RPC_THROTTLING = "exceptions.rpcThrottling"; + String EXCEPTIONS_CALL_DROPPED = "exceptions.callDropped"; void exception(); @@ -60,4 +61,5 @@ public interface ExceptionTrackingSource extends BaseSource { void callQueueTooBigException(); void quotaExceededException(); void rpcThrottlingException(); + void callDroppedException(); } diff --git a/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/metrics/ExceptionTrackingSourceImpl.java b/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/metrics/ExceptionTrackingSourceImpl.java index 23dafad02a2e..d6dabadd8e87 100644 --- a/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/metrics/ExceptionTrackingSourceImpl.java +++ b/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/metrics/ExceptionTrackingSourceImpl.java @@ -40,6 +40,7 @@ public class ExceptionTrackingSourceImpl extends BaseSourceImpl protected MutableFastCounter exceptionsCallQueueTooBig; protected MutableFastCounter exceptionsQuotaExceeded; protected MutableFastCounter exceptionsRpcThrottling; + protected MutableFastCounter exceptionsCallDropped; public ExceptionTrackingSourceImpl(String metricsName, String metricsDescription, String metricsContext, String metricsJmxContext) { @@ -72,6 +73,8 @@ public void init() { .newCounter(EXCEPTIONS_QUOTA_EXCEEDED, EXCEPTIONS_TYPE_DESC, 0L); this.exceptionsRpcThrottling = this.getMetricsRegistry() .newCounter(EXCEPTIONS_RPC_THROTTLING, EXCEPTIONS_TYPE_DESC, 0L); + this.exceptionsCallDropped = this.getMetricsRegistry() + .newCounter(EXCEPTIONS_CALL_DROPPED, EXCEPTIONS_TYPE_DESC, 0L); } @Override @@ -133,4 +136,9 @@ public void quotaExceededException() { public void rpcThrottlingException() { exceptionsRpcThrottling.incr(); } + + @Override + public void callDroppedException() { + exceptionsCallDropped.incr(); + } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/MetricsHBaseServer.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/MetricsHBaseServer.java index 11773338869a..d79c8eb4f66a 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/MetricsHBaseServer.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/MetricsHBaseServer.java @@ -19,6 +19,7 @@ package org.apache.hadoop.hbase.ipc; +import org.apache.hadoop.hbase.CallDroppedException; import org.apache.hadoop.hbase.CallQueueTooBigException; import org.apache.hadoop.hbase.MultiActionResultTooLarge; import org.apache.hadoop.hbase.NotServingRegionException; @@ -126,6 +127,8 @@ public void exception(Throwable throwable) { source.quotaExceededException(); } else if (throwable instanceof RpcThrottlingException) { source.rpcThrottlingException(); + } else if (throwable instanceof CallDroppedException) { + source.callDroppedException(); } else if (LOG.isDebugEnabled()) { LOG.debug("Unknown exception type", throwable); } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/ipc/TestRpcMetrics.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/ipc/TestRpcMetrics.java index 2f99d2b65929..1c9b2088339d 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/ipc/TestRpcMetrics.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/ipc/TestRpcMetrics.java @@ -19,6 +19,7 @@ import static org.junit.Assert.*; +import org.apache.hadoop.hbase.CallDroppedException; import org.apache.hadoop.hbase.CompatibilityFactory; import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.NotServingRegionException; @@ -143,11 +144,13 @@ public void testSourceMethods() { mrpc.exception(new RegionTooBusyException("Some region")); mrpc.exception(new OutOfOrderScannerNextException()); mrpc.exception(new NotServingRegionException()); + mrpc.exception(new CallDroppedException()); HELPER.assertCounter("exceptions.RegionMovedException", 1, serverSource); HELPER.assertCounter("exceptions.RegionTooBusyException", 1, serverSource); HELPER.assertCounter("exceptions.OutOfOrderScannerNextException", 1, serverSource); HELPER.assertCounter("exceptions.NotServingRegionException", 1, serverSource); - HELPER.assertCounter("exceptions", 5, serverSource); + HELPER.assertCounter("exceptions.CallDroppedException", 1, serverSource); + HELPER.assertCounter("exceptions", 6, serverSource); } @Test diff --git a/hbase-thrift/src/test/java/org/apache/hadoop/hbase/thrift/ErrorThrowingGetObserver.java b/hbase-thrift/src/test/java/org/apache/hadoop/hbase/thrift/ErrorThrowingGetObserver.java index 98f190b27c51..683884d0efdf 100644 --- a/hbase-thrift/src/test/java/org/apache/hadoop/hbase/thrift/ErrorThrowingGetObserver.java +++ b/hbase-thrift/src/test/java/org/apache/hadoop/hbase/thrift/ErrorThrowingGetObserver.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.Optional; +import org.apache.hadoop.hbase.CallDroppedException; import org.apache.hadoop.hbase.CallQueueTooBigException; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.DoNotRetryIOException; @@ -85,6 +86,8 @@ public void preGetOp(ObserverContext e, throw new QuotaExceededException("Failing for test"); case RPC_THROTTLING: throw new RpcThrottlingException("Failing for test"); + case CALL_DROPPED: + throw new CallDroppedException("Failing for test"); default: throw new DoNotRetryIOException("Failing for test"); } @@ -102,7 +105,8 @@ public enum ErrorType { REGION_TOO_BUSY(ExceptionTrackingSource.EXCEPTIONS_BUSY_NAME), OUT_OF_ORDER_SCANNER_NEXT(ExceptionTrackingSource.EXCEPTIONS_OOO_NAME), QUOTA_EXCEEDED(ExceptionTrackingSource.EXCEPTIONS_QUOTA_EXCEEDED), - RPC_THROTTLING(ExceptionTrackingSource.EXCEPTIONS_RPC_THROTTLING); + RPC_THROTTLING(ExceptionTrackingSource.EXCEPTIONS_RPC_THROTTLING), + CALL_DROPPED(ExceptionTrackingSource.EXCEPTIONS_CALL_DROPPED); private final String metricName; From 416c80eb7bb0faef55827135586b225d52af0de0 Mon Sep 17 00:00:00 2001 From: Richard Marscher Date: Thu, 23 Dec 2021 15:36:15 -0500 Subject: [PATCH 2/3] Fix counter reference in test --- .../test/java/org/apache/hadoop/hbase/ipc/TestRpcMetrics.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/ipc/TestRpcMetrics.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/ipc/TestRpcMetrics.java index 1c9b2088339d..c50414d01ada 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/ipc/TestRpcMetrics.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/ipc/TestRpcMetrics.java @@ -149,7 +149,7 @@ public void testSourceMethods() { HELPER.assertCounter("exceptions.RegionTooBusyException", 1, serverSource); HELPER.assertCounter("exceptions.OutOfOrderScannerNextException", 1, serverSource); HELPER.assertCounter("exceptions.NotServingRegionException", 1, serverSource); - HELPER.assertCounter("exceptions.CallDroppedException", 1, serverSource); + HELPER.assertCounter("exceptions.callDropped", 1, serverSource); HELPER.assertCounter("exceptions", 6, serverSource); } From 97c5be554c205a5f427d564c5500ba5c7010d791 Mon Sep 17 00:00:00 2001 From: Richard Marscher Date: Thu, 23 Dec 2021 21:23:37 -0500 Subject: [PATCH 3/3] Add case for call dropped in thrift metrics --- .../java/org/apache/hadoop/hbase/thrift/ThriftMetrics.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftMetrics.java b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftMetrics.java index 967b0ff417ca..4f88a534a2b2 100644 --- a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftMetrics.java +++ b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftMetrics.java @@ -20,6 +20,7 @@ package org.apache.hadoop.hbase.thrift; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.CallDroppedException; import org.apache.hadoop.hbase.CallQueueTooBigException; import org.apache.hadoop.hbase.CompatibilitySingletonFactory; import org.apache.hadoop.hbase.MultiActionResultTooLarge; @@ -154,6 +155,8 @@ public void exception(Throwable rawThrowable) { source.quotaExceededException(); } else if (throwable instanceof RpcThrottlingException) { source.rpcThrottlingException(); + } else if (throwable instanceof CallDroppedException) { + source.callDroppedException(); } else if (LOG.isDebugEnabled()) { LOG.debug("Unknown exception type", throwable); }