public interface RaftCluster
This class provides the view of the Raft cluster from the perspective of a single server. When a
RaftServer is started, the server will form a cluster
with other servers. Each Raft cluster consists of some set of members, and each
RaftMember represents a single server in the cluster. Users can use the Cluster to react to
state changes in the underlying Raft algorithm via the various listeners.
server.cluster().onJoin(member -> {
System.out.println(member.address() + " joined the cluster!");
});
Membership exposed via this interface is provided from the perspective of the local server and may not
necessarily be consistent with cluster membership from the perspective of other nodes. The only consistent
membership list is on the leader node.
Cluster to manage the Raft cluster membership. Typically, servers join the
cluster by calling RaftServer.bootstrap(MemberId...) or join(MemberId...),
but in the event that a server fails permanently and thus cannot remove itself, other nodes can remove arbitrary servers.
server.cluster().onJoin(member -> {
member.remove().thenRun(() -> System.out.println("Removed " + member.address() + " from the cluster!"));
});
When a member is removed from the cluster, the configuration change removing the member will be replicated to all
the servers in the cluster and persisted to disk. Once a member has been removed, for that member to rejoin the cluster
it must fully restart and request to rejoin the cluster. For servers configured with a persistent
StorageLevel, cluster configurations are stored on disk.
Additionally, members can be promoted and demoted by any
other member of the cluster. When a member state is changed, a cluster configuration change request is sent
to the cluster leader where it's logged and replicated through the Raft consensus algorithm. During
the configuration change, servers' cluster configurations will be updated. Once the configuration change is
complete, it will be persisted to disk on all servers and is guaranteed not to be lost even in the event of a
full cluster shutdown (assuming the server uses a persistent StorageLevel).
| Modifier and Type | Method and Description |
|---|---|
void |
addLeaderElectionListener(Consumer<RaftMember> listener)
Adds a listener to be called when a leader is elected.
|
void |
addListener(RaftClusterEventListener listener)
Registers a callback to be called when a member leaves the cluster.
|
CompletableFuture<Void> |
bootstrap(Collection<MemberId> cluster)
Bootstraps the cluster.
|
default CompletableFuture<Void> |
bootstrap(MemberId... cluster)
Bootstraps the cluster.
|
RaftMember |
getLeader()
Returns the current cluster leader.
|
RaftMember |
getMember()
Returns the local cluster member.
|
RaftMember |
getMember(MemberId id)
Returns a member by ID.
|
Collection<RaftMember> |
getMembers()
Returns a collection of all cluster members.
|
long |
getTerm()
Returns the current cluster term.
|
CompletableFuture<Void> |
join(Collection<MemberId> cluster)
Joins the cluster.
|
default CompletableFuture<Void> |
join(MemberId... cluster)
Joins the cluster.
|
CompletableFuture<Void> |
leave()
Leaves the cluster.
|
CompletableFuture<Void> |
listen(Collection<MemberId> cluster)
Joins the cluster as a listener.
|
default CompletableFuture<Void> |
listen(MemberId... cluster)
Joins the cluster as a listener.
|
void |
removeLeaderElectionListener(Consumer<RaftMember> listener)
Removes a leader election listener from the cluster.
|
void |
removeListener(RaftClusterEventListener listener)
Removes a listener from the cluster.
|
RaftMember getLeader()
If no leader has been elected for the current term, the leader will be null.
Once a leader is elected, the leader must be known to the local server's configuration. If the returned
RaftMember is null then that does not necessarily indicate that no leader yet exists for the
current term, only that the local server has not learned of a valid leader for the term.
null if no leader is known for the current term.long getTerm()
The term is representative of the epoch determined by the underlying Raft consensus algorithm. The term is a monotonically
increasing number used by Raft to represent a point in logical time. If the cluster is persistent (i.e. all servers use a persistent
StorageLevel), the term is guaranteed to be unique and monotonically increasing even across
cluster restarts. Additionally, for any given term, Raft guarantees that only a single leader can be elected.
void addLeaderElectionListener(Consumer<RaftMember> listener)
The provided callback will be called when a new leader is elected for a term. Because Raft ensures only a single leader
can be elected for any given term, each election callback will be called at most once per term. However, note that a leader may
not be elected for a term as well.
server.cluster().onLeaderElection(member -> {
System.out.println(member.address() + " elected for term " + server.cluster().term());
});
The RaftMember provided to the callback represents the member that was elected leader. Raft guarantees that this member is
a member of the RaftCluster. When a leader election callback is called, the correct getTerm() for the leader is guaranteed
to have already been set. Thus, to get the term for the provided leader, simply read the cluster getTerm().listener - The listener to be called when a new leader is elected.void removeLeaderElectionListener(Consumer<RaftMember> listener)
listener - The leader election listener to remove.RaftMember getMember()
RaftMember getMember(MemberId id)
The returned RaftMember is referenced by the unique RaftMember.memberId().
id - The member ID.null if no member with the given id exists.Collection<RaftMember> getMembers()
The returned members are representative of the last configuration known to the local server. Over time,
the cluster configuration may change. In the event of a membership change, the returned Collection
will not be modified, but instead a new collection will be created. Similarly, modifying the returned
collection will have no impact on the cluster membership.
default CompletableFuture<Void> bootstrap(MemberId... cluster)
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.
Only RaftMember.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.
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 joined to the cluster. In the event that the bootstrapped members cannot
reach a quorum to elect a leader, bootstrap will continue until successful.
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.
The 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.
cluster - The bootstrap cluster configuration.CompletableFuture<Void> bootstrap(Collection<MemberId> cluster)
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.
Only RaftMember.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.
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 joined to the cluster. In the event that the bootstrapped members cannot
reach a quorum to elect a leader, bootstrap will continue until successful.
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.
The 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.
cluster - The bootstrap cluster configuration.default CompletableFuture<Void> listen(MemberId... cluster)
Joining the cluster results in the local server being added to an existing cluster that has already been bootstrapped. The provided configuration will be used to connect to the existing cluster and submit a join request. Once the server has been added to the existing cluster's configuration, the join operation is complete.
Any type of server may join a cluster. In order to join a cluster, the provided list of
bootstrapped members must be non-empty and must include at least one active member of the cluster. If no member
in the configuration is reachable, the server will continue to attempt to join the cluster until successful. If
the provided cluster configuration is empty, the returned CompletableFuture will be completed exceptionally.
When the server joins the cluster, the local server will be transitioned into its initial state as defined by
the configured RaftMember.Type. Once the server has joined, it will immediately begin participating in
Raft and asynchronous replication according to its configuration.
It's important to note that the provided cluster configuration will only be used the first time the server attempts
to join the cluster. Thereafter, in the event that the server crashes and is restarted by joining the cluster
again, the last known configuration will be used assuming the server is configured with persistent storage. Only when
the server leaves the cluster will its configuration and log be reset.
In order to preserve safety during configuration changes, Raft leaders do not allow concurrent configuration
changes. In the event that an existing configuration change (a server joining or leaving the cluster or a
member being promoted or demoted) is under way, the local
server will retry attempts to join the cluster until successful. If the server fails to reach the leader,
the join will be retried until successful.
cluster - A list of cluster member addresses to join.CompletableFuture<Void> listen(Collection<MemberId> cluster)
Joining the cluster results in the local server being added to an existing cluster that has already been bootstrapped. The provided configuration will be used to connect to the existing cluster and submit a join request. Once the server has been added to the existing cluster's configuration, the join operation is complete.
Any type of server may join a cluster. In order to join a cluster, the provided list of
bootstrapped members must be non-empty and must include at least one active member of the cluster. If no member
in the configuration is reachable, the server will continue to attempt to join the cluster until successful. If
the provided cluster configuration is empty, the returned CompletableFuture will be completed exceptionally.
When the server joins the cluster, the local server will be transitioned into its initial state as defined by
the configured RaftMember.Type. Once the server has joined, it will immediately begin participating in
Raft and asynchronous replication according to its configuration.
It's important to note that the provided cluster configuration will only be used the first time the server attempts
to join the cluster. Thereafter, in the event that the server crashes and is restarted by joining the cluster
again, the last known configuration will be used assuming the server is configured with persistent storage. Only when
the server leaves the cluster will its configuration and log be reset.
In order to preserve safety during configuration changes, Raft leaders do not allow concurrent configuration
changes. In the event that an existing configuration change (a server joining or leaving the cluster or a
member being promoted or demoted) is under way, the local
server will retry attempts to join the cluster until successful. If the server fails to reach the leader,
the join will be retried until successful.
cluster - A collection of cluster member addresses to join.default CompletableFuture<Void> join(MemberId... cluster)
Joining the cluster results in the local server being added to an existing cluster that has already been bootstrapped. The provided configuration will be used to connect to the existing cluster and submit a join request. Once the server has been added to the existing cluster's configuration, the join operation is complete.
Any type of server may join a cluster. In order to join a cluster, the provided list of
bootstrapped members must be non-empty and must include at least one active member of the cluster. If no member
in the configuration is reachable, the server will continue to attempt to join the cluster until successful. If
the provided cluster configuration is empty, the returned CompletableFuture will be completed exceptionally.
When the server joins the cluster, the local server will be transitioned into its initial state as defined by
the configured RaftMember.Type. Once the server has joined, it will immediately begin participating in
Raft and asynchronous replication according to its configuration.
It's important to note that the provided cluster configuration will only be used the first time the server attempts
to join the cluster. Thereafter, in the event that the server crashes and is restarted by joining the cluster
again, the last known configuration will be used assuming the server is configured with persistent storage. Only when
the server leaves the cluster will its configuration and log be reset.
In order to preserve safety during configuration changes, Raft leaders do not allow concurrent configuration
changes. In the event that an existing configuration change (a server joining or leaving the cluster or a
member being promoted or demoted) is under way, the local
server will retry attempts to join the cluster until successful. If the server fails to reach the leader,
the join will be retried until successful.
cluster - A list of cluster member addresses to join.CompletableFuture<Void> join(Collection<MemberId> cluster)
Joining the cluster results in the local server being added to an existing cluster that has already been bootstrapped. The provided configuration will be used to connect to the existing cluster and submit a join request. Once the server has been added to the existing cluster's configuration, the join operation is complete.
Any type of server may join a cluster. In order to join a cluster, the provided list of
bootstrapped members must be non-empty and must include at least one active member of the cluster. If no member
in the configuration is reachable, the server will continue to attempt to join the cluster until successful. If
the provided cluster configuration is empty, the returned CompletableFuture will be completed exceptionally.
When the server joins the cluster, the local server will be transitioned into its initial state as defined by
the configured RaftMember.Type. Once the server has joined, it will immediately begin participating in
Raft and asynchronous replication according to its configuration.
It's important to note that the provided cluster configuration will only be used the first time the server attempts
to join the cluster. Thereafter, in the event that the server crashes and is restarted by joining the cluster
again, the last known configuration will be used assuming the server is configured with persistent storage. Only when
the server leaves the cluster will its configuration and log be reset.
In order to preserve safety during configuration changes, Raft leaders do not allow concurrent configuration
changes. In the event that an existing configuration change (a server joining or leaving the cluster or a
member being promoted or demoted) is under way, the local
server will retry attempts to join the cluster until successful. If the server fails to reach the leader,
the join will be retried until successful.
cluster - A collection of cluster member addresses to join.CompletableFuture<Void> leave()
Invocations of this method will cause the local RaftServer to leave the cluster.
This method is for advanced usage only. Typically, users should use RaftServer.leave()
to leave the cluster and close a server in order to ensure all associated resources are properly closed.
When a server leaves the cluster, the server submits a LeaveRequest
to the cluster leader. The leader will replicate and commit the configuration change in order to remove the
leaving server from the cluster and notify each member of the leaving server.
In order to preserve safety during configuration changes, Raft leaders do not allow concurrent configuration
changes. In the event that an existing configuration change (a server joining or leaving the cluster or a
member being promoted or demoted) is under way, the local
server will retry attempts to leave the cluster until successful. The server will continuously attempt to
leave the cluster until successful.
void addListener(RaftClusterEventListener listener)
The registered callback will be called whenever an existing RaftMember leaves the cluster. Membership
changes are sequentially consistent, meaning each server in the cluster will see members leave in the same
order, but different servers may see members leave at different points in time. Users should not in any case
assume that because one server has seen a member leave the cluster all servers have.
listener - The listener to be called when a member leaves the cluster.void removeListener(RaftClusterEventListener listener)
listener - The listener to remove from the cluster.Copyright © 2013–2017. All rights reserved.