You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by rm...@apache.org on 2026/10/08 19:40:17 UTC
(hbase) branch HBASE-30467-branch-3 created (now 3a4209ddb23)
This is an automated email from the ASF dual-hosted git repository.
rmdmattingly pushed a change to branch HBASE-30467-branch-3
in repository https://gitbox.apache.org/repos/asf/hbase.git
at 3a4209ddb23 HBASE-30467 Exempt scanner close requests from quotas (#8749)
This branch includes the following new commits:
new 3a4209ddb23 HBASE-30467 Exempt scanner close requests from quotas (#8749)
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(hbase) 01/01: HBASE-30467 Exempt scanner close requests from quotas (#8749)
Posted by rm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
rmdmattingly pushed a commit to branch HBASE-30467-branch-3
in repository https://gitbox.apache.org/repos/asf/hbase.git
commit 3a4209ddb239be4bdb5190219b1280fc5721d89b
Author: Ma Zhengxuan <49...@users.noreply.github.com>
AuthorDate: Fri Oct 9 03:28:31 2026 +0800
HBASE-30467 Exempt scanner close requests from quotas (#8749)
Signed-off-by: Ray Mattingly <rm...@apache.org>
---
.../hbase/quotas/RegionServerRpcQuotaManager.java | 6 +++
.../hadoop/hbase/quotas/TestAtomicReadQuota.java | 48 ++++++++++++++++++++++
2 files changed, 54 insertions(+)
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/RegionServerRpcQuotaManager.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/RegionServerRpcQuotaManager.java
index 34fc57cb081..b2716c50e14 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/RegionServerRpcQuotaManager.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/RegionServerRpcQuotaManager.java
@@ -181,6 +181,12 @@ public class RegionServerRpcQuotaManager implements RpcQuotaManager, Configurati
final ClientProtos.ScanRequest scanRequest, long maxScannerResultSize,
long maxBlockBytesScanned, long prevBlockBytesScannedDifference)
throws IOException, RpcThrottlingException {
+ if (
+ scanRequest.hasScannerId() && scanRequest.getCloseScanner()
+ && scanRequest.getNumberOfRows() == 0 && !scanRequest.getRenew()
+ ) {
+ return NoopOperationQuota.get();
+ }
Optional<User> user = RpcServer.getRequestUser();
UserGroupInformation ugi;
if (user.isPresent()) {
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/quotas/TestAtomicReadQuota.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/quotas/TestAtomicReadQuota.java
index 245dd91928f..f9601e008db 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/quotas/TestAtomicReadQuota.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/quotas/TestAtomicReadQuota.java
@@ -17,6 +17,10 @@
*/
package org.apache.hadoop.hbase.quotas;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -31,7 +35,10 @@ import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Increment;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.RowMutations;
+import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
+import org.apache.hadoop.hbase.ipc.HBaseRpcControllerImpl;
+import org.apache.hadoop.hbase.regionserver.RSRpcServices;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.testclassification.RegionServerTests;
@@ -44,6 +51,11 @@ import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException;
+
+import org.apache.hadoop.hbase.shaded.protobuf.RequestConverter;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.ScanResponse;
+
@Tag(RegionServerTests.TAG)
@Tag(MediumTests.TAG)
public class TestAtomicReadQuota {
@@ -71,6 +83,42 @@ public class TestAtomicReadQuota {
TEST_UTIL.waitTableAvailable(TABLE_NAME);
}
+ @Test
+ public void testCloseScannerWhenReadQuotaIsExhausted() throws Exception {
+ setupGenericQuota();
+ try {
+ RSRpcServices rpcServices = TEST_UTIL.getHBaseCluster().getRegionServer(0).getRSRpcServices();
+ int scannerCount = rpcServices.getScannersCount();
+ byte[] regionName = TEST_UTIL.getAdmin().getRegions(TABLE_NAME).get(0).getRegionName();
+ ScanResponse opened = rpcServices.scan(new HBaseRpcControllerImpl(),
+ RequestConverter.buildScanRequest(regionName, new Scan(), 0, false));
+ long scannerId = opened.getScannerId();
+ assertEquals(scannerCount + 1, rpcServices.getScannersCount());
+
+ ServiceException throttled =
+ assertThrows(ServiceException.class, () -> rpcServices.scan(new HBaseRpcControllerImpl(),
+ RequestConverter.buildScanRequest(scannerId, 1, true, false)));
+ assertInstanceOf(RpcThrottlingException.class, throttled.getCause());
+ assertEquals(scannerCount + 1, rpcServices.getScannersCount());
+
+ ServiceException renewThrottled =
+ assertThrows(ServiceException.class, () -> rpcServices.scan(new HBaseRpcControllerImpl(),
+ RequestConverter.buildScanRequest(scannerId, 0, true, 0, false, true, -1)));
+ assertInstanceOf(RpcThrottlingException.class, renewThrottled.getCause());
+
+ ServiceException openThrottled =
+ assertThrows(ServiceException.class, () -> rpcServices.scan(new HBaseRpcControllerImpl(),
+ RequestConverter.buildScanRequest(regionName, new Scan(), 0, true)));
+ assertInstanceOf(RpcThrottlingException.class, openThrottled.getCause());
+
+ rpcServices.scan(new HBaseRpcControllerImpl(),
+ RequestConverter.buildScanRequest(scannerId, 0, true, false));
+ assertEquals(scannerCount, rpcServices.getScannersCount());
+ } finally {
+ cleanupQuota();
+ }
+ }
+
@Test
public void testIncrementCountedAgainstReadCapacity() throws Exception {
setupGenericQuota();