Add direct in-memory journal threshold 74/92274/1
authortadei.bilan <tadei.bilan@pantheon.tech>
Tue, 21 Jul 2020 09:24:09 +0000 (12:24 +0300)
committerRobert Varga <nite@hq.sk>
Thu, 3 Sep 2020 11:52:08 +0000 (11:52 +0000)
Some deployments benefit from placing an absolute numeric limit
on the retained memory. Introduce a new tunable, which overrides
the usual percentange limit.

JIRA: CONTROLLER-1956
Change-Id: I688e226b173386765bea74931b6aaf617bda30a8
Signed-off-by: tadei.bilan <tadei.bilan@pantheon.tech>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 7cb260aeb0738104e3bee8a086de9e2e5f77b7e0)

opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ConfigParams.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/DefaultConfigParamsImpl.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ReplicatedLogImpl.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/SnapshotManager.java
opendaylight/md-sal/sal-clustering-config/src/main/resources/initial/datastore.cfg
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DatastoreContext.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/DatastoreConfigurationMXBean.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/DatastoreConfigurationMXBeanImpl.java
opendaylight/md-sal/sal-distributed-datastore/src/main/yang/distributed-datastore-provider.yang
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DatastoreContextIntrospectorTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DatastoreContextTest.java

index c5c78130e8fcb22c5c614a03032a74acae40a2bc..8351374d60fe0e73bb5ca2fbfa2ea01cbd5a3f52 100644 (file)
@@ -12,14 +12,9 @@ import org.opendaylight.controller.cluster.raft.policy.RaftPolicy;
 import scala.concurrent.duration.FiniteDuration;
 
 /**
- * Configuration Parameter interface for configuring the Raft consensus system
- *
- * <p>
- * Any component using this implementation might want to provide an implementation of
- * this interface to configure
- *
- * <p>
- * A default implementation will be used if none is provided.
+ * Configuration Parameter interface for configuring the Raft consensus system. Any component using this implementation
+ * might want to provide an implementation of this interface to configure. A default implementation will be used if none
+ * is provided.
  *
  * @author Kamal Rameshan
  */
