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

szetszwo 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 f7a0ab2ef4 HDDS-9232. Write performance degradation. (#5338)
f7a0ab2ef4 is described below

commit f7a0ab2ef432053a491f6029860a80ef08e62a04
Author: Tsz-Wo Nicholas Sze <[email protected]>
AuthorDate: Fri Oct 6 10:51:26 2023 -0700

    HDDS-9232. Write performance degradation. (#5338)
---
 .../org/apache/hadoop/hdds/scm/ScmConfigKeys.java  |  1 +
 .../hadoop/hdds/scm/ScmRatisServerConfig.java      | 52 +++++++++++++++
 .../transport/server/ratis/XceiverServerRatis.java |  2 +-
 .../ozone/container/common/ContainerTestUtils.java | 74 +++++++++++++++++++++-
 .../statemachine/TestDatanodeConfiguration.java    | 35 ++++++++++
 .../hdds/conf/DatanodeRatisServerConfig.java       | 17 +++++
 .../org/apache/hadoop/hdds/scm/ha/RatisUtil.java   |  5 ++
 .../hadoop/hdds/scm/ha/TestSCMHAConfiguration.java | 18 ++++++
 .../hadoop/ozone/TestOzoneConfigurationFields.java |  1 +
 .../org/apache/hadoop/ozone/om/TestOmConf.java     | 57 +++++++++++++++++
 .../ozone/om/TestOzoneManagerHAKeyDeletion.java    | 15 +++++
 .../ozone/om/ratis/OzoneManagerRatisServer.java    | 17 ++---
 .../om/ratis/OzoneManagerRatisServerConfig.java    | 17 +++++
 13 files changed, 296 insertions(+), 15 deletions(-)

diff --git 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/ScmConfigKeys.java
 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/ScmConfigKeys.java
index 315905f6d5..2d8f8c06c8 100644
--- 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/ScmConfigKeys.java
+++ 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/ScmConfigKeys.java
@@ -30,6 +30,7 @@ import java.util.concurrent.TimeUnit;
 @InterfaceAudience.Public
 @InterfaceStability.Unstable
 public final class ScmConfigKeys {
+  public static final String OZONE_SCM_HA_PREFIX = "ozone.scm.ha";
 
   // Location of SCM DB files. For now we just support a single
   // metadata dir but in future we may support multiple for redundancy or
diff --git 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/ScmRatisServerConfig.java
 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/ScmRatisServerConfig.java
new file mode 100644
index 0000000000..a645233b93
--- /dev/null
+++ 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/ScmRatisServerConfig.java
@@ -0,0 +1,52 @@
+/*
+ * 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.hdds.scm;
+
+import org.apache.hadoop.hdds.conf.Config;
+import org.apache.hadoop.hdds.conf.ConfigGroup;
+import org.apache.hadoop.hdds.conf.ConfigType;
+import org.apache.ratis.server.RaftServerConfigKeys;
+
+import static org.apache.hadoop.hdds.conf.ConfigTag.OZONE;
+import static org.apache.hadoop.hdds.conf.ConfigTag.PERFORMANCE;
+import static org.apache.hadoop.hdds.conf.ConfigTag.RATIS;
+import static org.apache.hadoop.hdds.conf.ConfigTag.SCM;
+
+/**
+ * SCM Ratis Server config.
+ */
+@ConfigGroup(prefix = ScmConfigKeys.OZONE_SCM_HA_PREFIX
+    + "." + RaftServerConfigKeys.PREFIX)
+public class ScmRatisServerConfig {
+  /** @see RaftServerConfigKeys.Log.Appender#WAIT_TIME_MIN_KEY */
+  @Config(key = "log.appender.wait-time.min",
+      defaultValue = "0ms",
+      type = ConfigType.TIME,
+      tags = {OZONE, SCM, RATIS, PERFORMANCE},
+      description = "Minimum wait time between two appendEntries calls."
+  )
+  private long logAppenderWaitTimeMin;
+
+  public long getLogAppenderWaitTimeMin() {
+    return logAppenderWaitTimeMin;
+  }
+
+  public void setLogAppenderWaitTimeMin(long logAppenderWaitTimeMin) {
+    this.logAppenderWaitTimeMin = logAppenderWaitTimeMin;
+  }
+}
diff --git 
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/transport/server/ratis/XceiverServerRatis.java
 
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/transport/server/ratis/XceiverServerRatis.java
index e690ab3bc5..932526aa88 100644
--- 
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/transport/server/ratis/XceiverServerRatis.java
+++ 
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/transport/server/ratis/XceiverServerRatis.java
@@ -245,7 +245,7 @@ public final class XceiverServerRatis implements 
XceiverServerSpi {
   }
 
   @SuppressWarnings("checkstyle:methodlength")
-  private RaftProperties newRaftProperties() {
+  public RaftProperties newRaftProperties() {
     final RaftProperties properties = new RaftProperties();
 
     // Set rpc type
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 5b2a1c0831..263ab54599 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
@@ -22,7 +22,10 @@ import org.apache.hadoop.conf.StorageUnit;
 import org.apache.hadoop.hdds.conf.ConfigurationSource;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.protocol.DatanodeDetails;
-import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos;
+import 
org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerCommandRequestProto;
+import 
org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerCommandResponseProto;
+import 
org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerDataProto;
+import 
org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerType;
 import org.apache.hadoop.hdds.utils.LegacyHadoopConfigurationSource;
 import org.apache.hadoop.hdfs.util.Canceler;
 import org.apache.hadoop.hdfs.util.DataTransferThrottler;
@@ -30,16 +33,22 @@ import org.apache.hadoop.io.retry.RetryPolicies;
 import org.apache.hadoop.ipc.ProtobufRpcEngine;
 import org.apache.hadoop.ipc.RPC;
 import org.apache.hadoop.net.NetUtils;
+import org.apache.hadoop.ozone.OzoneConfigKeys;
 import org.apache.hadoop.ozone.container.ContainerTestHelper;
 import org.apache.hadoop.ozone.container.common.impl.ContainerData;
 import org.apache.hadoop.ozone.container.common.impl.ContainerLayoutVersion;
+import org.apache.hadoop.ozone.container.common.impl.ContainerSet;
 import org.apache.hadoop.ozone.container.common.interfaces.Container;
 import 
org.apache.hadoop.ozone.container.common.interfaces.Container.ScanResult;
+import org.apache.hadoop.ozone.container.common.interfaces.ContainerDispatcher;
+import org.apache.hadoop.ozone.container.common.interfaces.Handler;
 import 
org.apache.hadoop.ozone.container.common.interfaces.VolumeChoosingPolicy;
 import 
org.apache.hadoop.ozone.container.common.statemachine.DatanodeConfiguration;
 import 
org.apache.hadoop.ozone.container.common.statemachine.DatanodeStateMachine;
 import 
org.apache.hadoop.ozone.container.common.statemachine.EndpointStateMachine;
 import org.apache.hadoop.ozone.container.common.statemachine.StateContext;
+import 
org.apache.hadoop.ozone.container.common.transport.server.ratis.DispatcherContext;
+import 
org.apache.hadoop.ozone.container.common.transport.server.ratis.XceiverServerRatis;
 import org.apache.hadoop.ozone.container.common.utils.StorageVolumeUtil;
 import org.apache.hadoop.ozone.container.common.volume.HddsVolume;
 import org.apache.hadoop.ozone.container.common.volume.MutableVolumeSet;
@@ -47,6 +56,7 @@ import 
org.apache.hadoop.ozone.container.common.volume.RoundRobinVolumeChoosingP
 import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainer;
 import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData;
 import 
org.apache.hadoop.ozone.container.keyvalue.helpers.KeyValueContainerUtil;
+import org.apache.hadoop.ozone.container.ozoneimpl.ContainerController;
 import org.apache.hadoop.ozone.container.ozoneimpl.OzoneContainer;
 import 
org.apache.hadoop.ozone.protocolPB.StorageContainerDatanodeProtocolClientSideTranslatorPB;
 import org.apache.hadoop.ozone.protocolPB.StorageContainerDatanodeProtocolPB;
@@ -56,6 +66,8 @@ import org.mockito.Mockito;
 import java.io.File;
 import java.io.IOException;
 import java.net.InetSocketAddress;
+import java.util.Collections;
+import java.util.Map;
 import java.util.Random;
 import java.util.UUID;
 import java.util.concurrent.atomic.AtomicLong;
@@ -135,7 +147,7 @@ public final class ContainerTestUtils {
 
   public static KeyValueContainer getContainer(long containerId,
       ContainerLayoutVersion layout,
-      ContainerProtos.ContainerDataProto.State state) {
+      ContainerDataProto.State state) {
     KeyValueContainerData kvData =
         new KeyValueContainerData(containerId,
             layout,
@@ -250,4 +262,62 @@ public final class ContainerTestUtils {
 
     return container;
   }
+
+  private static class NoopContainerDispatcher implements ContainerDispatcher {
+    @Override
+    public ContainerCommandResponseProto dispatch(
+        ContainerCommandRequestProto msg, DispatcherContext context) {
+      return ContainerTestHelper.getCreateContainerResponse(msg);
+    }
+
+    @Override
+    public void validateContainerCommand(ContainerCommandRequestProto msg) {
+    }
+
+    @Override
+    public void init() {
+    }
+
+    @Override
+    public void buildMissingContainerSetAndValidate(
+        Map<Long, Long> container2BCSIDMap) {
+    }
+
+    @Override
+    public void shutdown() {
+    }
+
+    @Override
+    public Handler getHandler(ContainerType containerType) {
+      return null;
+    }
+
+    @Override
+    public void setClusterId(String clusterId) {
+    }
+  }
+
+  private static final ContainerDispatcher NOOP_CONTAINER_DISPATCHER
+      = new NoopContainerDispatcher();
+
+  public static ContainerDispatcher getNoopContainerDispatcher() {
+    return NOOP_CONTAINER_DISPATCHER;
+  }
+
+  private static final ContainerController EMPTY_CONTAINER_CONTROLLER
+      = new ContainerController(new ContainerSet(1000), 
Collections.emptyMap());
+
+  public static ContainerController getEmptyContainerController() {
+    return EMPTY_CONTAINER_CONTROLLER;
+  }
+
+  public static XceiverServerRatis newXceiverServerRatis(
+      DatanodeDetails dn, OzoneConfiguration conf) throws IOException {
+    conf.setInt(OzoneConfigKeys.DFS_CONTAINER_RATIS_IPC_PORT,
+        dn.getPort(DatanodeDetails.Port.Name.RATIS).getValue());
+
+    return XceiverServerRatis.newXceiverServerRatis(dn, conf,
+        getNoopContainerDispatcher(), getEmptyContainerController(),
+        null, null);
+  }
 }
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 478f3b4061..28e5fdd764 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
@@ -17,7 +17,16 @@
  */
 package org.apache.hadoop.ozone.container.common.statemachine;
 
+import org.apache.hadoop.hdds.conf.DatanodeRatisServerConfig;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.hdds.protocol.DatanodeDetails;
+import org.apache.hadoop.hdds.scm.pipeline.MockPipeline;
+import org.apache.hadoop.ozone.OzoneConfigKeys;
+import org.apache.hadoop.ozone.container.common.ContainerTestUtils;
+import org.apache.ratis.conf.RaftProperties;
+import org.apache.ratis.server.RaftServerConfigKeys;
+import org.apache.ratis.util.TimeDuration;
+import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
 import java.util.concurrent.TimeUnit;
@@ -152,4 +161,30 @@ public class TestDatanodeConfiguration {
         subject.getDiskCheckTimeout().toMillis());
   }
 
+  @Test
+  public void testConf() throws Exception {
+    final OzoneConfiguration conf = new OzoneConfiguration();
+    final String dir = "dummy/dir";
+    conf.set(OzoneConfigKeys.DFS_CONTAINER_RATIS_DATANODE_STORAGE_DIR, dir);
+
+    final DatanodeRatisServerConfig ratisConf = conf.getObject(
+        DatanodeRatisServerConfig.class);
+    Assertions.assertEquals(1, ratisConf.getLogAppenderWaitTimeMin(),
+        "getLogAppenderWaitTimeMin");
+
+    assertWaitTimeMin(TimeDuration.ONE_MILLISECOND, conf);
+    ratisConf.setLogAppenderWaitTimeMin(0);
+    conf.setFromObject(ratisConf);
+    assertWaitTimeMin(TimeDuration.ZERO, conf);
+  }
+
+  static void assertWaitTimeMin(TimeDuration expected,
+      OzoneConfiguration conf) throws Exception {
+    final DatanodeDetails dn = MockPipeline.createPipeline(1).getFirstNode();
+    final RaftProperties p = ContainerTestUtils.newXceiverServerRatis(dn, conf)
+        .newRaftProperties();
+    final TimeDuration t = RaftServerConfigKeys.Log.Appender.waitTimeMin(p);
+    Assertions.assertEquals(expected, t,
+        RaftServerConfigKeys.Log.Appender.WAIT_TIME_MIN_KEY);
+  }
 }
diff --git 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/conf/DatanodeRatisServerConfig.java
 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/conf/DatanodeRatisServerConfig.java
index 11373e3301..3eb0faf302 100644
--- 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/conf/DatanodeRatisServerConfig.java
+++ 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/conf/DatanodeRatisServerConfig.java
@@ -190,4 +190,21 @@ public class DatanodeRatisServerConfig {
   public void setPreVote(boolean preVote) {
     this.preVoteEnabled = preVote;
   }
+
+  /** @see RaftServerConfigKeys.Log.Appender#WAIT_TIME_MIN_KEY */
+  @Config(key = "log.appender.wait-time.min",
+      defaultValue = "1ms",
+      type = ConfigType.TIME,
+      tags = {OZONE, DATANODE, RATIS, PERFORMANCE},
+      description = "Minimum wait time between two appendEntries calls."
+  )
+  private long logAppenderWaitTimeMin;
+
+  public long getLogAppenderWaitTimeMin() {
+    return logAppenderWaitTimeMin;
+  }
+
+  public void setLogAppenderWaitTimeMin(long logAppenderWaitTimeMin) {
+    this.logAppenderWaitTimeMin = logAppenderWaitTimeMin;
+  }
 }
diff --git 
a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/RatisUtil.java
 
b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/RatisUtil.java
index c75593eadc..4ae82d89bb 100644
--- 
a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/RatisUtil.java
+++ 
b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/RatisUtil.java
@@ -38,6 +38,7 @@ import java.io.IOException;
 import java.util.Collections;
 import java.util.concurrent.TimeUnit;
 
+import static org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_HA_PREFIX;
 import static 
org.apache.hadoop.hdds.security.exception.SCMSecurityException.ErrorCode.GET_CERTIFICATE_FAILED;
 import static 
org.apache.hadoop.hdds.security.exception.SCMSecurityException.ErrorCode.GET_DN_CERTIFICATE_FAILED;
 import static 
org.apache.hadoop.hdds.security.exception.SCMSecurityException.ErrorCode.GET_OM_CERTIFICATE_FAILED;
@@ -73,6 +74,10 @@ public final class RatisUtil {
     setRaftRetryCacheProperties(properties, conf);
     setRaftSnapshotProperties(properties, conf);
     setRaftLeadElectionProperties(properties, conf);
+
+    final String prefix = RaftServerConfigKeys.PREFIX + ".";
+    conf.getPropsMatchPrefixAndTrimPrefix(OZONE_SCM_HA_PREFIX + "." + prefix)
+        .forEach((k, v) -> properties.set(prefix + k, v));
     return properties;
   }
 
diff --git 
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/ha/TestSCMHAConfiguration.java
 
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/ha/TestSCMHAConfiguration.java
index 31a83fbd3c..3dd61c8a06 100644
--- 
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/ha/TestSCMHAConfiguration.java
+++ 
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/ha/TestSCMHAConfiguration.java
@@ -17,16 +17,22 @@
  */
 package org.apache.hadoop.hdds.scm.ha;
 
+import org.apache.hadoop.hdds.HddsConfigKeys;
 import org.apache.hadoop.hdds.conf.ConfigurationException;
 import org.apache.hadoop.hdds.conf.DefaultConfigManager;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.scm.ScmConfigKeys;
+import org.apache.hadoop.hdds.scm.ScmRatisServerConfig;
 import org.apache.hadoop.hdds.scm.server.SCMStorageConfig;
 import org.apache.hadoop.hdds.scm.server.StorageContainerManager;
 import org.apache.hadoop.hdds.utils.HddsServerUtil;
 import org.apache.hadoop.net.NetUtils;
 import org.apache.hadoop.ozone.common.Storage;
 import org.apache.hadoop.ozone.ha.ConfUtils;
+import org.apache.ozone.test.GenericTestUtils;
+import org.apache.ratis.conf.RaftProperties;
+import org.apache.ratis.server.RaftServerConfigKeys;
+import org.apache.ratis.util.TimeDuration;
 import org.junit.Assert;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -202,6 +208,18 @@ class TestSCMHAConfiguration {
         scmServiceId, "scm1"), 9999));
 
 
+    final ScmRatisServerConfig scmRatisConfig = conf.getObject(
+        ScmRatisServerConfig.class);
+    assertEquals(0, scmRatisConfig.getLogAppenderWaitTimeMin(),
+        "getLogAppenderWaitTimeMin");
+
+    final File testDir = GenericTestUtils.getRandomizedTestDir();
+    conf.set(HddsConfigKeys.OZONE_METADATA_DIRS, testDir.getPath());
+
+    final RaftProperties p = RatisUtil.newRaftProperties(conf);
+    final TimeDuration t = RaftServerConfigKeys.Log.Appender.waitTimeMin(p);
+    assertEquals(TimeDuration.ZERO, t,
+        RaftServerConfigKeys.Log.Appender.WAIT_TIME_MIN_KEY);
   }
 
 
diff --git 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestOzoneConfigurationFields.java
 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestOzoneConfigurationFields.java
index 23cfaf3265..cb29d61e1a 100644
--- 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestOzoneConfigurationFields.java
+++ 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestOzoneConfigurationFields.java
@@ -139,6 +139,7 @@ public class TestOzoneConfigurationFields extends 
TestConfigurationFieldsBase {
         OMConfigKeys.OZONE_OM_RANGER_HTTPS_ADMIN_API_USER,
         OMConfigKeys.OZONE_OM_RANGER_HTTPS_ADMIN_API_PASSWD,
         ScmConfigKeys.OZONE_SCM_PIPELINE_PLACEMENT_IMPL_KEY,
+        ScmConfigKeys.OZONE_SCM_HA_PREFIX,
         S3GatewayConfigKeys.OZONE_S3G_FSO_DIRECTORY_CREATION_ENABLED,
         HddsConfigKeys.HDDS_DATANODE_VOLUME_MIN_FREE_SPACE_PERCENT
     ));
diff --git 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOmConf.java
 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOmConf.java
new file mode 100644
index 0000000000..d46e0526b9
--- /dev/null
+++ 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOmConf.java
@@ -0,0 +1,57 @@
+/*
+ * 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.ozone.om;
+
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.ozone.om.ratis.OzoneManagerRatisServer;
+import org.apache.hadoop.ozone.om.ratis.OzoneManagerRatisServerConfig;
+import org.apache.ratis.conf.RaftProperties;
+import org.apache.ratis.server.RaftServerConfigKeys;
+import org.apache.ratis.util.TimeDuration;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Test for Ozone Manager configuration.
+ */
+public class TestOmConf {
+
+  @Test
+  public void testConf() {
+    final OzoneConfiguration conf = new OzoneConfiguration();
+    final OzoneManagerRatisServerConfig ratisConf = conf.getObject(
+        OzoneManagerRatisServerConfig.class);
+    Assertions.assertEquals(0, ratisConf.getLogAppenderWaitTimeMin(),
+        "getLogAppenderWaitTimeMin");
+    assertWaitTimeMin(TimeDuration.ZERO, conf);
+
+    ratisConf.setLogAppenderWaitTimeMin(1);
+    conf.setFromObject(ratisConf);
+    assertWaitTimeMin(TimeDuration.ONE_MILLISECOND, conf);
+
+  }
+
+  static void assertWaitTimeMin(TimeDuration expected,
+      OzoneConfiguration conf) {
+    final RaftProperties p = OzoneManagerRatisServer.newRaftProperties(
+        conf, 1000, "dummy/dir");
+    final TimeDuration t = RaftServerConfigKeys.Log.Appender.waitTimeMin(p);
+    Assertions.assertEquals(expected, t,
+        RaftServerConfigKeys.Log.Appender.WAIT_TIME_MIN_KEY);
+  }
+}
diff --git 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOzoneManagerHAKeyDeletion.java
 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOzoneManagerHAKeyDeletion.java
index f90ddf7b05..6407805a09 100644
--- 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOzoneManagerHAKeyDeletion.java
+++ 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOzoneManagerHAKeyDeletion.java
@@ -23,6 +23,10 @@ import org.apache.hadoop.ozone.client.OzoneBucket;
 import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
 import org.apache.hadoop.ozone.om.service.KeyDeletingService;
 import org.apache.ozone.test.GenericTestUtils;
+import org.apache.ratis.conf.RaftProperties;
+import org.apache.ratis.server.RaftServerConfigKeys;
+import org.apache.ratis.util.TimeDuration;
+import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
 import java.util.ArrayList;
@@ -34,6 +38,17 @@ import static org.junit.Assert.fail;
  * Tests key deletion in OM HA setup.
  */
 public class TestOzoneManagerHAKeyDeletion extends TestOzoneManagerHA {
+  @Test
+  public void testConf() {
+    final RaftProperties p = getCluster()
+        .getOzoneManager()
+        .getOmRatisServer()
+        .getServer()
+        .getProperties();
+    final TimeDuration t = RaftServerConfigKeys.Log.Appender.waitTimeMin(p);
+    Assertions.assertEquals(TimeDuration.ZERO, t,
+        RaftServerConfigKeys.Log.Appender.WAIT_TIME_MIN_KEY);
+  }
 
   @Test
   public void testKeyDeletion() throws Exception {
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerRatisServer.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerRatisServer.java
index b36118b37e..77e2599be7 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerRatisServer.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerRatisServer.java
@@ -143,7 +143,8 @@ public final class OzoneManagerRatisServer {
     this.omRatisAddress = addr;
     this.port = addr.getPort();
     this.ratisStorageDir = OzoneManagerRatisUtils.getOMRatisDirectory(conf);
-    RaftProperties serverProperties = newRaftProperties(conf);
+    final RaftProperties serverProperties = newRaftProperties(
+        conf, port, ratisStorageDir);
 
     this.raftPeerId = localRaftPeerId;
     this.raftGroupId = RaftGroupId.valueOf(
@@ -571,7 +572,8 @@ public final class OzoneManagerRatisServer {
 
   //TODO simplify it to make it shorter
   @SuppressWarnings("methodlength")
-  private RaftProperties newRaftProperties(ConfigurationSource conf) {
+  public static RaftProperties newRaftProperties(ConfigurationSource conf,
+      int port, String ratisStorageDir) {
     // Set RPC type
     final String rpcType = conf.get(
         OMConfigKeys.OZONE_OM_RATIS_RPC_TYPE_KEY,
@@ -727,19 +729,10 @@ public final class OzoneManagerRatisServer {
     RaftServerConfigKeys.Snapshot.setAutoTriggerThreshold(properties,
         snapshotAutoTriggerThreshold);
 
-    createRaftServerProperties(conf, properties);
+    getOMHAConfigs(conf).forEach(properties::set);
     return properties;
   }
 
-  private void createRaftServerProperties(ConfigurationSource ozoneConf,
-      RaftProperties raftProperties) {
-    Map<String, String> ratisServerConf =
-        getOMHAConfigs(ozoneConf);
-    ratisServerConf.forEach((key, val) -> {
-      raftProperties.set(key, val);
-    });
-  }
-
   private static Map<String, String> getOMHAConfigs(
       ConfigurationSource configuration) {
     return configuration
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerRatisServerConfig.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerRatisServerConfig.java
index c681289191..65248e7066 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerRatisServerConfig.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerRatisServerConfig.java
@@ -27,6 +27,7 @@ import java.time.Duration;
 
 import static org.apache.hadoop.hdds.conf.ConfigTag.OM;
 import static org.apache.hadoop.hdds.conf.ConfigTag.OZONE;
+import static org.apache.hadoop.hdds.conf.ConfigTag.PERFORMANCE;
 import static org.apache.hadoop.hdds.conf.ConfigTag.RATIS;
 
 /**
@@ -35,6 +36,22 @@ import static org.apache.hadoop.hdds.conf.ConfigTag.RATIS;
 @ConfigGroup(prefix = OMConfigKeys.OZONE_OM_HA_PREFIX + "."
     + RaftServerConfigKeys.PREFIX)
 public class OzoneManagerRatisServerConfig {
+  /** @see RaftServerConfigKeys.Log.Appender#WAIT_TIME_MIN_KEY */
+  @Config(key = "log.appender.wait-time.min",
+      defaultValue = "0ms",
+      type = ConfigType.TIME,
+      tags = {OZONE, OM, RATIS, PERFORMANCE},
+      description = "Minimum wait time between two appendEntries calls."
+  )
+  private long logAppenderWaitTimeMin;
+
+  public long getLogAppenderWaitTimeMin() {
+    return logAppenderWaitTimeMin;
+  }
+
+  public void setLogAppenderWaitTimeMin(long logAppenderWaitTimeMin) {
+    this.logAppenderWaitTimeMin = logAppenderWaitTimeMin;
+  }
 
   @Config(key = "retrycache.expirytime",
       defaultValue = "300s",


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

Reply via email to