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

ChenSammi 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 d1dbbe46574 HDDS-15149. Limit Connections Created by DataNode GRPC 
Server (#10184)
d1dbbe46574 is described below

commit d1dbbe465746a6e0c2d7e8570a6983d12af1f0fd
Author: Bolin Lin <[email protected]>
AuthorDate: Mon May 11 01:46:02 2026 -0400

    HDDS-15149. Limit Connections Created by DataNode GRPC Server (#10184)
---
 .../common/statemachine/DatanodeConfiguration.java | 25 +++++++++++++++++
 .../common/transport/server/XceiverServerGrpc.java |  8 ++++--
 .../statemachine/TestDatanodeConfiguration.java    | 32 ++++++++++++++++++++++
 3 files changed, 63 insertions(+), 2 deletions(-)

diff --git 
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/DatanodeConfiguration.java
 
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/DatanodeConfiguration.java
index a477e3876a1..e47fdbb0c6b 100644
--- 
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/DatanodeConfiguration.java
+++ 
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/DatanodeConfiguration.java
@@ -139,6 +139,9 @@ public class DatanodeConfiguration extends 
ReconfigurableConfig {
   static final int CONTAINER_CLOSE_THREADS_DEFAULT = 3;
   static final int BLOCK_DELETE_THREADS_DEFAULT = 5;
 
+  public static final String GRPC_SO_BACKLOG_KEY = 
"hdds.datanode.grpc.so.backlog";
+  public static final int GRPC_SO_BACKLOG_DEFAULT = 4096;
+
   public static final String BLOCK_DELETE_COMMAND_WORKER_INTERVAL =
       "hdds.datanode.block.delete.command.worker.interval";
   public static final Duration BLOCK_DELETE_COMMAND_WORKER_INTERVAL_DEFAULT = 
Duration.ofSeconds(2);
@@ -154,6 +157,20 @@ public class DatanodeConfiguration extends 
ReconfigurableConfig {
   )
   private int numReadThreadPerVolume = 10;
 
+  /**
+   * SO_BACKLOG value for the gRPC server socket.
+   */
+  @Config(key = "hdds.datanode.grpc.so.backlog",
+      type = ConfigType.INT,
+      defaultValue = "4096",
+      tags = {DATANODE},
+      description = "The SO_BACKLOG value for the Datanode gRPC server socket. 
" +
+          "This limits the number of pending connections in the kernel's " +
+          "accept queue. When this limit is reached, the kernel will reject " +
+          "new connection attempts with SYN drops."
+  )
+  private int grpcSoBacklog = GRPC_SO_BACKLOG_DEFAULT;
+
   /**
    * The maximum number of threads used to delete containers on a datanode
    * simultaneously.
@@ -1224,4 +1241,12 @@ static long getDefaultFreeSpace() {
     final StorageSize measure = 
StorageSize.parse(HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_DEFAULT);
     return Math.round(measure.getUnit().toBytes(measure.getValue()));
   }
+
+  public int getGrpcSoBacklog() {
+    return grpcSoBacklog;
+  }
+
+  public void setGrpcSoBacklog(int grpcSoBacklog) {
+    this.grpcSoBacklog = grpcSoBacklog;
+  }
 }
diff --git 
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/transport/server/XceiverServerGrpc.java
 
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/transport/server/XceiverServerGrpc.java
index 31dd1cb19e4..58be7965a74 100644
--- 
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/transport/server/XceiverServerGrpc.java
+++ 
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/transport/server/XceiverServerGrpc.java
@@ -50,6 +50,7 @@
 import org.apache.ratis.thirdparty.io.grpc.ServerInterceptors;
 import org.apache.ratis.thirdparty.io.grpc.netty.GrpcSslContexts;
 import org.apache.ratis.thirdparty.io.grpc.netty.NettyServerBuilder;
+import org.apache.ratis.thirdparty.io.netty.channel.ChannelOption;
 import org.apache.ratis.thirdparty.io.netty.channel.EventLoopGroup;
 import org.apache.ratis.thirdparty.io.netty.channel.ServerChannel;
 import org.apache.ratis.thirdparty.io.netty.channel.epoll.Epoll;
@@ -98,11 +99,13 @@ public XceiverServerGrpc(DatanodeDetails datanodeDetails,
       this.port = 0;
     }
 
-    final int threadCountPerDisk =
-        
conf.getObject(DatanodeConfiguration.class).getNumReadThreadPerVolume();
+    DatanodeConfiguration dnConf = conf.getObject(DatanodeConfiguration.class);
+    final int threadCountPerDisk = dnConf.getNumReadThreadPerVolume();
     final int numberOfDisks =
         HddsServerUtil.getDatanodeStorageDirs(conf).size();
     final int poolSize = threadCountPerDisk * numberOfDisks;
+    final int soBacklog = dnConf.getGrpcSoBacklog();
+    LOG.info("Datanode gRPC server SO_BACKLOG: {}", soBacklog);
 
     readExecutors = new ThreadPoolExecutor(poolSize, poolSize,
         60, TimeUnit.SECONDS,
@@ -134,6 +137,7 @@ public XceiverServerGrpc(DatanodeDetails datanodeDetails,
         .bossEventLoopGroup(eventLoopGroup)
         .workerEventLoopGroup(eventLoopGroup)
         .channelType(channelType)
+        .withOption(ChannelOption.SO_BACKLOG, soBacklog)
         .executor(readExecutors)
         .addService(ServerInterceptors.intercept(
             xceiverService.bindServiceWithZeroCopy(),
diff --git 
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/statemachine/TestDatanodeConfiguration.java
 
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/statemachine/TestDatanodeConfiguration.java
index 5012526782a..b12c6575960 100644
--- 
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/statemachine/TestDatanodeConfiguration.java
+++ 
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/statemachine/TestDatanodeConfiguration.java
@@ -29,6 +29,8 @@
 import static 
org.apache.hadoop.ozone.container.common.statemachine.DatanodeConfiguration.FAILED_DB_VOLUMES_TOLERATED_KEY;
 import static 
org.apache.hadoop.ozone.container.common.statemachine.DatanodeConfiguration.FAILED_METADATA_VOLUMES_TOLERATED_KEY;
 import static 
org.apache.hadoop.ozone.container.common.statemachine.DatanodeConfiguration.FAILED_VOLUMES_TOLERATED_DEFAULT;
+import static 
org.apache.hadoop.ozone.container.common.statemachine.DatanodeConfiguration.GRPC_SO_BACKLOG_DEFAULT;
+import static 
org.apache.hadoop.ozone.container.common.statemachine.DatanodeConfiguration.GRPC_SO_BACKLOG_KEY;
 import static 
org.apache.hadoop.ozone.container.common.statemachine.DatanodeConfiguration.HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_PERCENT_DEFAULT;
 import static 
org.apache.hadoop.ozone.container.common.statemachine.DatanodeConfiguration.PERIODIC_DISK_CHECK_INTERVAL_MINUTES_DEFAULT;
 import static 
org.apache.hadoop.ozone.container.common.statemachine.DatanodeConfiguration.PERIODIC_DISK_CHECK_INTERVAL_MINUTES_KEY;
@@ -283,4 +285,34 @@ static void assertWaitTimeMin(TimeDuration expected,
     assertEquals(expected, t,
         RaftServerConfigKeys.Log.Appender.WAIT_TIME_MIN_KEY);
   }
+
+  @Test
+  void testGrpcSoBacklogDefault() {
+    OzoneConfiguration conf = new OzoneConfiguration();
+
+    DatanodeConfiguration subject = 
conf.getObject(DatanodeConfiguration.class);
+
+    assertEquals(GRPC_SO_BACKLOG_DEFAULT, subject.getGrpcSoBacklog());
+  }
+
+  @Test
+  void testGrpcSoBacklogCustomValue() {
+    OzoneConfiguration conf = new OzoneConfiguration();
+    int customSoBacklog = 256;
+    conf.setInt(GRPC_SO_BACKLOG_KEY, customSoBacklog);
+
+    DatanodeConfiguration subject = 
conf.getObject(DatanodeConfiguration.class);
+
+    assertEquals(customSoBacklog, subject.getGrpcSoBacklog());
+  }
+
+  @Test
+  void testGrpcSoBacklogSetter() {
+    OzoneConfiguration conf = new OzoneConfiguration();
+    DatanodeConfiguration subject = 
conf.getObject(DatanodeConfiguration.class);
+
+    subject.setGrpcSoBacklog(512);
+
+    assertEquals(512, subject.getGrpcSoBacklog());
+  }
 }


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

Reply via email to