@@ -35,15 +30,23 @@ public interface ConfigParams {
 
     /**
      * Returns the percentage of total memory used in the in-memory Raft log before a snapshot should be taken.
+     * Disabled when direct threshold is enabled.
      *
      * @return the percentage.
      */
     int getSnapshotDataThresholdPercentage();
 
+    /**
+     * Returns the max size of memory used in the in-memory Raft log before a snapshot should be taken. 0 means that
+     * direct threshold is disabled and percentage is used instead.
+     *
+     * @return maximum journal size (in MiB).
+     */
+    int getSnapshotDataThreshold();
 
     /**
-     * Returns the interval(in seconds) after which a snapshot should be taken during recovery.
-     * Negative value means don't take snapshots.
+     * Returns the interval(in seconds) after which a snapshot should be taken during recovery. Negative value means
+     * do not take snapshots.
      *
      * @return the interval of recovery snapshot in seconds
      */
@@ -100,7 +103,6 @@ public interface ConfigParams {
      */
     long getIsolatedCheckIntervalInMillis();
 
-
     /**
      * Returns the multiplication factor to be used to determine the shard election timeout. The election timeout
      * is determined by multiplying the election timeout factor with the heart beat duration.
@@ -109,7 +111,6 @@ public interface ConfigParams {
      */
     long getElectionTimeoutFactor();
 
-
     /**
      * Returns the RaftPolicy used to determine certain Raft behaviors.
      *
index 97838b03212f8ea8b3fbd6201995b398a9b61977..37ed729bed3e4edaf8f5f013c6a497edb8ba7eb6 100644 (file)
@@ -68,6 +68,10 @@ public class DefaultConfigParamsImpl implements ConfigParams {
     // in-memory journal can use before it needs to snapshot
     private int snapshotDataThresholdPercentage = 12;
 
+    // max size of in-memory journal in MB
+    // 0 means direct threshold if disabled
+    private int snapshotDataThreshold = 0;
+
     private int snapshotChunkSize = SNAPSHOT_CHUNK_SIZE;
 
     private long electionTimeoutFactor = 2;
@@ -100,6 +104,10 @@ public class DefaultConfigParamsImpl implements ConfigParams {
         this.snapshotDataThresholdPercentage = snapshotDataThresholdPercentage;
     }
 
+    public void setSnapshotDataThreshold(final int snapshotDataThreshold) {
+        this.snapshotDataThreshold = snapshotDataThreshold;
+    }
+
     public void setSnapshotChunkSize(final int snapshotChunkSize) {
         this.snapshotChunkSize = snapshotChunkSize;
     }
@@ -148,6 +156,11 @@ public class DefaultConfigParamsImpl implements ConfigParams {
         return snapshotDataThresholdPercentage;
     }
 
+    @Override
+    public int getSnapshotDataThreshold() {
+        return snapshotDataThreshold;
+    }
+
     @Override
     public int getRecoverySnapshotIntervalSeconds() {
         return this.recoverySnapshotIntervalSeconds;
index 66d7b352a22f3ec94a896104098d3145c4fc30d5..6167aac6d2ad71da7225c388ce4bb68bbb139070 100644 (file)
@@ -54,10 +54,14 @@ final class ReplicatedLogImpl extends AbstractReplicatedLogImpl {
     @Override
     public boolean shouldCaptureSnapshot(final long logIndex) {
         final ConfigParams config = context.getConfigParams();
-        final long journalSize = logIndex + 1;
-        final long dataThreshold = context.getTotalMemory() * config.getSnapshotDataThresholdPercentage() / 100;
+        if ((logIndex + 1) % config.getSnapshotBatchCount() == 0) {
+            return true;
+        }
 
-        return journalSize % config.getSnapshotBatchCount() == 0 || getDataSizeForSnapshotCheck() > dataThreshold;
+        final long absoluteThreshold = config.getSnapshotDataThreshold();
+        final long dataThreshold = absoluteThreshold != 0 ? absoluteThreshold * ConfigParams.MEGABYTE
+                : context.getTotalMemory() * config.getSnapshotDataThresholdPercentage() / 100;
+        return getDataSizeForSnapshotCheck() > dataThreshold;
     }
 
     @Override
index 3e2410efdea80b659bfd200b2d9a160a4cffa9fb..791a791027ab2a2c2e7dc8786d167514c754dae6 100644 (file)
@@ -379,11 +379,14 @@ public class SnapshotManager implements SnapshotState {
 
             log.info("{}: Persisting of snapshot done: {}", persistenceId(), snapshot);
 
-            long dataThreshold = totalMemory * context.getConfigParams().getSnapshotDataThresholdPercentage() / 100;
-            boolean dataSizeThresholdExceeded = context.getReplicatedLog().dataSize() > dataThreshold;
+            final ConfigParams config = context.getConfigParams();
+            final long absoluteThreshold = config.getSnapshotDataThreshold();
+            final long dataThreshold = absoluteThreshold != 0 ? absoluteThreshold * ConfigParams.MEGABYTE
+                    : totalMemory * config.getSnapshotDataThresholdPercentage() / 100;
 
-            boolean logSizeExceededSnapshotBatchCount =
-                    context.getReplicatedLog().size() >= context.getConfigParams().getSnapshotBatchCount();
+            final boolean dataSizeThresholdExceeded = context.getReplicatedLog().dataSize() > dataThreshold;
+            final boolean logSizeExceededSnapshotBatchCount =
+                    context.getReplicatedLog().size() >= config.getSnapshotBatchCount();
 
             final RaftActorBehavior currentBehavior = context.getCurrentBehavior();
             if (dataSizeThresholdExceeded || logSizeExceededSnapshotBatchCount || captureSnapshot.isMandatoryTrim()) {
@@ -395,8 +398,7 @@ public class SnapshotManager implements SnapshotState {
                     } else if (logSizeExceededSnapshotBatchCount) {
                         log.debug("{}: log size {} exceeds the snapshot batch count {} - doing snapshotPreCommit with "
                                 + "index {}", context.getId(), context.getReplicatedLog().size(),
-                                context.getConfigParams().getSnapshotBatchCount(),
-                                captureSnapshot.getLastAppliedIndex());
+                                config.getSnapshotBatchCount(), captureSnapshot.getLastAppliedIndex());
                     } else {
                         log.debug("{}: user triggered or root overwrite snapshot encountered, trimming log up to "
                                 + "last applied index {}", context.getId(), captureSnapshot.getLastAppliedIndex());
index 25ee73b45c7a1bddbcc872ea3db8d8fe49aad878..b9821e28302dc3a813b7f3c0b3c59b002654b156 100644 (file)
@@ -53,8 +53,13 @@ operational.persistent=false
 #shard-snapshot-batch-count=20000
 
 # The percentage of Runtime.totalMemory() used by the in-memory journal log before a snapshot is to be taken.
+# Disabled, if direct threshold is enabled.
 #shard-snapshot-data-threshold-percentage=12
 
+# The max size of in-memory journal(in MB), after reaching the limit, snapshot will be taken. Should be not less then 1.
+# If set to 0, direct threshold is disabled and percentage is used instead.
+#shard-snapshot-data-threshold=0
+
 # The interval at which the leader of the shard will check if its majority followers are active and
 # term itself as isolated.
 #shard-isolated-leader-check-interval-in-millis=5000
index ddc6e29f5dd99c3391c6f8294c1de05fb873c86f..757612660024ed2c6970e49de8a57fe99897662a 100644 (file)
@@ -57,6 +57,7 @@ public class DatastoreContext implements ClientActorConfig {
     public static final boolean DEFAULT_SNAPSHOT_ON_ROOT_OVERWRITE = false;
     public static final FileAkkaConfigurationReader DEFAULT_CONFIGURATION_READER = new FileAkkaConfigurationReader();
     public static final int DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD_PERCENTAGE = 12;
+    public static final int DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD = 0;
     public static final int DEFAULT_SHARD_ELECTION_TIMEOUT_FACTOR = 2;
     public static final int DEFAULT_SHARD_CANDIDATE_ELECTION_TIMEOUT_DIVISOR = 1;
     public static final int DEFAULT_TX_CREATION_INITIAL_RATE_LIMIT = 100;
@@ -114,6 +115,7 @@ public class DatastoreContext implements ClientActorConfig {
         setHeartbeatInterval(DEFAULT_HEARTBEAT_INTERVAL_IN_MILLIS);
         setIsolatedLeaderCheckInterval(DEFAULT_ISOLATED_LEADER_CHECK_INTERVAL_IN_MILLIS);
         setSnapshotDataThresholdPercentage(DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD_PERCENTAGE);
+        setSnapshotDataThreshold(DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD);
         setElectionTimeoutFactor(DEFAULT_SHARD_ELECTION_TIMEOUT_FACTOR);
         setCandidateElectionTimeoutDivisor(DEFAULT_SHARD_CANDIDATE_ELECTION_TIMEOUT_DIVISOR);
         setSyncIndexThreshold(DEFAULT_SYNC_INDEX_THRESHOLD);
@@ -154,6 +156,7 @@ public class DatastoreContext implements ClientActorConfig {
         setHeartbeatInterval(other.raftConfig.getHeartBeatInterval().toMillis());
         setIsolatedLeaderCheckInterval(other.raftConfig.getIsolatedCheckIntervalInMillis());
         setSnapshotDataThresholdPercentage(other.raftConfig.getSnapshotDataThresholdPercentage());
+        setSnapshotDataThreshold(other.raftConfig.getSnapshotDataThreshold());
         setElectionTimeoutFactor(other.raftConfig.getElectionTimeoutFactor());
         setCandidateElectionTimeoutDivisor(other.raftConfig.getCandidateElectionTimeoutDivisor());
         setCustomRaftPolicyImplementation(other.raftConfig.getCustomRaftPolicyImplementationClass());
@@ -309,6 +312,11 @@ public class DatastoreContext implements ClientActorConfig {
         raftConfig.setSnapshotDataThresholdPercentage(shardSnapshotDataThresholdPercentage);
     }
 
+    private void setSnapshotDataThreshold(final int shardSnapshotDataThreshold) {
+        checkArgument(shardSnapshotDataThreshold >= 0);
+        raftConfig.setSnapshotDataThreshold(shardSnapshotDataThreshold);
+    }
+
     private void setSnapshotBatchCount(final long shardSnapshotBatchCount) {
         raftConfig.setSnapshotBatchCount(shardSnapshotBatchCount);
     }
@@ -470,6 +478,11 @@ public class DatastoreContext implements ClientActorConfig {
             return this;
         }
 
+        public Builder shardSnapshotDataThreshold(final int shardSnapshotDataThreshold) {
+            datastoreContext.setSnapshotDataThreshold(shardSnapshotDataThreshold);
+            return this;
+        }
+
         public Builder shardHeartbeatIntervalInMillis(final int shardHeartbeatIntervalInMillis) {
             datastoreContext.setHeartbeatInterval(shardHeartbeatIntervalInMillis);
             return this;
index 3abdafd983bfa05b0929f5c11bb6ac9d44eb82e5..f229328b2bc61cc2063af2f5508332b2bd78da6f 100644 (file)
@@ -28,6 +28,8 @@ public interface DatastoreConfigurationMXBean {
 
     int getShardSnapshotDataThresholdPercentage();
 
+    int getShardSnapshotDataThreshold();
+
     long getShardSnapshotBatchCount();
 
     long getShardTransactionCommitTimeoutInSeconds();
index 20b6e79e075fb4674f4ff3e6e73f76b6d61c45cb..e5d1aaf6a24eb5da0554bc148b1b343bb1fe427c 100644 (file)
@@ -64,6 +64,11 @@ public class DatastoreConfigurationMXBeanImpl extends AbstractMXBean implements
         return context.getShardRaftConfig().getSnapshotDataThresholdPercentage();
     }
 
+    @Override
+    public int getShardSnapshotDataThreshold() {
+        return context.getShardRaftConfig().getSnapshotDataThreshold();
+    }
+
     @Override
     public long getShardSnapshotBatchCount() {
         return context.getShardRaftConfig().getSnapshotBatchCount();
index acb22256ce26f88cf8a57b61ca7857703737380c..5eea2f1bf7779e60c2f77d8baca0008f604cecff 100644 (file)
@@ -78,7 +78,17 @@ module distributed-datastore-provider {
         leaf shard-snapshot-data-threshold-percentage {
             default 12;
             type percentage;
-            description "The percentage of Runtime.maxMemory() used by the in-memory journal log before a snapshot is to be taken";
+            description "The percentage of Runtime.maxMemory() used by the in-memory journal log before a snapshot is to be taken.
+                         Disabled, if direct threshold is enabled.";
+        }
+
+        leaf shard-snapshot-data-threshold {
+            default 0;
+            type uint32 {
+                range "0..max";
+            }
+            description "The threshold of in-memory journal size before a snapshot is to be taken. If set to 0, direct threshold
+                         is disabled and percentage is used instead.";
         }
 
 
index ef00e161d863ad75910e87c98ec2491515db36fc..992278725b8ad3f37c451be8dbc69f7dcdb03445 100644 (file)
@@ -15,6 +15,7 @@ import static org.mockito.Mockito.mock;
 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_HEARTBEAT_INTERVAL_IN_MILLIS;
 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_OPERATION_TIMEOUT_IN_MS;
 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_INITIALIZATION_TIMEOUT;
+import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD;
 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD_PERCENTAGE;
 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_TRANSACTION_IDLE_TIMEOUT;
 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_TX_COMMIT_TIMEOUT_IN_SECONDS;
@@ -89,6 +90,7 @@ public class DatastoreContextIntrospectorTest {
         properties.put("recovery-snapshot-interval-seconds", "360");
         properties.put("shard-isolated-leader-check-interval-in-millis", "123");
         properties.put("shard-snapshot-data-threshold-percentage", "100");
+        properties.put("shard-snapshot-data-threshold", "800");
         properties.put("shard-election-timeout-factor", "21");
         properties.put("shard-batched-modification-count", "901");
         properties.put("transactionCreationInitialRateLimit", "200");
@@ -116,6 +118,7 @@ public class DatastoreContextIntrospectorTest {
         assertEquals(360, context.getShardRaftConfig().getRecoverySnapshotIntervalSeconds());
         assertEquals(123, context.getShardRaftConfig().getIsolatedCheckIntervalInMillis());
         assertEquals(100, context.getShardRaftConfig().getSnapshotDataThresholdPercentage());
+        assertEquals(800, context.getShardRaftConfig().getSnapshotDataThreshold());
         assertEquals(21, context.getShardRaftConfig().getElectionTimeoutFactor());
         assertEquals(901, context.getShardBatchedModificationCount());
         assertEquals(200, context.getTransactionCreationInitialRateLimit());
@@ -151,6 +154,7 @@ public class DatastoreContextIntrospectorTest {
         assertEquals(6, context.getInitialSettleTimeoutMultiplier());
         assertEquals(123, context.getShardRaftConfig().getIsolatedCheckIntervalInMillis());
         assertEquals(100, context.getShardRaftConfig().getSnapshotDataThresholdPercentage());
+        assertEquals(800, context.getShardRaftConfig().getSnapshotDataThreshold());
         assertEquals(22, context.getShardRaftConfig().getElectionTimeoutFactor());
         assertEquals(200, context.getTransactionCreationInitialRateLimit());
         assertEquals(42, context.getDataStoreProperties().getMaxDataChangeExecutorPoolSize());
@@ -180,6 +184,7 @@ public class DatastoreContextIntrospectorTest {
         properties.put("shard-heartbeat-interval-in-millis", "99"); // bad - must be >= 100
         properties.put("shard-transaction-commit-queue-capacity", "567"); // good
         properties.put("shard-snapshot-data-threshold-percentage", "101"); // bad - must be 0-100
+        properties.put("shard-snapshot-data-threshold", "-1"); // bad - must be > 0
         properties.put("shard-initialization-timeout-in-seconds", "-1"); // bad - must be > 0
         properties.put("max-shard-data-change-executor-pool-size", "bogus"); // bad - NaN
         properties.put("unknownProperty", "1"); // bad - invalid property name
@@ -198,6 +203,7 @@ public class DatastoreContextIntrospectorTest {
         assertEquals(567, context.getShardTransactionCommitQueueCapacity());
         assertEquals(DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD_PERCENTAGE,
                 context.getShardRaftConfig().getSnapshotDataThresholdPercentage());
+        assertEquals(DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD, context.getShardRaftConfig().getSnapshotDataThreshold());
         assertEquals(DEFAULT_SHARD_INITIALIZATION_TIMEOUT, context.getShardInitializationTimeout());
         assertEquals(InMemoryDOMDataStoreConfigProperties.DEFAULT_MAX_DATA_CHANGE_EXECUTOR_POOL_SIZE,
                 context.getDataStoreProperties().getMaxDataChangeExecutorPoolSize());
index 59c7d5ab8e3623c98a88913abee0982a84262f88..7825f6009a859cf088432bba0c234e078e02fc3c 100644 (file)
@@ -22,6 +22,7 @@ import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEF
 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_ELECTION_TIMEOUT_FACTOR;
 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_INITIALIZATION_TIMEOUT;
 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_LEADER_ELECTION_TIMEOUT;
+import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD;
 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD_PERCENTAGE;
 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_TRANSACTION_IDLE_TIMEOUT;
 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_TX_COMMIT_QUEUE_CAPACITY;
@@ -61,6 +62,8 @@ public class DatastoreContextTest {
                 context.getShardRaftConfig().getIsolatedCheckIntervalInMillis());
         assertEquals(DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD_PERCENTAGE,
                 context.getShardRaftConfig().getSnapshotDataThresholdPercentage());
+        assertEquals(DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD,
+                context.getShardRaftConfig().getSnapshotDataThreshold());
         assertEquals(DEFAULT_SHARD_ELECTION_TIMEOUT_FACTOR, context.getShardRaftConfig().getElectionTimeoutFactor());
         assertEquals(DEFAULT_TX_CREATION_INITIAL_RATE_LIMIT, context.getTransactionCreationInitialRateLimit());
         assertEquals(DatastoreContext.DEFAULT_SHARD_BATCHED_MODIFICATION_COUNT,
@@ -99,6 +102,7 @@ public class DatastoreContextTest {
         builder.persistent(!DEFAULT_PERSISTENT);
         builder.shardIsolatedLeaderCheckIntervalInMillis(DEFAULT_ISOLATED_LEADER_CHECK_INTERVAL_IN_MILLIS + 1);
         builder.shardSnapshotDataThresholdPercentage(DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD_PERCENTAGE + 1);
+        builder.shardSnapshotDataThreshold(DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD + 1);
         builder.shardElectionTimeoutFactor(DEFAULT_SHARD_ELECTION_TIMEOUT_FACTOR + 1);
         builder.transactionCreationInitialRateLimit(DEFAULT_TX_CREATION_INITIAL_RATE_LIMIT + 1);
         builder.shardBatchedModificationCount(DEFAULT_SHARD_BATCHED_MODIFICATION_COUNT + 1);
@@ -153,6 +157,8 @@ public class DatastoreContextTest {
                 context.getShardRaftConfig().getIsolatedCheckIntervalInMillis());
         assertEquals(DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD_PERCENTAGE + 1,
                 context.getShardRaftConfig().getSnapshotDataThresholdPercentage());
+        assertEquals(DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD + 1,
+                context.getShardRaftConfig().getSnapshotDataThreshold());
         assertEquals(DEFAULT_SHARD_ELECTION_TIMEOUT_FACTOR + 1,
                 context.getShardRaftConfig().getElectionTimeoutFactor());
         assertEquals(DEFAULT_TX_CREATION_INITIAL_RATE_LIMIT + 1, context.getTransactionCreationInitialRateLimit());