fredag 13 september 2013

Leader election in a cluster using Hazelcast

In my cluster I wanted to have just one node performing a scheduled task recurringly, and if that node went down I wanted some other node to take over the responsibility automatically.

My setup was a Spring-enabled server that used Hazelcast as a datagrid for the caching of various data structures (but also to act as 2nd level cache for Hibernate). So the idea was to use Hazelcast for leader election, since the Hazelcast cluster automagically will grow/shrink as the size of my cluster changed and thus Hazelcast will always know the size of the cluster and its members.

So is there a simple way through which we can use Hazelcast for leader election?

/**
 * Leader election is the process of designating a
 * single node as the organizer of some distributed
 * task among several nodes in the cluster.
 *
 * @author Andreas Lindfalk
 */
public interface LeaderElection {

  /**
  * Get whether this node is the leader
  * in the cluster or not.
  *
  * @return {@code true} if it is this node
  * that is the leader, else {@code false}
  */
  boolean isLeader();
}


The implementation simply selects the oldest member in the Hazelcast cluster as the leader, and this code will check if the current node is in fact that oldest and therefore leading node:

/**
 * A simple leader election implementation based on
 * a Hazelcast cluster that simply elects the oldest
 * member in the cluster as the leader.
 * 
 * @author Andreas Lindfalk
 */

@Component
public class HazelcastLeaderElection
  implements LeaderElection {

  @Resource
  private HazelcastInstance instance;

  /**
  * {@inheritDoc}
  */
  @Override
  public boolean isLeader() {

  // The first member in the set is the
  // oldest member, this is the one that
  // we always will point out as leader

  Member oldestMember = instance.getCluster()

            .getMembers().iterator().next();

  return oldestMember.localMember();
  }
}


So now in the scheduled and recurring task I can now check whether the current node is the leader in the cluster or not, and based on this either proceed and perform the task or step back and let the leader take care of it.

@Component
public class WeatherSchedulerImpl
    implements WeatherScheduler {

    @Resource
    private LeaderElection leaderElection;

    /**
     * {@inheritDoc}
     */
    @Override
    @Scheduled(
        initialDelayString = "10000",
        fixedDelayString = "900000")
    public void retrieveWeather() {

        if (leaderElection.isLeader()) {
            // Fetch the weather data...
        }
    }
}

Inga kommentarer:

Skicka en kommentar