You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ratis.apache.org by dr...@apache.org on 2022/08/22 12:12:16 UTC
[ratis] 03/03: RATIS-1638. Separate first election timeout (#713)
This is an automated email from the ASF dual-hosted git repository.
dragonyliu pushed a commit to branch branch-2
in repository https://gitbox.apache.org/repos/asf/ratis.git
commit 87d7d0144ed0d059afa824d44d96d65e0b01075e
Author: William Song <48...@users.noreply.github.com>
AuthorDate: Fri Aug 19 23:18:29 2022 +0800
RATIS-1638. Separate first election timeout (#713)
(cherry picked from commit e49687aba20cad70c576900f1be59bb8fcd55d10)
---
.../main/java/org/apache/ratis/conf/ConfUtils.java | 14 +++++++-
.../apache/ratis/server/RaftServerConfigKeys.java | 39 +++++++++++++++++++---
.../apache/ratis/server/impl/RaftServerImpl.java | 17 ++++++++++
.../org/apache/ratis/server/impl/ServerState.java | 1 +
4 files changed, 66 insertions(+), 5 deletions(-)
diff --git a/ratis-common/src/main/java/org/apache/ratis/conf/ConfUtils.java b/ratis-common/src/main/java/org/apache/ratis/conf/ConfUtils.java
index 681c0dc67..629d5a389 100644
--- a/ratis-common/src/main/java/org/apache/ratis/conf/ConfUtils.java
+++ b/ratis-common/src/main/java/org/apache/ratis/conf/ConfUtils.java
@@ -214,6 +214,17 @@ public interface ConfUtils {
return value;
}
+ @SafeVarargs
+ static TimeDuration getTimeDuration(
+ BiFunction<String, TimeDuration, TimeDuration> getter,
+ String key, TimeDuration defaultValue, String fallbackKey, TimeDuration fallbackValue,
+ Consumer<String> logger, BiConsumer<String, TimeDuration>... assertions) {
+ final TimeDuration value = get(getter, key, defaultValue, fallbackKey, fallbackValue, logger, assertions);
+ requireNonNegativeTimeDuration().accept(key, value);
+ return value;
+ }
+
+
static TlsConf getTlsConf(
Function<String, TlsConf> tlsConfGetter,
String key, Consumer<String> logger) {
@@ -236,10 +247,11 @@ public interface ConfUtils {
T value = get(getter, key, defaultValue, null, assertions);
if (value != defaultValue) {
logGet(key, value, defaultValue, logger);
+ return value;
} else {
logFallback(key, fallbackKey, fallbackValue, logger);
+ return fallbackValue;
}
- return value;
}
static InetSocketAddress getInetSocketAddress(
diff --git a/ratis-server-api/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java b/ratis-server-api/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java
index 6d0c5d41b..e24631378 100644
--- a/ratis-server-api/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java
+++ b/ratis-server-api/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java
@@ -619,9 +619,12 @@ public interface RaftServerConfigKeys {
String TIMEOUT_MIN_KEY = PREFIX + ".timeout.min";
TimeDuration TIMEOUT_MIN_DEFAULT = TimeDuration.valueOf(150, TimeUnit.MILLISECONDS);
- static TimeDuration timeoutMin(RaftProperties properties) {
+ static TimeDuration timeoutMin(RaftProperties properties, Consumer<String> logger) {
return getTimeDuration(properties.getTimeDuration(TIMEOUT_MIN_DEFAULT.getUnit()),
- TIMEOUT_MIN_KEY, TIMEOUT_MIN_DEFAULT, getDefaultLog());
+ TIMEOUT_MIN_KEY, TIMEOUT_MIN_DEFAULT, logger);
+ }
+ static TimeDuration timeoutMin(RaftProperties properties) {
+ return timeoutMin(properties, getDefaultLog());
}
static void setTimeoutMin(RaftProperties properties, TimeDuration minDuration) {
setTimeDuration(properties::setTimeDuration, TIMEOUT_MIN_KEY, minDuration);
@@ -629,14 +632,42 @@ public interface RaftServerConfigKeys {
String TIMEOUT_MAX_KEY = PREFIX + ".timeout.max";
TimeDuration TIMEOUT_MAX_DEFAULT = TimeDuration.valueOf(300, TimeUnit.MILLISECONDS);
- static TimeDuration timeoutMax(RaftProperties properties) {
+ static TimeDuration timeoutMax(RaftProperties properties, Consumer<String> logger) {
return getTimeDuration(properties.getTimeDuration(TIMEOUT_MAX_DEFAULT.getUnit()),
- TIMEOUT_MAX_KEY, TIMEOUT_MAX_DEFAULT, getDefaultLog());
+ TIMEOUT_MAX_KEY, TIMEOUT_MAX_DEFAULT, logger);
+ }
+ static TimeDuration timeoutMax(RaftProperties properties) {
+ return timeoutMax(properties, getDefaultLog());
}
static void setTimeoutMax(RaftProperties properties, TimeDuration maxDuration) {
setTimeDuration(properties::setTimeDuration, TIMEOUT_MAX_KEY, maxDuration);
}
+ /** separate first timeout so that the startup unavailable time can be reduced */
+ String FIRST_ELECTION_TIMEOUT_MIN_KEY = PREFIX + ".first-election.timeout.min";
+ TimeDuration FIRST_ELECTION_TIMEOUT_MIN_DEFAULT = null;
+ static TimeDuration firstElectionTimeoutMin(RaftProperties properties) {
+ final TimeDuration fallbackFirstElectionTimeoutMin = Rpc.timeoutMin(properties, null);
+ return getTimeDuration(properties.getTimeDuration(fallbackFirstElectionTimeoutMin.getUnit()),
+ FIRST_ELECTION_TIMEOUT_MIN_KEY, FIRST_ELECTION_TIMEOUT_MIN_DEFAULT,
+ Rpc.TIMEOUT_MIN_KEY, fallbackFirstElectionTimeoutMin, getDefaultLog());
+ }
+ static void setFirstElectionTimeoutMin(RaftProperties properties, TimeDuration firstMinDuration) {
+ setTimeDuration(properties::setTimeDuration, FIRST_ELECTION_TIMEOUT_MIN_KEY, firstMinDuration);
+ }
+
+ String FIRST_ELECTION_TIMEOUT_MAX_KEY = PREFIX + ".first-election.timeout.max";
+ TimeDuration FIRST_ELECTION_TIMEOUT_MAX_DEFAULT = null;
+ static TimeDuration firstElectionTimeoutMax(RaftProperties properties) {
+ final TimeDuration fallbackFirstElectionTimeoutMax = Rpc.timeoutMax(properties, null);
+ return getTimeDuration(properties.getTimeDuration(fallbackFirstElectionTimeoutMax.getUnit()),
+ FIRST_ELECTION_TIMEOUT_MAX_KEY, FIRST_ELECTION_TIMEOUT_MAX_DEFAULT,
+ Rpc.TIMEOUT_MAX_KEY, fallbackFirstElectionTimeoutMax, getDefaultLog());
+ }
+ static void setFirstElectionTimeoutMax(RaftProperties properties, TimeDuration firstMaxDuration) {
+ setTimeDuration(properties::setTimeDuration, FIRST_ELECTION_TIMEOUT_MAX_KEY, firstMaxDuration);
+ }
+
String REQUEST_TIMEOUT_KEY = PREFIX + ".request.timeout";
TimeDuration REQUEST_TIMEOUT_DEFAULT = TimeDuration.valueOf(3000, TimeUnit.MILLISECONDS);
static TimeDuration requestTimeout(RaftProperties properties) {
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java
index ee314dbe2..1994fa8de 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java
@@ -187,6 +187,8 @@ class RaftServerImpl implements RaftServer.Division,
private final ExecutorService serverExecutor;
private final ExecutorService clientExecutor;
+ private final AtomicBoolean firstElectionSinceStartup = new AtomicBoolean(true);
+
RaftServerImpl(RaftGroup group, StateMachine stateMachine, RaftServerProxy proxy) throws IOException {
final RaftPeerId id = proxy.getId();
LOG.info("{}: new RaftServerImpl for {} with {}", id, group, stateMachine);
@@ -245,11 +247,22 @@ class RaftServerImpl implements RaftServer.Division,
}
TimeDuration getRandomElectionTimeout() {
+ if (firstElectionSinceStartup.get()) {
+ return getFirstRandomElectionTimeout();
+ }
final int min = properties().minRpcTimeoutMs();
final int millis = min + ThreadLocalRandom.current().nextInt(properties().maxRpcTimeoutMs() - min + 1);
return TimeDuration.valueOf(millis, TimeUnit.MILLISECONDS);
}
+ private TimeDuration getFirstRandomElectionTimeout() {
+ final RaftProperties properties = proxy.getProperties();
+ final int min = RaftServerConfigKeys.Rpc.firstElectionTimeoutMin(properties).toIntExact(TimeUnit.MILLISECONDS);
+ final int max = RaftServerConfigKeys.Rpc.firstElectionTimeoutMax(properties).toIntExact(TimeUnit.MILLISECONDS);
+ final int mills = min + ThreadLocalRandom.current().nextInt(max - min + 1);
+ return TimeDuration.valueOf(mills, TimeUnit.MILLISECONDS);
+ }
+
TimeDuration getLeaderStepDownWaitTime() {
return leaderStepDownWaitTime;
}
@@ -1725,4 +1738,8 @@ class RaftServerImpl implements RaftServer.Division,
.collect(Collectors.toList());
}
}
+
+ void onGroupLeaderElected() {
+ this.firstElectionSinceStartup.set(false);
+ }
}
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java
index 34e9cb92c..1ee2cab5e 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java
@@ -315,6 +315,7 @@ class ServerState implements Closeable {
leaderId = newLeaderId;
if (leaderId != null) {
server.finishTransferLeadership();
+ server.onGroupLeaderElected();
}
}
}