@Override public synchronized void startInternal() throws InterruptedException, IOException { LOG.info("Starting Raft journal system"); long startTime = System.currentTimeMillis(); try { mServer.bootstrap(getClusterAddresses(mConf)).get(); } catch (ExecutionException e) { String errorMessage = ExceptionMessage.FAILED_RAFT_BOOTSTRAP.getMessage( Arrays.toString(getClusterAddresses(mConf).toArray()), e.getCause().toString()); throw new IOException(errorMessage, e.getCause()); } LOG.info("Started Raft Journal System in {}ms. Cluster addresses: {}. Local address: {}", System.currentTimeMillis() - startTime, getClusterAddresses(mConf), getLocalAddress(mConf)); }
LOG.info("Bootstrapping new Raft server"); try { mServer.bootstrap(getClusterAddresses(mConf)).get(); } catch (InterruptedException e) { Thread.currentThread().interrupt();
/** * Bootstraps a single-node cluster. * <p> * Bootstrapping a single-node cluster results in the server forming a new cluster to which additional servers * can be joined. * <p> * Only {@link Member.Type#ACTIVE} members can be included in a bootstrap configuration. If the local server is * not initialized as an active member, it cannot be part of the bootstrap configuration for the cluster. * <p> * When the cluster is bootstrapped, the local server will be transitioned into the active state and begin * participating in the Raft consensus algorithm. When the cluster is first bootstrapped, no leader will exist. * The bootstrapped members will elect a leader amongst themselves. Once a cluster has been bootstrapped, additional * members may be {@link #join(Address...) joined} to the cluster. In the event that the bootstrapped members cannot * reach a quorum to elect a leader, bootstrap will continue until successful. * <p> * It is critical that all servers in a bootstrap configuration be started with the same exact set of members. * Bootstrapping multiple servers with different configurations may result in split brain. * <p> * The {@link CompletableFuture} returned by this method will be completed once the cluster has been bootstrapped, * a leader has been elected, and the leader has been notified of the local server's client configurations. * * @return A completable future to be completed once the cluster has been bootstrapped. */ @SuppressWarnings("unchecked") public CompletableFuture<CopycatServer> bootstrap() { return bootstrap(Collections.EMPTY_LIST); }
/** * Bootstraps a single-node cluster. * <p> * Bootstrapping a single-node cluster results in the server forming a new cluster to which additional servers * can be joined. * <p> * Only {@link Member.Type#ACTIVE} members can be included in a bootstrap configuration. If the local server is * not initialized as an active member, it cannot be part of the bootstrap configuration for the cluster. * <p> * When the cluster is bootstrapped, the local server will be transitioned into the active state and begin * participating in the Raft consensus algorithm. When the cluster is first bootstrapped, no leader will exist. * The bootstrapped members will elect a leader amongst themselves. Once a cluster has been bootstrapped, additional * members may be {@link #join(Address...) joined} to the cluster. In the event that the bootstrapped members cannot * reach a quorum to elect a leader, bootstrap will continue until successful. * <p> * It is critical that all servers in a bootstrap configuration be started with the same exact set of members. * Bootstrapping multiple servers with different configurations may result in split brain. * <p> * The {@link CompletableFuture} returned by this method will be completed once the cluster has been bootstrapped, * a leader has been elected, and the leader has been notified of the local server's client configurations. * * @return A completable future to be completed once the cluster has been bootstrapped. */ @SuppressWarnings("unchecked") public CompletableFuture<CopycatServer> bootstrap() { return bootstrap(Collections.EMPTY_LIST); }
/** * Bootstraps the cluster using the provided cluster configuration. * <p> * Bootstrapping the cluster results in a new cluster being formed with the provided configuration. The initial * nodes in a cluster must always be bootstrapped. This is necessary to prevent split brain. If the provided * configuration is empty, the local server will form a single-node cluster. * <p> * Only {@link Member.Type#ACTIVE} members can be included in a bootstrap configuration. If the local server is * not initialized as an active member, it cannot be part of the bootstrap configuration for the cluster. * <p> * When the cluster is bootstrapped, the local server will be transitioned into the active state and begin * participating in the Raft consensus algorithm. When the cluster is first bootstrapped, no leader will exist. * The bootstrapped members will elect a leader amongst themselves. Once a cluster has been bootstrapped, additional * members may be {@link #join(Address...) joined} to the cluster. In the event that the bootstrapped members cannot * reach a quorum to elect a leader, bootstrap will continue until successful. * <p> * It is critical that all servers in a bootstrap configuration be started with the same exact set of members. * Bootstrapping multiple servers with different configurations may result in split brain. * <p> * The {@link CompletableFuture} returned by this method will be completed once the cluster has been bootstrapped, * a leader has been elected, and the leader has been notified of the local server's client configurations. * * @param cluster The bootstrap cluster configuration. * @return A completable future to be completed once the cluster has been bootstrapped. */ public CompletableFuture<ResourceServer> bootstrap(Collection<Address> cluster) { return server.bootstrap(cluster).thenApply(v -> this); }
/** * Bootstraps a single-node cluster. * <p> * Bootstrapping a single-node cluster results in the server forming a new cluster to which additional servers * can be joined. * <p> * Only {@link Member.Type#ACTIVE} members can be included in a bootstrap configuration. If the local server is * not initialized as an active member, it cannot be part of the bootstrap configuration for the cluster. * <p> * When the cluster is bootstrapped, the local server will be transitioned into the active state and begin * participating in the Raft consensus algorithm. When the cluster is first bootstrapped, no leader will exist. * The bootstrapped members will elect a leader amongst themselves. Once a cluster has been bootstrapped, additional * members may be {@link #join(Address...) joined} to the cluster. In the event that the bootstrapped members cannot * reach a quorum to elect a leader, bootstrap will continue until successful. * <p> * It is critical that all servers in a bootstrap configuration be started with the same exact set of members. * Bootstrapping multiple servers with different configurations may result in split brain. * <p> * The {@link CompletableFuture} returned by this method will be completed once the cluster has been bootstrapped, * a leader has been elected, and the leader has been notified of the local server's client configurations. * * @return A completable future to be completed once the cluster has been bootstrapped. */ @SuppressWarnings("unchecked") public CompletableFuture<ResourceServer> bootstrap() { return server.bootstrap().thenApply(v -> this); }
/** * Bootstraps the cluster using the provided cluster configuration. * <p> * Bootstrapping the cluster results in a new cluster being formed with the provided configuration. The initial * nodes in a cluster must always be bootstrapped. This is necessary to prevent split brain. If the provided * configuration is empty, the local server will form a single-node cluster. * <p> * Only {@link Member.Type#ACTIVE} members can be included in a bootstrap configuration. If the local server is * not initialized as an active member, it cannot be part of the bootstrap configuration for the cluster. * <p> * When the cluster is bootstrapped, the local server will be transitioned into the active state and begin * participating in the Raft consensus algorithm. When the cluster is first bootstrapped, no leader will exist. * The bootstrapped members will elect a leader amongst themselves. Once a cluster has been bootstrapped, additional * members may be {@link #join(Address...) joined} to the cluster. In the event that the bootstrapped members cannot * reach a quorum to elect a leader, bootstrap will continue until successful. * <p> * It is critical that all servers in a bootstrap configuration be started with the same exact set of members. * Bootstrapping multiple servers with different configurations may result in split brain. * <p> * The {@link CompletableFuture} returned by this method will be completed once the cluster has been bootstrapped, * a leader has been elected, and the leader has been notified of the local server's client configurations. * * @param cluster The bootstrap cluster configuration. * @return A completable future to be completed once the cluster has been bootstrapped. */ public CompletableFuture<CopycatServer> bootstrap(Address... cluster) { return bootstrap(Arrays.asList(cluster)); }
/** * Bootstraps the cluster using the provided cluster configuration. * <p> * Bootstrapping the cluster results in a new cluster being formed with the provided configuration. The initial * nodes in a cluster must always be bootstrapped. This is necessary to prevent split brain. If the provided * configuration is empty, the local server will form a single-node cluster. * <p> * Only {@link Member.Type#ACTIVE} members can be included in a bootstrap configuration. If the local server is * not initialized as an active member, it cannot be part of the bootstrap configuration for the cluster. * <p> * When the cluster is bootstrapped, the local server will be transitioned into the active state and begin * participating in the Raft consensus algorithm. When the cluster is first bootstrapped, no leader will exist. * The bootstrapped members will elect a leader amongst themselves. Once a cluster has been bootstrapped, additional * members may be {@link #join(Address...) joined} to the cluster. In the event that the bootstrapped members cannot * reach a quorum to elect a leader, bootstrap will continue until successful. * <p> * It is critical that all servers in a bootstrap configuration be started with the same exact set of members. * Bootstrapping multiple servers with different configurations may result in split brain. * <p> * The {@link CompletableFuture} returned by this method will be completed once the cluster has been bootstrapped, * a leader has been elected, and the leader has been notified of the local server's client configurations. * * @param cluster The bootstrap cluster configuration. * @return A completable future to be completed once the cluster has been bootstrapped. */ public CompletableFuture<CopycatServer> bootstrap(Address... cluster) { return bootstrap(Arrays.asList(cluster)); }
/** * Creates a set of Copycat servers. */ private List<CopycatServer> createServers(int nodes) throws Exception { List<CopycatServer> servers = new ArrayList<>(); for (int i = 0; i < nodes; i++) { members.add(nextMember(Member.Type.ACTIVE)); } CountDownLatch latch = new CountDownLatch(nodes); for (int i = 0; i < nodes; i++) { CopycatServer server = createServer(members.get(i)); server.bootstrap(members.stream().map(Member::serverAddress).collect(Collectors.toList())).thenRun(latch::countDown); servers.add(server); } latch.await(30 * nodes, TimeUnit.SECONDS); return servers; }
/** * Creates a set of Copycat servers. */ private List<CopycatServer> createServers(int nodes) throws Exception { List<CopycatServer> servers = new ArrayList<>(); for (int i = 0; i < nodes; i++) { members.add(nextMember(Member.Type.ACTIVE)); } CountDownLatch latch = new CountDownLatch(nodes); for (int i = 0; i < nodes; i++) { CopycatServer server = createServer(members.get(i)); server.bootstrap(members.stream().map(Member::serverAddress).collect(Collectors.toList())).thenRun(latch::countDown); servers.add(server); } latch.await(30 * nodes, TimeUnit.SECONDS); return servers; }
/** * Creates a set of Raft servers. */ protected List<CopycatServer> createServers(int live, int total, Resource.Config config) throws Throwable { List<Address> members = new ArrayList<>(); for (int i = 0; i < total; i++) { members.add(nextAddress()); } this.members.addAll(members); List<CopycatServer> servers = new ArrayList<>(); for (int i = 0; i < live; i++) { CopycatServer server = createServer(members.get(i), config); server.bootstrap(members).thenRun(this::resume); servers.add(server); } await(0, live); return servers; }
public ClusterNode build() { CopycatServer server = createCopyCatServer(); if(mode == JOIN_MODE.BOOTSTRAP) { server.bootstrap().join(); } else { server.join(new Address(bootstrapNode, bootstrapPort)).join(); } return new CopyCatClusterNode(server, createClient()); }
/** * Creates a set of Copycat servers. */ private List<CopycatServer> createServers(int live, int total) throws Throwable { List<CopycatServer> servers = new ArrayList<>(); for (int i = 0; i < total; i++) { members.add(nextMember(Member.Type.ACTIVE)); } for (int i = 0; i < live; i++) { CopycatServer server = createServer(members.get(i)); server.bootstrap(members.stream().map(Member::serverAddress).collect(Collectors.toList())).thenRun(this::resume); servers.add(server); } await(30000 * live, live); return servers; }
} else { System.out.println("Bootstrapping server: " + newServer.cluster().member().address()); joinFuture = newServer.bootstrap(members.stream().map(Member::serverAddress).collect(Collectors.toList()));
/** * Creates a set of Copycat servers. */ private List<CopycatServer> createServers(int nodes) throws Throwable { List<CopycatServer> servers = new ArrayList<>(); for (int i = 0; i < nodes; i++) { members.add(nextMember(Member.Type.ACTIVE)); } for (int i = 0; i < nodes; i++) { CopycatServer server = createServer(members.get(i)); server.bootstrap(members.stream().map(Member::serverAddress).collect(Collectors.toList())).thenRun(this::resume); servers.add(server); } await(30000 * nodes, nodes); return servers; }
server.serializer().register(DeleteCommand.class, 3); server.bootstrap(members).join();
/** * Tests starting several members individually. */ public void testSingleMemberStart() throws Throwable { CopycatServer server = createServers(1).get(0); server.bootstrap().thenRun(this::resume); await(5000); CopycatServer joiner1 = createServer(nextMember(Member.Type.ACTIVE)); joiner1.join(server.cluster().member().address()).thenRun(this::resume); await(5000); CopycatServer joiner2 = createServer(nextMember(Member.Type.ACTIVE)); joiner2.join(server.cluster().member().address()).thenRun(this::resume); await(5000); }