Interface JGroupsRaftAdministration


@ThreadSafe public interface JGroupsRaftAdministration
Administrative operations for the Raft cluster.

This interface provides operations to manage the Raft cluster, including:

  • Trigger leader elections.
  • Add or remove Raft members.
  • Create snapshots of the state machine.
These operations are intended to be utilized during maintenance by operators. We recommend using them sparingly.

Leader Election

The Raft protocol utilizes a leader to replicate the commands in the cluster. Our implementation differs from the one described in the Raft paper. We leverage JGroups' capabilities to ensure more stable leadership. Elections are based on View updates from nodes leaving and joining the cluster. For more information, see the design documents.

This interface provides an API to trigger leader election without requiring a View update. However, note that the election procedure still adheres to the safety requirements of the Raft protocol to select a new leader. Consequently, it is possible for the previous leader to be elected again.

Dynamic Membership

The Raft protocol allows dynamic membership changes. Nodes can be added or removed from the cluster without disruptions. We implement a mechanism that performs a single membership change at a time. For example, adding two new nodes requires submitting two operations.

The same approach applies to adding or removing nodes. Membership operations must be submitted by the leader and require a quorum of nodes to agree on the configuration change. This means that membership operations are not possible if the cluster is unhealthy; extra care is needed to avoid disrupting the cluster. Consider the following points:

  • Fresh and stateless nodes can cause an availability gap in the system.

    Nodes added to the cluster without any state will need to catch up with the leader. If the quorum size changes with the new node, the cluster will not be able to make progress until the new node is fully caught up.

  • A leader removing itself from the cluster.

    In this case, the leader replicates an operation to remove itself from the cluster. The leader must replicate the operation but should not count itself in the quorum. After the operation is completed, the leader must step down.

  • A node not in the member list.

    A node can be removed from the Raft member list but still remain connected to the JGroups cluster. This node will transition to the role of learner and won't count towards quorum.

Although the Raft protocol guarantees strong consistency and safety, it is important to understand how administrative operations can affect the cluster. These operations should be used with care for maintenance.

Since:
2.0
Author:
José Bolina
See Also:
  • Method Details

    • forceLeaderElection

      CompletionStage<String> forceLeaderElection()
      Forces a new leader election, excluding the current leader from candidacy.

      This operation triggers the election mechanism without requiring a View update. The current leader is excluded from candidacy so that a different node is elected. If no leader exists at the time of the call, the election proceeds without exclusion.

      This method must be called on the JGroups view coordinator. Calling it on a non-coordinator node completes the returned stage exceptionally with IllegalStateException. Use this operation sparingly, for example, to offload leadership before removing a node from the cluster.

      The election still adheres to the Raft safety requirements: only a node with a sufficiently up-to-date log can be elected. If the excluded leader is the only node with the highest log, the election retries until another node catches. If the cluster is running below majority, the returned stage completes exceptionally. The future also completes exceptionally if the election mechanism is stopped externally (e.g., a view change stops the procedure).

      Callers can set a timeout on the returned stage. Otherwise, the election mechanism will run indefinitely. Cancelling the stage stops the election mechanism:

      administration.forceLeaderElection()
          .toCompletableFuture()
          .orTimeout(10, TimeUnit.SECONDS)
          .whenComplete((leader, err) -> {
              if (err != null) {
                  // Election timed out or failed.
              }
          });
      
      Returns:
      a stage that completes with the Raft ID of the newly elected leader.
    • addNode

      CompletionStage<Void> addNode(String raftId)
      Adds a new voting member to the Raft cluster.

      Submits a membership change that adds the given Raft ID as a voting member. The operation is replicated through the Raft log and requires a quorum of the current members to commit. The returned stage completes when the membership change is committed.

      This operation must be submitted to the leader. If a REDIRECT protocol is present in the stack, the request is forwarded automatically; otherwise, calling this on a cluster without leader completes the stage exceptionally.

      Only one membership change can be in progress at a time. Adding a node that is already a member completes the stage exceptionally. Be aware that adding a fresh, stateless node might increase the quorum size; the cluster may stall until the new node catches up with the leader's log. Consider adding the node first as learner, just joining the cluster, and then promoting it to a voting member.

      Parameters:
      raftId - the Raft identifier of the node to add. Must match the raft_id configured on the target node.
      Returns:
      a stage that completes when the membership change is committed.
    • removeNode

      CompletionStage<Void> removeNode(String raftId)
      Removes a voting member from the Raft cluster.

      Submits a membership change that removes the given Raft ID from the set of voting members. The operation is replicated through the Raft log and requires a quorum of the current members to commit. The returned stage completes when the membership change is committed.

      This operation must be submitted to the leader. If a REDIRECT protocol is present in the stack, the request is forwarded automatically; otherwise, calling this on a cluster without a leader node completes the stage exceptionally.

      Parameters:
      raftId - the Raft identifier of the node to remove.
      Returns:
      a stage that completes when the membership change is committed.
    • members

      Set<String> members()
      Returns the current set of voting members in the Raft cluster.

      The returned set reflects the committed membership configuration as known by this node. During a pending membership change, the set may not yet include a recently added node or may still include a recently removed one until the change is committed.

      Returns:
      an unmodifiable set of Raft identifiers of the current voting members.
    • snapshot

      CompletionStage<Void> snapshot()
      Triggers a snapshot of the current state machine and truncates the log.

      A snapshot captures the current state machine state and allows the log to be truncated, reclaiming storage. Snapshots are also used to bring slow or new followers up to date without replaying the entire log. Taking a snapshot means stopping all reads and writes operations happening to the state machine until the procedure completes.

      Returns:
      a stage that completes when the snapshot is done.