Interface ElectionService
-
- All Superinterfaces:
Service
@DefaultServiceFactory(ElectionServiceFactory.class) public interface ElectionService extends Service
« start hereMain entry point to leader election API.Overview
This service provides support for electing a leader among a set of cluster nodes that belong to the same election group. This service guarantees that only one node within each group will be elected as a leader and all other nodes will become followers. If leader node goes down or decides to yield its leadership then some other node will be elected as a new leader.
In order to participate in leader election process, each node must
register
an implementation of theCandidate
interface and specify itsgroup name
. Each node can register candidates to multiple groups andElectionService
will make sure that only one node within each group will become a leader.Service Configuration
ElectionService
can be registered and configured inHekateBootstrap
with the help ofElectionServiceFactory
as shown in the example below:// Prepare service factory. ElectionServiceFactory factory = new ElectionServiceFactory() // Register candidate. .withCandidate(new CandidateConfig() // Group name. .withGroup("example.election.group") // Candidate implementation. .withCandidate(new ExampleCandidate()) ); // Start node. Hekate hekate = new HekateBootstrap() .withService(factory) .join(); // Access the service. ElectionService election = hekate.election();
Note: This example requires Spring Framework integration (see HekateSpringBootstrap).<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.hekate.io/spring/hekate-core" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.hekate.io/spring/hekate-core http://www.hekate.io/spring/hekate-core.xsd"> <h:node id="hekate"> <!-- Leader election service. --> <h:election> <!-- Register leader election candidate. --> <h:candidate group="example.election.group"> <bean class="foo.bar.SomeCandidate"/> </h:candidate> </h:election> <!-- ...other services... --> </h:node> </beans>
Note: This example requires Spring Framework integration (see HekateSpringBootstrap).<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="hekate" class="io.hekate.spring.bean.HekateSpringBootstrap"> <property name="services"> <list> <!-- Leader election service. --> <bean class="io.hekate.election.ElectionServiceFactory"> <property name="candidates"> <list> <!-- Register leader election candidate. --> <bean class="io.hekate.election.CandidateConfig"> <property name="group" value="example.election.group"/> <property name="candidate"> <bean class="foo.bar.SomeCandidate"/> </property> </bean> </list> </property> </bean> <!-- ...other services... --> </list> </property> </bean> </beans>
Leader Election
Leader election process starts right after the node joins the cluster. If leader has been already elected by that time then
Candidate
switches to thefolower
state. If this is the first node in the election group thenCandidate
switches to theleader
state. If multiple nodes are joining the cluster at the same time then only one of them will be elected as a leader and all other nodes will switch to the follower state.If
Candidate
won elections and became a group leader then it will remain in this state until its cluster node isstopped
or until it yields its leadership by callingLeaderContext.yieldLeadership()
. In the first case some other node will be elected as a new leader and will be notified viaCandidate.becomeLeader(LeaderContext)
method. In the second case leadership will be withdrawn and with high probability some other node will become a new leader. If no other node could win elections then the same node will become leader again and itsCandidate.becomeLeader(LeaderContext)
method will be called.When
Candidate
switches to the follower state then it can optionally register a leader change listener viaFollowerContext.addListener(LeaderChangeListener)
. This listener will be notified every time when leadership gets transferred from one remote node to another remote node.Below is the example of
Candidate
interface implementation:class ExampleCandidate implements Candidate { @Override public void becomeLeader(LeaderContext ctx) { System.out.println("I'm leader."); // ...do some work as leader... System.out.println("Done with the leader task ...will yield leadership."); // Let some other node to become a leader. ctx.yieldLeadership(); } @Override public void becomeFollower(FollowerContext ctx) { System.out.println("Leader: " + ctx.leader()); // Listen for leader change events while we are staying in the follower state. ctx.addListener(changed -> System.out.println("Leader changed: " + changed.leader()) ); } @Override public void terminate() { // ...cleanup logic... } }
Leader Election Details
Leader elections are based on the
LockService
capabilities. During the startupElectionService
tries to asynchronously acquire a distributed lock for each of its registered groups. If lock acquisition is successful thenCandidate
of such group gets notified on becoming a leader. If lock is busy thenCandidate
get notified on becoming a follower and continues to await for the lock to be acquired.- See Also:
ElectionServiceFactory
-
-
Method Summary
All Methods Instance Methods Abstract Methods Modifier and Type Method Description LeaderFuture
leader(String group)
Returns a future object that can be used to get the current leader of the specified group.
-
-
-
Method Detail
-
leader
LeaderFuture leader(String group) throws IllegalStateException
Returns a future object that can be used to get the current leader of the specified group.- Parameters:
group
- Group name (seeCandidateConfig.setGroup(String)
).- Returns:
- Future object for getting the current leader.
- Throws:
IllegalStateException
- If service is stopped.
-
-