aboutsummaryrefslogtreecommitdiffstats
path: root/zookeeper-server/zookeeper-server-common/src/main
diff options
context:
space:
mode:
authorJon Marius Venstad <venstad@gmail.com>2021-10-18 10:10:35 +0200
committerJon Marius Venstad <venstad@gmail.com>2022-01-11 10:31:10 +0100
commit38a353a10345b2a5e17d241057bdbf662e4b05d1 (patch)
treeae9fa1e84631c09e5ecde024597baba98f96502c /zookeeper-server/zookeeper-server-common/src/main
parent79b2045754f226de4e20c800e62bcb94b81d0b83 (diff)
Use bulk reconfig mode
Diffstat (limited to 'zookeeper-server/zookeeper-server-common/src/main')
-rw-r--r--zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java11
-rw-r--r--zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Reconfigurer.java45
-rw-r--r--zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperAdmin.java2
3 files changed, 25 insertions, 33 deletions
diff --git a/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java
index f95704f8b58..c65035106f1 100644
--- a/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java
+++ b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java
@@ -85,7 +85,7 @@ public class Configurator {
sb.append("reconfigEnabled=true").append("\n");
sb.append("skipACL=yes").append("\n");
ensureThisServerIsRepresented(config.myid(), config.server());
- config.server().forEach(server -> addServerToCfg(sb, server, config.clientPort()));
+ config.server().forEach(server -> sb.append(serverSpec(server, config.clientPort(), server.joining())).append("\n"));
sb.append(new TlsQuorumConfig().createConfig(vespaTlsConfig));
sb.append(new TlsClientServerConfig().createConfig(vespaTlsConfig));
return sb.toString();
@@ -110,7 +110,8 @@ public class Configurator {
}
}
- private void addServerToCfg(StringBuilder sb, ZookeeperServerConfig.Server server, int clientPort) {
+ static String serverSpec(ZookeeperServerConfig.Server server, int clientPort, boolean joining) {
+ StringBuilder sb = new StringBuilder();
sb.append("server.")
.append(server.id())
.append("=")
@@ -119,7 +120,7 @@ public class Configurator {
.append(server.quorumPort())
.append(":")
.append(server.electionPort());
- if (server.joining()) {
+ if (joining) {
// Servers that are joining an existing cluster must be marked as observers. Note that this will NOT
// actually make the server an observer, but prevent it from forming an ensemble independently of the
// existing cluster.
@@ -129,8 +130,8 @@ public class Configurator {
.append("observer");
}
sb.append(";")
- .append(clientPort)
- .append("\n");
+ .append(clientPort);
+ return sb.toString();
}
static List<String> zookeeperServerHostnames(ZookeeperServerConfig zookeeperServerConfig) {
diff --git a/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Reconfigurer.java b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Reconfigurer.java
index 4452e74bb10..514d45c7e77 100644
--- a/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Reconfigurer.java
+++ b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Reconfigurer.java
@@ -10,13 +10,14 @@ import com.yahoo.yolean.Exceptions;
import java.time.Duration;
import java.time.Instant;
-import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;
-import java.util.stream.Collectors;
+
+import static com.yahoo.vespa.zookeeper.Configurator.serverSpec;
+import static java.util.stream.Collectors.toList;
/**
* Starts zookeeper server and supports reconfiguring zookeeper cluster. Keep this as a component
@@ -84,30 +85,34 @@ public class Reconfigurer extends AbstractComponent {
return runner;
}
+ // TODO jonmv: unify server config writing here and in Configurator
+ // TODO jonmv: read dynamic file, discard if old quorum impossible (config file + .dynamic.<id>)
+ // TODO jonmv: if dynamic file, all unlisted servers are observers; otherwise joiners are observers
+ // TODO jonmv: use bulk mode, i.e., supply only new servers
+ // TODO jonmv: always reconfigure when dynamic config is used, and to only non-retired nodes
+ // TODO jonmv: verify reconfig by issuing a dummy write
+ // TODO jonmv: wrap Curator in Provider, for Curator shutdown
+ // TODO jonmv: scale down to 1 server as well
+ // TODO jonmv: unit test this
private void reconfigure(ZookeeperServerConfig newConfig) {
Instant reconfigTriggered = Instant.now();
// No point in trying to reconfigure if there is only one server in the new ensemble,
// the others will be shutdown or are about to be shutdown
if (newConfig.server().size() == 1) shutdownAndDie(Duration.ZERO);
- List<String> newServers = difference(servers(newConfig), servers(activeConfig));
- String leavingServerIds = String.join(",", serverIdsDifference(activeConfig, newConfig));
- String joiningServersSpec = String.join(",", newServers);
- leavingServerIds = leavingServerIds.isEmpty() ? null : leavingServerIds;
- joiningServersSpec = joiningServersSpec.isEmpty() ? null : joiningServersSpec;
- log.log(Level.INFO, "Will reconfigure ZooKeeper cluster. \nJoining servers: " + joiningServersSpec +
- "\nleaving servers: " + leavingServerIds +
+ String newServers = String.join(",", servers(newConfig));
+ log.log(Level.INFO, "Will reconfigure ZooKeeper cluster." +
"\nServers in active config:" + servers(activeConfig) +
"\nServers in new config:" + servers(newConfig));
String connectionSpec = localConnectionSpec(activeConfig);
Instant now = Instant.now();
- Duration reconfigTimeout = reconfigTimeout(newServers.size());
+ Duration reconfigTimeout = reconfigTimeout(newConfig.server().size());
Instant end = now.plus(reconfigTimeout);
// Loop reconfiguring since we might need to wait until another reconfiguration is finished before we can succeed
for (int attempt = 1; now.isBefore(end); attempt++) {
try {
Instant reconfigStarted = Instant.now();
- vespaZooKeeperAdmin.reconfigure(connectionSpec, joiningServersSpec, leavingServerIds);
+ vespaZooKeeperAdmin.reconfigure(connectionSpec, newServers);
Instant reconfigEnded = Instant.now();
log.log(Level.INFO, "Reconfiguration completed in " +
Duration.between(reconfigTriggered, reconfigEnded) +
@@ -146,24 +151,10 @@ public class Reconfigurer extends AbstractComponent {
return HostName.getLocalhost() + ":" + config.clientPort();
}
- private static List<String> serverIdsDifference(ZookeeperServerConfig oldConfig, ZookeeperServerConfig newConfig) {
- return difference(servers(oldConfig), servers(newConfig)).stream()
- .map(server -> server.substring(0, server.indexOf('=')))
- .collect(Collectors.toList());
- }
-
private static List<String> servers(ZookeeperServerConfig config) {
- // See https://zookeeper.apache.org/doc/r3.6.3/zookeeperReconfig.html#sc_reconfig_clientport for format
return config.server().stream()
- .map(server -> server.id() + "=" + server.hostname() + ":" + server.quorumPort() + ":" +
- server.electionPort() + ";" + config.clientPort())
- .collect(Collectors.toList());
- }
-
- private static <T> List<T> difference(List<T> list1, List<T> list2) {
- List<T> copy = new ArrayList<>(list1);
- copy.removeAll(list2);
- return copy;
+ .map(server -> serverSpec(server, config.clientPort(), false))
+ .collect(toList());
}
}
diff --git a/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperAdmin.java b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperAdmin.java
index 8809dca0def..59c9628bcab 100644
--- a/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperAdmin.java
+++ b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperAdmin.java
@@ -10,7 +10,7 @@ import java.time.Duration;
*/
public interface VespaZooKeeperAdmin {
- void reconfigure(String connectionSpec, String joiningServers, String leavingServers) throws ReconfigException;
+ void reconfigure(String connectionSpec, String servers) throws ReconfigException;
/* Timeout for connecting to ZooKeeper */
default Duration sessionTimeout() { return Duration.ofSeconds(30); }