You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by bb...@apache.org on 2023/02/05 22:31:21 UTC
[hbase] branch branch-2 updated: HBASE-27534 Determine too large requests by response block size rather than just cell size (#5007)
This is an automated email from the ASF dual-hosted git repository.
bbeaudreault pushed a commit to branch branch-2
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-2 by this push:
new 3358db1f975 HBASE-27534 Determine too large requests by response block size rather than just cell size (#5007)
3358db1f975 is described below
commit 3358db1f975bb841636a70f4180bce97fc715cef
Author: Bryan Beaudreault <bb...@apache.org>
AuthorDate: Sun Feb 5 16:54:21 2023 -0500
HBASE-27534 Determine too large requests by response block size rather than just cell size (#5007)
Signed-off-by: Duo Zhang <zh...@apache.org>
---
.../hadoop/hbase/client/OnlineLogRecord.java | 51 +++++++---
.../hadoop/hbase/shaded/protobuf/ProtobufUtil.java | 1 +
.../hadoop/hbase/slowlog/SlowLogTableAccessor.java | 2 +
.../src/main/protobuf/TooSlowLog.proto | 2 +
.../org/apache/hadoop/hbase/ipc/RpcServer.java | 36 ++++---
.../hadoop/hbase/namequeues/RpcLogDetails.java | 8 +-
.../hbase/namequeues/impl/SlowLogQueueService.java | 6 +-
.../regionserver/rsOperationDetails.jsp | 4 +
.../hbase/namequeues/TestNamedQueueRecorder.java | 5 +-
.../hadoop/hbase/namequeues/TestTooLargeLog.java | 107 ++++++++++++++++++++
.../hadoop/hbase/thrift2/ThriftUtilities.java | 2 +
.../hbase/thrift2/generated/TOnlineLogRecord.java | 111 +++++++++++++++++++--
.../org/apache/hadoop/hbase/thrift2/hbase.thrift | 3 +-
13 files changed, 294 insertions(+), 44 deletions(-)
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/OnlineLogRecord.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/OnlineLogRecord.java
index 96182ca4b29..3ea3061a62f 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/OnlineLogRecord.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/OnlineLogRecord.java
@@ -59,6 +59,7 @@ final public class OnlineLogRecord extends LogEntry {
private final int processingTime;
private final int queueTime;
private final long responseSize;
+ private final long blockBytesScanned;
private final String clientAddress;
private final String serverClass;
private final String methodName;
@@ -88,6 +89,13 @@ final public class OnlineLogRecord extends LogEntry {
return responseSize;
}
+ /**
+ * Return the amount of block bytes scanned to retrieve the response cells.
+ */
+ public long getBlockBytesScanned() {
+ return blockBytesScanned;
+ }
+
public String getClientAddress() {
return clientAddress;
}
@@ -129,14 +137,15 @@ final public class OnlineLogRecord extends LogEntry {
}
private OnlineLogRecord(final long startTime, final int processingTime, final int queueTime,
- final long responseSize, final String clientAddress, final String serverClass,
- final String methodName, final String callDetails, final String param, final String regionName,
- final String userName, final int multiGetsCount, final int multiMutationsCount,
- final int multiServiceCalls) {
+ final long responseSize, final long blockBytesScanned, final String clientAddress,
+ final String serverClass, final String methodName, final String callDetails, final String param,
+ final String regionName, final String userName, final int multiGetsCount,
+ final int multiMutationsCount, final int multiServiceCalls) {
this.startTime = startTime;
this.processingTime = processingTime;
this.queueTime = queueTime;
this.responseSize = responseSize;
+ this.blockBytesScanned = blockBytesScanned;
this.clientAddress = clientAddress;
this.serverClass = serverClass;
this.methodName = methodName;
@@ -154,6 +163,7 @@ final public class OnlineLogRecord extends LogEntry {
private int processingTime;
private int queueTime;
private long responseSize;
+ private long blockBytesScanned;
private String clientAddress;
private String serverClass;
private String methodName;
@@ -185,6 +195,14 @@ final public class OnlineLogRecord extends LogEntry {
return this;
}
+ /**
+ * Sets the amount of block bytes scanned to retrieve the response cells.
+ */
+ public OnlineLogRecordBuilder setBlockBytesScanned(long blockBytesScanned) {
+ this.blockBytesScanned = blockBytesScanned;
+ return this;
+ }
+
public OnlineLogRecordBuilder setClientAddress(String clientAddress) {
this.clientAddress = clientAddress;
return this;
@@ -236,9 +254,9 @@ final public class OnlineLogRecord extends LogEntry {
}
public OnlineLogRecord build() {
- return new OnlineLogRecord(startTime, processingTime, queueTime, responseSize, clientAddress,
- serverClass, methodName, callDetails, param, regionName, userName, multiGetsCount,
- multiMutationsCount, multiServiceCalls);
+ return new OnlineLogRecord(startTime, processingTime, queueTime, responseSize,
+ blockBytesScanned, clientAddress, serverClass, methodName, callDetails, param, regionName,
+ userName, multiGetsCount, multiMutationsCount, multiServiceCalls);
}
}
@@ -256,7 +274,8 @@ final public class OnlineLogRecord extends LogEntry {
return new EqualsBuilder().append(startTime, that.startTime)
.append(processingTime, that.processingTime).append(queueTime, that.queueTime)
- .append(responseSize, that.responseSize).append(multiGetsCount, that.multiGetsCount)
+ .append(responseSize, that.responseSize).append(blockBytesScanned, that.blockBytesScanned)
+ .append(multiGetsCount, that.multiGetsCount)
.append(multiMutationsCount, that.multiMutationsCount)
.append(multiServiceCalls, that.multiServiceCalls).append(clientAddress, that.clientAddress)
.append(serverClass, that.serverClass).append(methodName, that.methodName)
@@ -267,9 +286,9 @@ final public class OnlineLogRecord extends LogEntry {
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37).append(startTime).append(processingTime).append(queueTime)
- .append(responseSize).append(clientAddress).append(serverClass).append(methodName)
- .append(callDetails).append(param).append(regionName).append(userName).append(multiGetsCount)
- .append(multiMutationsCount).append(multiServiceCalls).toHashCode();
+ .append(responseSize).append(blockBytesScanned).append(clientAddress).append(serverClass)
+ .append(methodName).append(callDetails).append(param).append(regionName).append(userName)
+ .append(multiGetsCount).append(multiMutationsCount).append(multiServiceCalls).toHashCode();
}
@Override
@@ -281,11 +300,11 @@ final public class OnlineLogRecord extends LogEntry {
public String toString() {
return new ToStringBuilder(this).append("startTime", startTime)
.append("processingTime", processingTime).append("queueTime", queueTime)
- .append("responseSize", responseSize).append("clientAddress", clientAddress)
- .append("serverClass", serverClass).append("methodName", methodName)
- .append("callDetails", callDetails).append("param", param).append("regionName", regionName)
- .append("userName", userName).append("multiGetsCount", multiGetsCount)
- .append("multiMutationsCount", multiMutationsCount)
+ .append("responseSize", responseSize).append("blockBytesScanned", blockBytesScanned)
+ .append("clientAddress", clientAddress).append("serverClass", serverClass)
+ .append("methodName", methodName).append("callDetails", callDetails).append("param", param)
+ .append("regionName", regionName).append("userName", userName)
+ .append("multiGetsCount", multiGetsCount).append("multiMutationsCount", multiMutationsCount)
.append("multiServiceCalls", multiServiceCalls).toString();
}
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java
index 5a36374867a..755cd7bb8a7 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java
@@ -3334,6 +3334,7 @@ public final class ProtobufUtil {
.setParam(slowLogPayload.getParam()).setProcessingTime(slowLogPayload.getProcessingTime())
.setQueueTime(slowLogPayload.getQueueTime()).setRegionName(slowLogPayload.getRegionName())
.setResponseSize(slowLogPayload.getResponseSize())
+ .setBlockBytesScanned(slowLogPayload.getBlockBytesScanned())
.setServerClass(slowLogPayload.getServerClass()).setStartTime(slowLogPayload.getStartTime())
.setUserName(slowLogPayload.getUserName()).build();
return onlineLogRecord;
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/slowlog/SlowLogTableAccessor.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/slowlog/SlowLogTableAccessor.java
index e6db8f43017..6a45c0ffa88 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/slowlog/SlowLogTableAccessor.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/slowlog/SlowLogTableAccessor.java
@@ -87,6 +87,8 @@ public class SlowLogTableAccessor {
Bytes.toBytes(slowLogPayload.getRegionName()))
.addColumn(HConstants.SLOWLOG_INFO_FAMILY, Bytes.toBytes("response_size"),
Bytes.toBytes(Long.toString(slowLogPayload.getResponseSize())))
+ .addColumn(HConstants.SLOWLOG_INFO_FAMILY, Bytes.toBytes("block_bytes_scanned"),
+ Bytes.toBytes(Long.toString(slowLogPayload.getBlockBytesScanned())))
.addColumn(HConstants.SLOWLOG_INFO_FAMILY, Bytes.toBytes("server_class"),
Bytes.toBytes(slowLogPayload.getServerClass()))
.addColumn(HConstants.SLOWLOG_INFO_FAMILY, Bytes.toBytes("start_time"),
diff --git a/hbase-protocol-shaded/src/main/protobuf/TooSlowLog.proto b/hbase-protocol-shaded/src/main/protobuf/TooSlowLog.proto
index 36ed9d504a7..4ed0324e5a8 100644
--- a/hbase-protocol-shaded/src/main/protobuf/TooSlowLog.proto
+++ b/hbase-protocol-shaded/src/main/protobuf/TooSlowLog.proto
@@ -44,6 +44,8 @@ message SlowLogPayload {
optional int32 multi_service_calls = 14 [default = 0];
required Type type = 15;
+ optional int64 block_bytes_scanned = 16;
+
// SLOW_LOG is RPC call slow in nature whereas LARGE_LOG is RPC call quite large.
// Majority of times, slow logs are also large logs and hence, ALL is combination of
// both
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/RpcServer.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/RpcServer.java
index 39aca2c54fb..962c14c73d7 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/RpcServer.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/RpcServer.java
@@ -428,6 +428,7 @@ public abstract class RpcServer implements RpcServerInterface, ConfigurationObse
// Use the raw request call size for now.
long requestSize = call.getSize();
long responseSize = result.getSerializedSize();
+ long responseBlockSize = call.getResponseBlockSize();
if (call.isClientCellBlockSupported()) {
// Include the payload size in HBaseRpcController
responseSize += call.getResponseCellSize();
@@ -441,20 +442,21 @@ public abstract class RpcServer implements RpcServerInterface, ConfigurationObse
// log any RPC responses that are slower than the configured warn
// response time or larger than configured warning size
boolean tooSlow = (processingTime > warnResponseTime && warnResponseTime > -1);
- boolean tooLarge = (responseSize > warnResponseSize && warnResponseSize > -1);
+ boolean tooLarge = (warnResponseSize > -1
+ && (responseSize > warnResponseSize || responseBlockSize > warnResponseSize));
if (tooSlow || tooLarge) {
final String userName = call.getRequestUserName().orElse(StringUtils.EMPTY);
// when tagging, we let TooLarge trump TooSmall to keep output simple
// note that large responses will often also be slow.
logResponse(param, md.getName(), md.getName() + "(" + param.getClass().getName() + ")",
tooLarge, tooSlow, status.getClient(), startTime, processingTime, qTime, responseSize,
- userName);
+ responseBlockSize, userName);
if (this.namedQueueRecorder != null && this.isOnlineLogProviderEnabled) {
// send logs to ring buffer owned by slowLogRecorder
final String className =
server == null ? StringUtils.EMPTY : server.getClass().getSimpleName();
this.namedQueueRecorder.addRecord(new RpcLogDetails(call, param, status.getClient(),
- responseSize, className, tooSlow, tooLarge));
+ responseSize, responseBlockSize, className, tooSlow, tooLarge));
}
}
return new Pair<>(result, controller.cellScanner());
@@ -482,22 +484,23 @@ public abstract class RpcServer implements RpcServerInterface, ConfigurationObse
/**
* Logs an RPC response to the LOG file, producing valid JSON objects for client Operations.
- * @param param The parameters received in the call.
- * @param methodName The name of the method invoked
- * @param call The string representation of the call
- * @param tooLarge To indicate if the event is tooLarge
- * @param tooSlow To indicate if the event is tooSlow
- * @param clientAddress The address of the client who made this call.
- * @param startTime The time that the call was initiated, in ms.
- * @param processingTime The duration that the call took to run, in ms.
- * @param qTime The duration that the call spent on the queue prior to being initiated,
- * in ms.
- * @param responseSize The size in bytes of the response buffer.
- * @param userName UserName of the current RPC Call
+ * @param param The parameters received in the call.
+ * @param methodName The name of the method invoked
+ * @param call The string representation of the call
+ * @param tooLarge To indicate if the event is tooLarge
+ * @param tooSlow To indicate if the event is tooSlow
+ * @param clientAddress The address of the client who made this call.
+ * @param startTime The time that the call was initiated, in ms.
+ * @param processingTime The duration that the call took to run, in ms.
+ * @param qTime The duration that the call spent on the queue prior to being
+ * initiated, in ms.
+ * @param responseSize The size in bytes of the response buffer.
+ * @param blockBytesScanned The size of block bytes scanned to retrieve the response.
+ * @param userName UserName of the current RPC Call
*/
void logResponse(Message param, String methodName, String call, boolean tooLarge, boolean tooSlow,
String clientAddress, long startTime, int processingTime, int qTime, long responseSize,
- String userName) {
+ long blockBytesScanned, String userName) {
final String className = server == null ? StringUtils.EMPTY : server.getClass().getSimpleName();
// base information that is reported regardless of type of call
Map<String, Object> responseInfo = new HashMap<>();
@@ -505,6 +508,7 @@ public abstract class RpcServer implements RpcServerInterface, ConfigurationObse
responseInfo.put("processingtimems", processingTime);
responseInfo.put("queuetimems", qTime);
responseInfo.put("responsesize", responseSize);
+ responseInfo.put("blockbytesscanned", blockBytesScanned);
responseInfo.put("client", clientAddress);
responseInfo.put("class", className);
responseInfo.put("method", methodName);
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/namequeues/RpcLogDetails.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/namequeues/RpcLogDetails.java
index 7a2d9b6ded3..c0baf21e434 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/namequeues/RpcLogDetails.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/namequeues/RpcLogDetails.java
@@ -35,17 +35,19 @@ public class RpcLogDetails extends NamedQueuePayload {
private final Message param;
private final String clientAddress;
private final long responseSize;
+ private final long blockBytesScanned;
private final String className;
private final boolean isSlowLog;
private final boolean isLargeLog;
public RpcLogDetails(RpcCall rpcCall, Message param, String clientAddress, long responseSize,
- String className, boolean isSlowLog, boolean isLargeLog) {
+ long blockBytesScanned, String className, boolean isSlowLog, boolean isLargeLog) {
super(SLOW_LOG_EVENT);
this.rpcCall = rpcCall;
this.param = param;
this.clientAddress = clientAddress;
this.responseSize = responseSize;
+ this.blockBytesScanned = blockBytesScanned;
this.className = className;
this.isSlowLog = isSlowLog;
this.isLargeLog = isLargeLog;
@@ -63,6 +65,10 @@ public class RpcLogDetails extends NamedQueuePayload {
return responseSize;
}
+ public long getBlockBytesScanned() {
+ return blockBytesScanned;
+ }
+
public String getClassName() {
return className;
}
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/namequeues/impl/SlowLogQueueService.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/namequeues/impl/SlowLogQueueService.java
index 86b24e9d975..fb002fdf3e8 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/namequeues/impl/SlowLogQueueService.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/namequeues/impl/SlowLogQueueService.java
@@ -116,6 +116,7 @@ public class SlowLogQueueService implements NamedQueueService {
final RpcCall rpcCall = rpcLogDetails.getRpcCall();
final String clientAddress = rpcLogDetails.getClientAddress();
final long responseSize = rpcLogDetails.getResponseSize();
+ final long blockBytesScanned = rpcLogDetails.getBlockBytesScanned();
final String className = rpcLogDetails.getClassName();
final TooSlowLog.SlowLogPayload.Type type = getLogType(rpcLogDetails);
if (type == null) {
@@ -158,8 +159,9 @@ public class SlowLogQueueService implements NamedQueueService {
.setParam(slowLogParams != null ? slowLogParams.getParams() : StringUtils.EMPTY)
.setProcessingTime(processingTime).setQueueTime(qTime)
.setRegionName(slowLogParams != null ? slowLogParams.getRegionName() : StringUtils.EMPTY)
- .setResponseSize(responseSize).setServerClass(className).setStartTime(startTime).setType(type)
- .setUserName(userName).build();
+ .setResponseSize(responseSize).setBlockBytesScanned(blockBytesScanned)
+ .setServerClass(className).setStartTime(startTime).setType(type).setUserName(userName)
+ .build();
slowLogQueue.add(slowLogPayload);
if (isSlowLogTableEnabled) {
if (!slowLogPayload.getRegionName().startsWith("hbase:slowlog")) {
diff --git a/hbase-server/src/main/resources/hbase-webapps/regionserver/rsOperationDetails.jsp b/hbase-server/src/main/resources/hbase-webapps/regionserver/rsOperationDetails.jsp
index b606ae40f8a..a1ff23143ba 100644
--- a/hbase-server/src/main/resources/hbase-webapps/regionserver/rsOperationDetails.jsp
+++ b/hbase-server/src/main/resources/hbase-webapps/regionserver/rsOperationDetails.jsp
@@ -97,6 +97,7 @@
<th>Processing Time</th>
<th>Queue Time</th>
<th>Response Size</th>
+ <th>Block Bytes Scanned</th>
<th>Client Address</th>
<th>Server Class</th>
<th>Method Name</th>
@@ -115,6 +116,7 @@
<td><%=r.getProcessingTime()%>ms</td>
<td><%=r.getQueueTime()%>ms</td>
<td><%=StringUtils.byteDesc(r.getResponseSize())%></td>
+ <td><%=StringUtils.byteDesc(r.getBlockBytesScanned())%></td>
<td><%=r.getClientAddress()%></td>
<td><%=r.getServerClass()%></td>
<td><%=r.getMethodName()%></td>
@@ -138,6 +140,7 @@
<th>Processing Time</th>
<th>Queue Time</th>
<th>Response Size</th>
+ <th>Block Bytes Scanned</th>
<th>Client Address</th>
<th>Server Class</th>
<th>Method Name</th>
@@ -156,6 +159,7 @@
<td><%=r.getProcessingTime()%>ms</td>
<td><%=r.getQueueTime()%>ms</td>
<td><%=StringUtils.byteDesc(r.getResponseSize())%></td>
+ <td><%=StringUtils.byteDesc(r.getBlockBytesScanned())%></td>
<td><%=r.getClientAddress()%></td>
<td><%=r.getServerClass()%></td>
<td><%=r.getMethodName()%></td>
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/namequeues/TestNamedQueueRecorder.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/namequeues/TestNamedQueueRecorder.java
index 8ae27478a18..a04783f5490 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/namequeues/TestNamedQueueRecorder.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/namequeues/TestNamedQueueRecorder.java
@@ -529,13 +529,14 @@ public class TestNamedQueueRecorder {
static RpcLogDetails getRpcLogDetails(String userName, String clientAddress, String className) {
RpcCall rpcCall = getRpcCall(userName);
- return new RpcLogDetails(rpcCall, rpcCall.getParam(), clientAddress, 0, className, true, true);
+ return new RpcLogDetails(rpcCall, rpcCall.getParam(), clientAddress, 0, 0, className, true,
+ true);
}
private RpcLogDetails getRpcLogDetails(String userName, String clientAddress, String className,
boolean isSlowLog, boolean isLargeLog) {
RpcCall rpcCall = getRpcCall(userName);
- return new RpcLogDetails(rpcCall, rpcCall.getParam(), clientAddress, 0, className, isSlowLog,
+ return new RpcLogDetails(rpcCall, rpcCall.getParam(), clientAddress, 0, 0, className, isSlowLog,
isLargeLog);
}
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/namequeues/TestTooLargeLog.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/namequeues/TestTooLargeLog.java
new file mode 100644
index 00000000000..d865131deb8
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/namequeues/TestTooLargeLog.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.namequeues;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import org.apache.hadoop.hbase.HBaseClassTestRule;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.ServerName;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.Admin;
+import org.apache.hadoop.hbase.client.LogEntry;
+import org.apache.hadoop.hbase.client.OnlineLogRecord;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.client.ServerType;
+import org.apache.hadoop.hbase.client.Table;
+import org.apache.hadoop.hbase.testclassification.MediumTests;
+import org.apache.hadoop.hbase.testclassification.RegionServerTests;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TestName;
+
+@Category({ RegionServerTests.class, MediumTests.class })
+public class TestTooLargeLog {
+
+ @ClassRule
+ public static final HBaseClassTestRule CLASS_RULE =
+ HBaseClassTestRule.forClass(TestTooLargeLog.class);
+
+ protected final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
+ protected static Admin ADMIN;
+
+ @Rule
+ public TestName name = new TestName();
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ TEST_UTIL.getConfiguration().setBoolean(HConstants.SLOW_LOG_BUFFER_ENABLED_KEY, true);
+ TEST_UTIL.getConfiguration().setInt("hbase.ipc.warn.response.size", 100);
+ TEST_UTIL.startMiniCluster(1);
+ ADMIN = TEST_UTIL.getAdmin();
+ }
+
+ /**
+ * Tests that we can trigger based on blocks scanned, and also that we properly pass the block
+ * bytes scanned value through to the client.
+ */
+ @Test
+ public void testLogLargeBlockBytesScanned() throws IOException, InterruptedException {
+ byte[] family = Bytes.toBytes("0");
+ Table table = TEST_UTIL.createTable(TableName.valueOf("testLogLargeBlockBytesScanned"), family);
+ TEST_UTIL.loadTable(table, family);
+ TEST_UTIL.flush(table.getName());
+
+ Set<ServerName> server =
+ Collections.singleton(TEST_UTIL.getHBaseCluster().getRegionServer(0).getServerName());
+ Admin admin = TEST_UTIL.getAdmin();
+ admin.clearSlowLogResponses(server);
+
+ Scan scan = new Scan();
+ scan.setCaching(1);
+
+ try (ResultScanner scanner = table.getScanner(scan)) {
+ scanner.next();
+ }
+
+ List<LogEntry> entries =
+ admin.getLogEntries(server, "LARGE_LOG", ServerType.REGION_SERVER, 1, Collections.emptyMap());
+
+ assertEquals(1, entries.size());
+
+ OnlineLogRecord record = (OnlineLogRecord) entries.get(0);
+ System.out.println(record.toJsonPrettyPrint());
+
+ assertTrue("expected " + record.getBlockBytesScanned() + " to be >= 100",
+ record.getBlockBytesScanned() >= 100);
+ assertTrue("expected " + record.getResponseSize() + " to be < 100",
+ record.getResponseSize() < 100);
+
+ }
+}
diff --git a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/ThriftUtilities.java b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/ThriftUtilities.java
index 3a335e974bc..303309e4529 100644
--- a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/ThriftUtilities.java
+++ b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/ThriftUtilities.java
@@ -1650,6 +1650,7 @@ public class ThriftUtilities {
tOnlineLogRecord.setQueueTime(slowLogRecord.getQueueTime());
tOnlineLogRecord.setRegionName(slowLogRecord.getRegionName());
tOnlineLogRecord.setResponseSize(slowLogRecord.getResponseSize());
+ tOnlineLogRecord.setBlockBytesScanned(slowLogRecord.getBlockBytesScanned());
tOnlineLogRecord.setServerClass(slowLogRecord.getServerClass());
tOnlineLogRecord.setStartTime(slowLogRecord.getStartTime());
tOnlineLogRecord.setUserName(slowLogRecord.getUserName());
@@ -1673,6 +1674,7 @@ public class ThriftUtilities {
.setParam(tSlowLogRecord.getParam()).setProcessingTime(tSlowLogRecord.getProcessingTime())
.setQueueTime(tSlowLogRecord.getQueueTime()).setRegionName(tSlowLogRecord.getRegionName())
.setResponseSize(tSlowLogRecord.getResponseSize())
+ .setBlockBytesScanned(tSlowLogRecord.getBlockBytesScanned())
.setServerClass(tSlowLogRecord.getServerClass()).setStartTime(tSlowLogRecord.getStartTime())
.setUserName(tSlowLogRecord.getUserName()).build())
.collect(Collectors.toList());
diff --git a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TOnlineLogRecord.java b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TOnlineLogRecord.java
index 2362a05bf20..eb5c7d6b287 100644
--- a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TOnlineLogRecord.java
+++ b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TOnlineLogRecord.java
@@ -9,9 +9,9 @@ package org.apache.hadoop.hbase.thrift2.generated;
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
/**
* Thrift wrapper around
- * org.apache.hadoop.hbase.client.OnlineLogRecordrd
+ * org.apache.hadoop.hbase.client.OnlineLogRecord
*/
-@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.14.1)", date = "2022-07-05")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.14.1)", date = "2023-02-05")
public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecord, TOnlineLogRecord._Fields>, java.io.Serializable, Cloneable, Comparable<TOnlineLogRecord> {
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TOnlineLogRecord");
@@ -29,6 +29,7 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
private static final org.apache.thrift.protocol.TField MULTI_MUTATIONS_COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("multiMutationsCount", org.apache.thrift.protocol.TType.I32, (short)12);
private static final org.apache.thrift.protocol.TField MULTI_SERVICE_CALLS_FIELD_DESC = new org.apache.thrift.protocol.TField("multiServiceCalls", org.apache.thrift.protocol.TType.I32, (short)13);
private static final org.apache.thrift.protocol.TField REGION_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("regionName", org.apache.thrift.protocol.TType.STRING, (short)14);
+ private static final org.apache.thrift.protocol.TField BLOCK_BYTES_SCANNED_FIELD_DESC = new org.apache.thrift.protocol.TField("blockBytesScanned", org.apache.thrift.protocol.TType.I64, (short)15);
private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new TOnlineLogRecordStandardSchemeFactory();
private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new TOnlineLogRecordTupleSchemeFactory();
@@ -47,6 +48,7 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
public int multiMutationsCount; // required
public int multiServiceCalls; // required
public @org.apache.thrift.annotation.Nullable java.lang.String regionName; // optional
+ public long blockBytesScanned; // optional
/** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
public enum _Fields implements org.apache.thrift.TFieldIdEnum {
@@ -63,7 +65,8 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
MULTI_GETS_COUNT((short)11, "multiGetsCount"),
MULTI_MUTATIONS_COUNT((short)12, "multiMutationsCount"),
MULTI_SERVICE_CALLS((short)13, "multiServiceCalls"),
- REGION_NAME((short)14, "regionName");
+ REGION_NAME((short)14, "regionName"),
+ BLOCK_BYTES_SCANNED((short)15, "blockBytesScanned");
private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
@@ -107,6 +110,8 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
return MULTI_SERVICE_CALLS;
case 14: // REGION_NAME
return REGION_NAME;
+ case 15: // BLOCK_BYTES_SCANNED
+ return BLOCK_BYTES_SCANNED;
default:
return null;
}
@@ -155,8 +160,9 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
private static final int __MULTIGETSCOUNT_ISSET_ID = 4;
private static final int __MULTIMUTATIONSCOUNT_ISSET_ID = 5;
private static final int __MULTISERVICECALLS_ISSET_ID = 6;
+ private static final int __BLOCKBYTESSCANNED_ISSET_ID = 7;
private byte __isset_bitfield = 0;
- private static final _Fields optionals[] = {_Fields.REGION_NAME};
+ private static final _Fields optionals[] = {_Fields.REGION_NAME,_Fields.BLOCK_BYTES_SCANNED};
public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
static {
java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
@@ -188,6 +194,8 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
tmpMap.put(_Fields.REGION_NAME, new org.apache.thrift.meta_data.FieldMetaData("regionName", org.apache.thrift.TFieldRequirementType.OPTIONAL,
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+ tmpMap.put(_Fields.BLOCK_BYTES_SCANNED, new org.apache.thrift.meta_data.FieldMetaData("blockBytesScanned", org.apache.thrift.TFieldRequirementType.OPTIONAL,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TOnlineLogRecord.class, metaDataMap);
}
@@ -266,6 +274,7 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
if (other.isSetRegionName()) {
this.regionName = other.regionName;
}
+ this.blockBytesScanned = other.blockBytesScanned;
}
public TOnlineLogRecord deepCopy() {
@@ -295,6 +304,8 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
setMultiServiceCallsIsSet(false);
this.multiServiceCalls = 0;
this.regionName = null;
+ setBlockBytesScannedIsSet(false);
+ this.blockBytesScanned = 0;
}
public long getStartTime() {
@@ -633,6 +644,29 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
}
}
+ public long getBlockBytesScanned() {
+ return this.blockBytesScanned;
+ }
+
+ public TOnlineLogRecord setBlockBytesScanned(long blockBytesScanned) {
+ this.blockBytesScanned = blockBytesScanned;
+ setBlockBytesScannedIsSet(true);
+ return this;
+ }
+
+ public void unsetBlockBytesScanned() {
+ __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __BLOCKBYTESSCANNED_ISSET_ID);
+ }
+
+ /** Returns true if field blockBytesScanned is set (has been assigned a value) and false otherwise */
+ public boolean isSetBlockBytesScanned() {
+ return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __BLOCKBYTESSCANNED_ISSET_ID);
+ }
+
+ public void setBlockBytesScannedIsSet(boolean value) {
+ __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __BLOCKBYTESSCANNED_ISSET_ID, value);
+ }
+
public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
switch (field) {
case START_TIME:
@@ -747,6 +781,14 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
}
break;
+ case BLOCK_BYTES_SCANNED:
+ if (value == null) {
+ unsetBlockBytesScanned();
+ } else {
+ setBlockBytesScanned((java.lang.Long)value);
+ }
+ break;
+
}
}
@@ -795,6 +837,9 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
case REGION_NAME:
return getRegionName();
+ case BLOCK_BYTES_SCANNED:
+ return getBlockBytesScanned();
+
}
throw new java.lang.IllegalStateException();
}
@@ -834,6 +879,8 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
return isSetMultiServiceCalls();
case REGION_NAME:
return isSetRegionName();
+ case BLOCK_BYTES_SCANNED:
+ return isSetBlockBytesScanned();
}
throw new java.lang.IllegalStateException();
}
@@ -977,6 +1024,15 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
return false;
}
+ boolean this_present_blockBytesScanned = true && this.isSetBlockBytesScanned();
+ boolean that_present_blockBytesScanned = true && that.isSetBlockBytesScanned();
+ if (this_present_blockBytesScanned || that_present_blockBytesScanned) {
+ if (!(this_present_blockBytesScanned && that_present_blockBytesScanned))
+ return false;
+ if (this.blockBytesScanned != that.blockBytesScanned)
+ return false;
+ }
+
return true;
}
@@ -1026,6 +1082,10 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
if (isSetRegionName())
hashCode = hashCode * 8191 + regionName.hashCode();
+ hashCode = hashCode * 8191 + ((isSetBlockBytesScanned()) ? 131071 : 524287);
+ if (isSetBlockBytesScanned())
+ hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(blockBytesScanned);
+
return hashCode;
}
@@ -1177,6 +1237,16 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
return lastComparison;
}
}
+ lastComparison = java.lang.Boolean.compare(isSetBlockBytesScanned(), other.isSetBlockBytesScanned());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetBlockBytesScanned()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.blockBytesScanned, other.blockBytesScanned);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
return 0;
}
@@ -1283,6 +1353,12 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
}
first = false;
}
+ if (isSetBlockBytesScanned()) {
+ if (!first) sb.append(", ");
+ sb.append("blockBytesScanned:");
+ sb.append(this.blockBytesScanned);
+ first = false;
+ }
sb.append(")");
return sb.toString();
}
@@ -1465,6 +1541,14 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
break;
+ case 15: // BLOCK_BYTES_SCANNED
+ if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
+ struct.blockBytesScanned = iprot.readI64();
+ struct.setBlockBytesScannedIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
default:
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
@@ -1559,6 +1643,11 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
oprot.writeFieldEnd();
}
}
+ if (struct.isSetBlockBytesScanned()) {
+ oprot.writeFieldBegin(BLOCK_BYTES_SCANNED_FIELD_DESC);
+ oprot.writeI64(struct.blockBytesScanned);
+ oprot.writeFieldEnd();
+ }
oprot.writeFieldStop();
oprot.writeStructEnd();
}
@@ -1593,10 +1682,16 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
if (struct.isSetRegionName()) {
optionals.set(0);
}
- oprot.writeBitSet(optionals, 1);
+ if (struct.isSetBlockBytesScanned()) {
+ optionals.set(1);
+ }
+ oprot.writeBitSet(optionals, 2);
if (struct.isSetRegionName()) {
oprot.writeString(struct.regionName);
}
+ if (struct.isSetBlockBytesScanned()) {
+ oprot.writeI64(struct.blockBytesScanned);
+ }
}
@Override
@@ -1628,11 +1723,15 @@ public class TOnlineLogRecord implements org.apache.thrift.TBase<TOnlineLogRecor
struct.setMultiMutationsCountIsSet(true);
struct.multiServiceCalls = iprot.readI32();
struct.setMultiServiceCallsIsSet(true);
- java.util.BitSet incoming = iprot.readBitSet(1);
+ java.util.BitSet incoming = iprot.readBitSet(2);
if (incoming.get(0)) {
struct.regionName = iprot.readString();
struct.setRegionNameIsSet(true);
}
+ if (incoming.get(1)) {
+ struct.blockBytesScanned = iprot.readI64();
+ struct.setBlockBytesScannedIsSet(true);
+ }
}
}
diff --git a/hbase-thrift/src/main/resources/org/apache/hadoop/hbase/thrift2/hbase.thrift b/hbase-thrift/src/main/resources/org/apache/hadoop/hbase/thrift2/hbase.thrift
index 11923165d9a..21e3ba2befb 100644
--- a/hbase-thrift/src/main/resources/org/apache/hadoop/hbase/thrift2/hbase.thrift
+++ b/hbase-thrift/src/main/resources/org/apache/hadoop/hbase/thrift2/hbase.thrift
@@ -481,7 +481,7 @@ struct TLogQueryFilter {
/**
* Thrift wrapper around
- * org.apache.hadoop.hbase.client.OnlineLogRecordrd
+ * org.apache.hadoop.hbase.client.OnlineLogRecord
*/
struct TOnlineLogRecord {
1: required i64 startTime
@@ -498,6 +498,7 @@ struct TOnlineLogRecord {
12: required i32 multiMutationsCount
13: required i32 multiServiceCalls
14: optional string regionName
+ 15: optional i64 blockBytesScanned
}
//