This is an automated email from the ASF dual-hosted git repository.

chungen0126 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new d0454e0cffd HDDS-16720. Count SCR GetBlock bytes in both bytesGetBlock 
and localBytesGetBlock (#11491)
d0454e0cffd is described below

commit d0454e0cffdd82d8a2059bcc550079ae19ffe17d
Author: Gargi Jaiswal <[email protected]>
AuthorDate: Tue Oct 13 23:37:18 2026 +0530

    HDDS-16720. Count SCR GetBlock bytes in both bytesGetBlock and 
localBytesGetBlock (#11491)
---
 .../ozone/container/keyvalue/KeyValueHandler.java  |   3 +-
 .../ozone/container/common/ContainerTestUtils.java |  10 +-
 .../container/keyvalue/TestKeyValueHandler.java    | 116 ++++++++++++++++++++-
 3 files changed, 124 insertions(+), 5 deletions(-)

diff --git 
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueHandler.java
 
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueHandler.java
index 06439a0c589..411866044a3 100644
--- 
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueHandler.java
+++ 
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueHandler.java
@@ -865,10 +865,9 @@ ContainerCommandResponseProto handleGetBlock(
         }
       }
       final long numBytes = responseData.getSerializedSize();
+      metrics.incContainerBytesStats(Type.GetBlock, numBytes);
       if (shortCircuitGranted) {
         metrics.incContainerLocalBytesStats(Type.GetBlock, numBytes);
-      } else {
-        metrics.incContainerBytesStats(Type.GetBlock, numBytes);
       }
     } catch (StorageContainerException ex) {
       return ContainerUtils.logAndReturnError(LOG, ex, request);
diff --git 
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/ContainerTestUtils.java
 
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/ContainerTestUtils.java
index 7172aa3fe50..9971abb0f08 100644
--- 
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/ContainerTestUtils.java
+++ 
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/ContainerTestUtils.java
@@ -28,6 +28,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.net.InetSocketAddress;
+import java.time.Clock;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -222,7 +223,14 @@ public static KeyValueHandler 
getKeyValueHandler(ConfigurationSource config,
   public static KeyValueHandler getKeyValueHandler(ConfigurationSource config,
       String datanodeId, ContainerSet contSet, VolumeSet volSet, 
ContainerMetrics metrics,
       ContainerChecksumTreeManager checksumTreeManager) {
-    return new KeyValueHandler(config, datanodeId, contSet, volSet, metrics, c 
-> { }, checksumTreeManager);
+    return getKeyValueHandler(config, datanodeId, contSet, volSet, metrics, 
checksumTreeManager, null);
+  }
+
+  public static KeyValueHandler getKeyValueHandler(ConfigurationSource config,
+      String datanodeId, ContainerSet contSet, VolumeSet volSet, 
ContainerMetrics metrics,
+      ContainerChecksumTreeManager checksumTreeManager, OzoneContainer 
ozoneContainer) {
+    return new KeyValueHandler(config, datanodeId, contSet, volSet, null, 
metrics,
+        c -> { }, Clock.systemUTC(), checksumTreeManager, ozoneContainer);
   }
 
   /**
diff --git 
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueHandler.java
 
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueHandler.java
index 721681619c9..c8fb512386d 100644
--- 
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueHandler.java
+++ 
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueHandler.java
@@ -58,6 +58,7 @@
 import com.google.common.collect.Sets;
 import java.io.File;
 import java.io.IOException;
+import java.io.RandomAccessFile;
 import java.lang.reflect.Field;
 import java.nio.ByteBuffer;
 import java.nio.file.Files;
@@ -80,6 +81,7 @@
 import org.apache.hadoop.hdds.client.BlockID;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.protocol.DatanodeDetails;
+import org.apache.hadoop.hdds.protocol.DatanodeID;
 import org.apache.hadoop.hdds.protocol.MockDatanodeDetails;
 import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos;
 import 
org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerCommandRequestProto;
@@ -114,6 +116,7 @@
 import org.apache.hadoop.ozone.container.common.report.IncrementalReportSender;
 import 
org.apache.hadoop.ozone.container.common.statemachine.DatanodeConfiguration;
 import org.apache.hadoop.ozone.container.common.statemachine.StateContext;
+import 
org.apache.hadoop.ozone.container.common.transport.server.XceiverServerSpi;
 import 
org.apache.hadoop.ozone.container.common.transport.server.ratis.DispatcherContext;
 import org.apache.hadoop.ozone.container.common.utils.StorageVolumeUtil;
 import org.apache.hadoop.ozone.container.common.volume.HddsVolume;
@@ -125,6 +128,7 @@
 import org.apache.hadoop.ozone.container.ozoneimpl.ContainerController;
 import 
org.apache.hadoop.ozone.container.ozoneimpl.ContainerScannerConfiguration;
 import org.apache.hadoop.ozone.container.ozoneimpl.OnDemandContainerScanner;
+import org.apache.hadoop.ozone.container.ozoneimpl.OzoneContainer;
 import org.apache.hadoop.util.Time;
 import org.apache.ozone.test.GenericTestUtils;
 import org.apache.ozone.test.GenericTestUtils.LogCapturer;
@@ -164,6 +168,7 @@ public class TestKeyValueHandler {
   // Deliberately not a multiple of BYTES_PER_CHECKSUM, so an offset past the 
end of the block can still have its
   // checksum aligned floor inside the block.
   private static final int BLOCK_SIZE = 1000;
+  private static final int GET_BLOCK_TEST_CHUNK_LEN = 1024;
 
   private HddsDispatcher dispatcher;
   private KeyValueHandler handler;
@@ -1097,11 +1102,18 @@ private static class HandlerWithVolumeSet {
     private final KeyValueHandler handler;
     private final MutableVolumeSet volumeSet;
     private final ContainerSet containerSet;
+    private final ContainerMetrics containerMetrics;
 
     HandlerWithVolumeSet(KeyValueHandler handler, MutableVolumeSet volumeSet, 
ContainerSet containerSet) {
+      this(handler, volumeSet, containerSet, null);
+    }
+
+    HandlerWithVolumeSet(KeyValueHandler handler, MutableVolumeSet volumeSet,
+        ContainerSet containerSet, ContainerMetrics containerMetrics) {
       this.handler = handler;
       this.volumeSet = volumeSet;
       this.containerSet = containerSet;
+      this.containerMetrics = containerMetrics;
     }
 
     KeyValueHandler getHandler() {
@@ -1115,12 +1127,22 @@ MutableVolumeSet getVolumeSet() {
     ContainerSet getContainerSet() {
       return containerSet;
     }
+
+    ContainerMetrics getContainerMetrics() {
+      return containerMetrics;
+    }
   }
 
   private HandlerWithVolumeSet createKeyValueHandlerWithVolumeSet(Path path) 
throws IOException {
+    return createKeyValueHandlerWithVolumeSet(path, null);
+  }
+
+  private HandlerWithVolumeSet createKeyValueHandlerWithVolumeSet(Path path, 
OzoneContainer ozoneContainer)
+      throws IOException {
     ContainerMetrics.remove();
     final ContainerSet containerSet = newContainerSet();
     final MutableVolumeSet volumeSet = mock(MutableVolumeSet.class);
+    final ContainerMetrics containerMetrics = ContainerMetrics.create(conf);
 
     HddsVolume hddsVolume = new HddsVolume.Builder(path.toString()).conf(conf)
         .clusterID(CLUSTER_ID).datanodeUuid(DATANODE_UUID)
@@ -1132,7 +1154,8 @@ private HandlerWithVolumeSet 
createKeyValueHandlerWithVolumeSet(Path path) throw
     
when(volumeSet.getVolumesList()).thenReturn(Collections.singletonList(hddsVolume));
 
     final KeyValueHandler kvHandler = 
ContainerTestUtils.getKeyValueHandler(conf,
-        DATANODE_UUID, containerSet, volumeSet);
+        DATANODE_UUID, containerSet, volumeSet, containerMetrics,
+        new ContainerChecksumTreeManager(conf), ozoneContainer);
     kvHandler.setClusterID(CLUSTER_ID);
     hddsVolume.getVolumeInfoStats().unregister();
     hddsVolume.getVolumeIOStats().unregister();
@@ -1143,7 +1166,96 @@ private HandlerWithVolumeSet 
createKeyValueHandlerWithVolumeSet(Path path) throw
         conf.getObject(ContainerScannerConfiguration.class), controller);
     containerSet.registerOnDemandScanner(onDemandScanner);
 
-    return new HandlerWithVolumeSet(kvHandler, volumeSet, containerSet);
+    return new HandlerWithVolumeSet(kvHandler, volumeSet, containerSet, 
containerMetrics);
+  }
+
+  private HddsDispatcher createGetBlockDispatcher(HandlerWithVolumeSet 
handlerWithVolume) throws IOException {
+    DatanodeDetails datanodeDetails =
+        
MockDatanodeDetails.createDatanodeDetails(DatanodeID.fromUuidString(DATANODE_UUID));
+    StateContext context = ContainerTestUtils.getMockContext(datanodeDetails, 
conf);
+    HashMap<ContainerType, Handler> handlers = new HashMap<>();
+    handlers.put(ContainerType.KeyValueContainer, 
handlerWithVolume.getHandler());
+    return new HddsDispatcher(conf, handlerWithVolume.getContainerSet(), 
handlerWithVolume.getVolumeSet(), handlers,
+        context, handlerWithVolume.getContainerMetrics(), null);
+  }
+
+  private void writeTestBlockForGetBlock(
+      KeyValueHandler kvHandler, KeyValueContainer container, BlockID blockID) 
throws IOException {
+    BlockData blockData = new BlockData(blockID);
+    ChunkInfo chunkInfo = new ChunkInfo("chunk1", 0, GET_BLOCK_TEST_CHUNK_LEN);
+    blockData.addChunk(chunkInfo.getProtoBufMessage());
+    kvHandler.getBlockManager().putBlock(container, blockData);
+    ChunkBuffer data = 
ChunkBuffer.wrap(ByteBuffer.allocate(GET_BLOCK_TEST_CHUNK_LEN));
+    kvHandler.getChunkManager().writeChunk(container, blockID, chunkInfo, data,
+        DispatcherContext.getHandleWriteChunk());
+  }
+
+  private static ContainerCommandRequestProto newGetBlockRequest(
+      long containerID, BlockID blockID, boolean requestShortCircuitAccess) {
+    ContainerProtos.GetBlockRequestProto.Builder getBlock = 
ContainerProtos.GetBlockRequestProto.newBuilder()
+        .setBlockID(blockID.getDatanodeBlockIDProtobuf());
+    if (requestShortCircuitAccess) {
+      getBlock.setRequestShortCircuitAccess(true);
+    }
+    return ContainerCommandRequestProto.newBuilder()
+        .setCmdType(ContainerProtos.Type.GetBlock)
+        .setContainerID(containerID)
+        .setDatanodeUuid(DATANODE_UUID)
+        .setGetBlock(getBlock)
+        .build();
+  }
+
+  private static OzoneContainer mockOzoneContainerWithSCDomainSocket() {
+    OzoneContainer ozoneContainer = mock(OzoneContainer.class);
+    XceiverServerSpi domainSocketServer = mock(XceiverServerSpi.class);
+    
when(ozoneContainer.getReadDomainSocketChannel()).thenReturn(domainSocketServer);
+    when(domainSocketServer.isStarted()).thenReturn(true);
+    return ozoneContainer;
+  }
+
+  @Test
+  public void testGetBlockMetrics() throws Exception {
+    Path testDir = Files.createTempDirectory("testGetBlockMetrics");
+    try {
+      conf.set(OZONE_SCM_CONTAINER_LAYOUT_KEY, 
ContainerLayoutVersion.FILE_PER_BLOCK.name());
+      HandlerWithVolumeSet handlerWithVolume = 
createKeyValueHandlerWithVolumeSet(testDir,
+          mockOzoneContainerWithSCDomainSocket());
+      KeyValueHandler kvHandler = handlerWithVolume.getHandler();
+      HddsDispatcher getBlockDispatcher = 
createGetBlockDispatcher(handlerWithVolume);
+
+      long containerID = ContainerTestHelper.getTestContainerID();
+      KeyValueContainer container = createOpenContainer(containerID, 
handlerWithVolume.getVolumeSet(),
+          handlerWithVolume.getContainerSet());
+      BlockID blockID = ContainerTestHelper.getTestBlockID(containerID);
+      writeTestBlockForGetBlock(kvHandler, container, blockID);
+
+      ContainerCommandResponseProto response = getBlockDispatcher.dispatch(
+          newGetBlockRequest(containerID, blockID, false), null);
+      assertEquals(ContainerProtos.Result.SUCCESS, response.getResult());
+      long blockMetadataBytes = 
response.getGetBlock().getBlockData().getSerializedSize();
+
+      MetricsRecordBuilder containerMetrics = getMetrics(
+          ContainerMetrics.STORAGE_CONTAINER_METRICS);
+      assertCounter("numGetBlock", 1L, containerMetrics);
+      assertCounter("bytesGetBlock", blockMetadataBytes, containerMetrics);
+      assertCounter("localBytesGetBlock", 0L, containerMetrics);
+
+      ContainerCommandRequestProto shortCircuitRequest = 
newGetBlockRequest(containerID, blockID, true);
+      response = getBlockDispatcher.dispatch(shortCircuitRequest, null);
+      assertEquals(ContainerProtos.Result.SUCCESS, response.getResult());
+      assertTrue(response.getGetBlock().getShortCircuitAccessGranted());
+      try (RandomAccessFile blockFile = 
kvHandler.getBlockFile(shortCircuitRequest)) {
+        assertNotNull(blockFile);
+      }
+
+      containerMetrics = 
getMetrics(ContainerMetrics.STORAGE_CONTAINER_METRICS);
+      assertCounter("numGetBlock", 2L, containerMetrics);
+      assertCounter("bytesGetBlock", 2 * blockMetadataBytes, containerMetrics);
+      assertCounter("localBytesGetBlock", blockMetadataBytes, 
containerMetrics);
+    } finally {
+      FileUtils.deleteDirectory(testDir.toFile());
+      ContainerMetrics.remove();
+    }
   }
 
   @Test


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to