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

rpuch pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new 00f7a8e5bbf IGNITE-28075 Make writeBufferSize for RocksDB log storage 
configurable (#7724)
00f7a8e5bbf is described below

commit 00f7a8e5bbf401e6d4b0332e16adb337da0d9fa8
Author: Roman Puchkovskiy <[email protected]>
AuthorDate: Mon Mar 9 11:58:38 2026 +0400

    IGNITE-28075 Make writeBufferSize for RocksDB log storage configurable 
(#7724)
---
 modules/raft/build.gradle                          |  1 +
 .../ItLogStorageConfigurationTest.java             | 57 +++++++++++++++++
 .../storage/impl/DefaultLogStorageManager.java     | 36 +++++++----
 .../storage/impl/RocksDbLogStorageOptions.java     | 74 ++++++++++++++++++++++
 .../raft/util/SharedLogStorageManagerUtils.java    | 24 ++++++-
 .../storage/impl/DefaultLogStorageManagerTest.java |  2 +-
 .../org/apache/ignite/internal/app/IgniteImpl.java |  4 +-
 7 files changed, 183 insertions(+), 15 deletions(-)

diff --git a/modules/raft/build.gradle b/modules/raft/build.gradle
index d9b56187f2f..398bfdcbd2b 100644
--- a/modules/raft/build.gradle
+++ b/modules/raft/build.gradle
@@ -118,6 +118,7 @@ dependencies {
     integrationTestImplementation libs.awaitility
     integrationTestImplementation libs.dropwizard.metrics
     integrationTestImplementation libs.disruptor
+    integrationTestImplementation libs.rocksdb.jni
 }
 
 tasks.named('integrationTest').configure {
diff --git 
a/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raftsnapshot/ItLogStorageConfigurationTest.java
 
b/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raftsnapshot/ItLogStorageConfigurationTest.java
new file mode 100644
index 00000000000..fc377b2345f
--- /dev/null
+++ 
b/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raftsnapshot/ItLogStorageConfigurationTest.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.ignite.internal.raftsnapshot;
+
+import static org.apache.ignite.internal.TestWrappers.unwrapIgniteImpl;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.internal.ClusterPerTestIntegrationTest;
+import org.apache.ignite.internal.ConfigOverride;
+import org.apache.ignite.internal.raft.storage.LogStorageManager;
+import org.apache.ignite.internal.raft.storage.impl.DefaultLogStorageManager;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.rocksdb.ColumnFamilyOptions;
+
+class ItLogStorageConfigurationTest extends ClusterPerTestIntegrationTest {
+    private Ignite node;
+
+    @Override
+    protected int initialNodes() {
+        return 1;
+    }
+
+    @BeforeEach
+    void prepare() {
+        node = cluster.node(0);
+    }
+
+    @Test
+    @ConfigOverride(name = 
"ignite.system.properties.partitionsRaftLogStorageWriteBufferSize", value = "" 
+ (99L * 1024 * 1024))
+    void partitionsLogStorageWriteBufferSizeIsTakenFromConfiguration() throws 
Exception {
+        LogStorageManager logStorageManager = 
unwrapIgniteImpl(node).partitionsLogStorageManager();
+        DefaultLogStorageManager defaultLogStorageManager = 
(DefaultLogStorageManager) logStorageManager;
+
+        @SuppressWarnings("resource")
+        ColumnFamilyOptions cfOptions = 
defaultLogStorageManager.dataColumnFamilyHandle().getDescriptor().getOptions();
+
+        assertThat(cfOptions.writeBufferSize(), is(99L * 1024 * 1024));
+    }
+}
diff --git 
a/modules/raft/src/main/java/org/apache/ignite/internal/raft/storage/impl/DefaultLogStorageManager.java
 
b/modules/raft/src/main/java/org/apache/ignite/internal/raft/storage/impl/DefaultLogStorageManager.java
index 27641609e95..eec9af158d7 100644
--- 
a/modules/raft/src/main/java/org/apache/ignite/internal/raft/storage/impl/DefaultLogStorageManager.java
+++ 
b/modules/raft/src/main/java/org/apache/ignite/internal/raft/storage/impl/DefaultLogStorageManager.java
@@ -72,7 +72,6 @@ import org.rocksdb.Slice;
 import org.rocksdb.SstFileManager;
 import org.rocksdb.WriteBatch;
 import org.rocksdb.WriteOptions;
-import org.rocksdb.util.SizeUnit;
 
 /** Implementation of the {@link LogStorageManager} that creates {@link 
RocksDbSharedLogStorage}s. */
 public class DefaultLogStorageManager implements LogStorageManager {
@@ -91,6 +90,8 @@ public class DefaultLogStorageManager implements 
LogStorageManager {
     /** Path to the log storage. */
     private final Path logPath;
 
+    private final RocksDbLogStorageOptions specificOptions;
+
     /** Executor for shared storages. */
     private final ExecutorService executorService;
 
@@ -139,7 +140,7 @@ public class DefaultLogStorageManager implements 
LogStorageManager {
      */
     @TestOnly
     public DefaultLogStorageManager(Path path) {
-        this("test", "test", path, true);
+        this("test", "test", path, true, RocksDbLogStorageOptions.defaults());
     }
 
     /**
@@ -147,14 +148,22 @@ public class DefaultLogStorageManager implements 
LogStorageManager {
      *
      * @param factoryName Name of the log factory, will be used in logs.
      * @param nodeName Node name.
-     * @param logPath Function to get path to the log storage.
+     * @param logPath Path to the log storage.
      * @param fsync If should fsync after each write to database.
+     * @param specificOptions Options specific for this implementation.
      */
-    public DefaultLogStorageManager(String factoryName, String nodeName, Path 
logPath, boolean fsync) {
+    public DefaultLogStorageManager(
+            String factoryName,
+            String nodeName,
+            Path logPath,
+            boolean fsync,
+            RocksDbLogStorageOptions specificOptions
+    ) {
         this.factoryName = factoryName;
         this.logPath = logPath;
         this.fsync = fsync;
         this.nodeName = nodeName;
+        this.specificOptions = specificOptions;
 
         executorService = Executors.newSingleThreadExecutor(
                 IgniteThreadFactory.create(nodeName, 
"raft-shared-log-storage-pool", LOG)
@@ -374,7 +383,7 @@ public class DefaultLogStorageManager implements 
LogStorageManager {
      *
      * @return Default column family options.
      */
-    private static ColumnFamilyOptions createColumnFamilyOptions() {
+    private ColumnFamilyOptions createColumnFamilyOptions() {
         var opts = new ColumnFamilyOptions();
 
         if (!Platform.isWindows()) {
@@ -383,16 +392,21 @@ public class DefaultLogStorageManager implements 
LogStorageManager {
                     .optimizeLevelStyleCompaction();
         }
 
-        opts.setWriteBufferSize(64 * SizeUnit.MB);
+        long writeBufferSize = specificOptions.writeBufferSize();
+        int minWriteBufferNumberToMerge = 1;
+        int level0FileNumCompactionTrigger = 50;
+
+        opts.setWriteBufferSize(writeBufferSize);
         opts.setMaxWriteBufferNumber(5);
-        opts.setMinWriteBufferNumberToMerge(1);
-        opts.setLevel0FileNumCompactionTrigger(50);
+
+        opts.setMinWriteBufferNumberToMerge(minWriteBufferNumberToMerge);
+        opts.setLevel0FileNumCompactionTrigger(level0FileNumCompactionTrigger);
         opts.setLevel0SlowdownWritesTrigger(100);
         opts.setLevel0StopWritesTrigger(200);
         // Size of level 0 which is (in stable state) equal to
         // WriteBufferSize * MinWriteBufferNumberToMerge * 
Level0FileNumCompactionTrigger
-        opts.setMaxBytesForLevelBase(3200 * SizeUnit.MB);
-        opts.setTargetFileSizeBase(320 * SizeUnit.MB);
+        opts.setMaxBytesForLevelBase(writeBufferSize * 
minWriteBufferNumberToMerge * level0FileNumCompactionTrigger);
+        opts.setTargetFileSizeBase(writeBufferSize * 5);
 
         return opts;
     }
@@ -458,7 +472,7 @@ public class DefaultLogStorageManager implements 
LogStorageManager {
     }
 
     @TestOnly
-    ColumnFamilyHandle dataColumnFamilyHandle() {
+    public ColumnFamilyHandle dataColumnFamilyHandle() {
         return dataHandle;
     }
 }
diff --git 
a/modules/raft/src/main/java/org/apache/ignite/internal/raft/storage/impl/RocksDbLogStorageOptions.java
 
b/modules/raft/src/main/java/org/apache/ignite/internal/raft/storage/impl/RocksDbLogStorageOptions.java
new file mode 100644
index 00000000000..d87ce80545f
--- /dev/null
+++ 
b/modules/raft/src/main/java/org/apache/ignite/internal/raft/storage/impl/RocksDbLogStorageOptions.java
@@ -0,0 +1,74 @@
+/*
+ * 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.ignite.internal.raft.storage.impl;
+
+import org.apache.ignite.internal.configuration.SystemLocalView;
+import org.apache.ignite.internal.configuration.SystemPropertyView;
+import org.apache.ignite.internal.logger.IgniteLogger;
+import org.apache.ignite.internal.logger.Loggers;
+import org.rocksdb.util.SizeUnit;
+
+/**
+ * RocksDB-specific options for RocksDB-based log storage.
+ */
+public class RocksDbLogStorageOptions {
+    private static final IgniteLogger LOG = 
Loggers.forClass(RocksDbLogStorageOptions.class);
+
+    private static final String 
PARTITIONS_RAFT_LOG_STORAGE_WRITE_BUFFER_SIZE_PROPERTY_NAME = 
"partitionsRaftLogStorageWriteBufferSize";
+
+    private static final long DEFAULT_WRITE_BUFFER_SIZE = 64 * SizeUnit.MB;
+
+    private final long writeBufferSize;
+
+    public static RocksDbLogStorageOptions forPartitions(SystemLocalView 
properties) {
+        return new 
RocksDbLogStorageOptions(partitionsRaftLogStorageWriteBufferSize(properties));
+    }
+
+    private static long 
partitionsRaftLogStorageWriteBufferSize(SystemLocalView properties) {
+        SystemPropertyView property = 
properties.properties().get(PARTITIONS_RAFT_LOG_STORAGE_WRITE_BUFFER_SIZE_PROPERTY_NAME);
+
+        if (property == null) {
+            return DEFAULT_WRITE_BUFFER_SIZE;
+        }
+
+        try {
+            return Long.parseLong(property.propertyValue());
+        } catch (NumberFormatException e) {
+            LOG.warn(
+                    "Failed to parse partitions writeBufferSize '{}', default 
value will be used ({})",
+                    e,
+                    property.propertyValue(),
+                    DEFAULT_WRITE_BUFFER_SIZE
+            );
+
+            return DEFAULT_WRITE_BUFFER_SIZE;
+        }
+    }
+
+    public static RocksDbLogStorageOptions defaults() {
+        return new RocksDbLogStorageOptions(DEFAULT_WRITE_BUFFER_SIZE);
+    }
+
+    private RocksDbLogStorageOptions(long writeBufferSize) {
+        this.writeBufferSize = writeBufferSize;
+    }
+
+    public long writeBufferSize() {
+        return writeBufferSize;
+    }
+}
diff --git 
a/modules/raft/src/main/java/org/apache/ignite/internal/raft/util/SharedLogStorageManagerUtils.java
 
b/modules/raft/src/main/java/org/apache/ignite/internal/raft/util/SharedLogStorageManagerUtils.java
index e6169dfc1f9..f8917fd16b1 100644
--- 
a/modules/raft/src/main/java/org/apache/ignite/internal/raft/util/SharedLogStorageManagerUtils.java
+++ 
b/modules/raft/src/main/java/org/apache/ignite/internal/raft/util/SharedLogStorageManagerUtils.java
@@ -21,6 +21,7 @@ import java.nio.file.Path;
 import org.apache.ignite.internal.lang.IgniteSystemProperties;
 import org.apache.ignite.internal.raft.storage.LogStorageManager;
 import org.apache.ignite.internal.raft.storage.impl.DefaultLogStorageManager;
+import org.apache.ignite.internal.raft.storage.impl.RocksDbLogStorageOptions;
 import org.apache.ignite.internal.raft.storage.logit.LogitLogStorageManager;
 import org.apache.ignite.raft.jraft.storage.logit.option.StoreOptions;
 import org.jetbrains.annotations.TestOnly;
@@ -48,9 +49,28 @@ public class SharedLogStorageManagerUtils {
      * Creates a LogStorageManager with {@link DefaultLogStorageManager} or 
{@link LogitLogStorageManager} implementation depending on
      * LOGIT_STORAGE_ENABLED_PROPERTY.
      */
-    public static LogStorageManager create(String factoryName, String 
nodeName, Path logStoragePath, boolean fsync) {
+    public static LogStorageManager create(
+            String factoryName,
+            String nodeName,
+            Path logStoragePath,
+            boolean fsync
+    ) {
+        return create(factoryName, nodeName, logStoragePath, fsync, 
RocksDbLogStorageOptions.defaults());
+    }
+
+    /**
+     * Creates a LogStorageManager with {@link DefaultLogStorageManager} or 
{@link LogitLogStorageManager} implementation depending on
+     * LOGIT_STORAGE_ENABLED_PROPERTY.
+     */
+    public static LogStorageManager create(
+            String factoryName,
+            String nodeName,
+            Path logStoragePath,
+            boolean fsync,
+            RocksDbLogStorageOptions specificOptions
+    ) {
         return 
IgniteSystemProperties.getBoolean(LOGIT_STORAGE_ENABLED_PROPERTY, 
LOGIT_STORAGE_ENABLED_PROPERTY_DEFAULT)
                 ? new LogitLogStorageManager(nodeName, new StoreOptions(), 
logStoragePath)
-                : new DefaultLogStorageManager(factoryName, nodeName, 
logStoragePath, fsync);
+                : new DefaultLogStorageManager(factoryName, nodeName, 
logStoragePath, fsync, specificOptions);
     }
 }
diff --git 
a/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/impl/DefaultLogStorageManagerTest.java
 
b/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/impl/DefaultLogStorageManagerTest.java
index bee12132c89..190e642881d 100644
--- 
a/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/impl/DefaultLogStorageManagerTest.java
+++ 
b/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/impl/DefaultLogStorageManagerTest.java
@@ -75,7 +75,7 @@ class DefaultLogStorageManagerTest {
         
logStorageOptions.setLogEntryCodecFactory(DefaultLogEntryCodecFactory.getInstance());
 
         boolean disableFsync = 
testInfo.getTestMethod().orElseThrow().isAnnotationPresent(DisableFsync.class);
-        logStorageManager = new DefaultLogStorageManager("test", "test", 
workDir, !disableFsync);
+        logStorageManager = new DefaultLogStorageManager("test", "test", 
workDir, !disableFsync, RocksDbLogStorageOptions.defaults());
 
         startFactory();
     }
diff --git 
a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java 
b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
index 39de9eee97b..bf1402cf11c 100644
--- 
a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
+++ 
b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
@@ -210,6 +210,7 @@ import 
org.apache.ignite.internal.raft.configuration.RaftExtensionConfiguration;
 import 
org.apache.ignite.internal.raft.server.impl.GroupStoragesContextResolver;
 import org.apache.ignite.internal.raft.storage.GroupStoragesDestructionIntents;
 import org.apache.ignite.internal.raft.storage.LogStorageManager;
+import org.apache.ignite.internal.raft.storage.impl.RocksDbLogStorageOptions;
 import 
org.apache.ignite.internal.raft.storage.impl.VaultGroupStoragesDestructionIntents;
 import 
org.apache.ignite.internal.raft.storage.impl.VolatileLogStorageManagerCreator;
 import org.apache.ignite.internal.raft.util.SharedLogStorageManagerUtils;
@@ -663,7 +664,8 @@ public class IgniteImpl implements Ignite {
                 "table data log",
                 clusterSvc.nodeName(),
                 partitionsWorkDir.raftLogPath(),
-                raftConfiguration.fsync().value()
+                raftConfiguration.fsync().value(),
+                
RocksDbLogStorageOptions.forPartitions(systemConfiguration.value())
         );
 
         LogSyncer partitionsLogSyncer = 
partitionsLogStorageManager.logSyncer();

Reply via email to