JGroups: Leader election without additional infrastructure

Datetime:2016-08-23 03:10:14          Topic:          Share

Hi there,

in this post I’ll show how you can solve the problem of leader election without using any additional infrastructure like Apache Zookeeper or Consul .

Leader election is a common way to solve the problem that in a distributed system only one instance must do a particular job.

This could be for example

  • triggering scheduled jobs
  • coordinating connection establishment, when the system acts as a client towards external systems
  • running clean up tasks

Usually this is solved by employing the mentioned, or similar, infrastructure. But there is an alternative, if you don’t want to introduce them to your system landscape: JGroups .

JGroups is a

toolkit for reliable messaging. It can be used to create clusters whose nodes can send messages to each other.[http://jgroups.org/]

With JGroups setting up leader election can be done fairly easy by using the View concept of JGroups.

Views are actual, guess what, views on the state of a cluster. As each cluster has exactly one coordinator, which is the first member of the list of members in a view, this one can be interpreted as the leader of the cluster.

If the leader dies/is restarted/is faulty, the next member in the list becomes the new leader. This is a very handy and deterministic approach.

Example

Let’s have a look on some very simple code, that demonstrates this:

public class JGroupsLeaderElectionExample {
 
  private static final int MAX_ROUNDS = 1_000;
  private static final int SLEEP_TIME_IN_MILLIS = 1000;
 
  public static void main(String[] args) throws Exception {
    JChannel channel = new JChannel();
    channel.connect("The Test Cluster");
    for (int round = 0; round < MAX_ROUNDS; round++) {
      checkLeaderStatus(channel);
      sleep();
    }
 
    channel.close();
  }
 
  private static void sleep() {
    try {
      Thread.sleep(SLEEP_TIME_IN_MILLIS);
    } catch (InterruptedException e) {
      // Ignored
    }
  }
 
  private static void checkLeaderStatus(JChannel channel) {
    View view = channel.getView();
    Address address = view.getMembers()
                          .get(0);
    if (address.equals(channel.getAddress())) {
      System.out.println("I'm (" + channel.getAddress() + ") the leader");
    } else {
      System.out.println("I'm (" + channel.getAddress() + ") not the leader");
    }
  }
}

The above code, creates a new JChannel with the default stack settings. The stack can also be configured by using either an XML file or the programmatic approach.

Then the channel is connected to The Test Cluster . JGroups discovers the cluster by broadcasting on connect. If the current instance is first, it creates the cluster.

In the loop the code now just get’s the actual view from the channel and checks if the actual instance is also the first member or not. As you remember the first member can be treated as the leader.

If you now start multiple instances and stop the first one, the second will take over. Like in this example:

-------------------------------------------------------------------
GMS: address=Ygdrassil-21922, cluster=The Test Cluster, physical address=2003:4e:a904:2d67:55c:2653:7e28:8634:59721
-------------------------------------------------------------------
I'm (Ygdrassil-21922) the leader
I'm (Ygdrassil-21922) the leader
I'm (Ygdrassil-21922) the leader
I'm (Ygdrassil-21922) the leader
-------------------------------------------------------------------
GMS: address=Ygdrassil-57947, cluster=The Test Cluster, physical address=2003:4e:a904:2d67:55c:2653:7e28:8634:59724
-------------------------------------------------------------------
I'm (Ygdrassil-57947) not the leader
I'm (Ygdrassil-57947) not the leader
I'm (Ygdrassil-57947) not the leader
I'm (Ygdrassil-57947) not the leader
I'm (Ygdrassil-57947) not the leader
I'm (Ygdrassil-57947) the leader
I'm (Ygdrassil-57947) the leader

As usual the code can be found on my GitHub Account .

Summary

In this article we’ve seen how to setup a leader election without the introduction of any additional infrastructure. JGroups provides a lot more interesting things, like distributed counters, distributed task execution, and so on.