etcd-leader
v0.0.1
Published
Etcd leader election for Node.js
Downloads
3
Readme
etcd-leader
Under development, not yet suitable for production use.
Leader election module built on a robust election algorithm, and extremely thoroughly tested.
Usage
Expects a configured node-etcd client to be provided. Note that this package does not depend on node-etcd. It is compatible with the ^4.0.0
version of node-etcd.
var Etcd = require("node-etcd");
var etcdLeader = require("etcd-leader");
var etcd = new Etcd("localhost", 4001);
// First parameter is etcd key to use for election.
// Second parameter is name of this node.
// Third parameter is the expiry window for master election.
var election = etcdLeader(etcd, "/master", "foo", 10).start();
election.on("elected", function() {
console.log("I am the MASTER.");
});
election.on("unelected", function() {
console.log("I am no longer the MASTER.");
});
election.on("leader", function(node) {
console.log("Leader is now " + node);
});
Algorithm
The leader election algorithm here is based on top of the atomic in-order insertion strategy documented by ZooKeeper.
How do we do this specifically in etcd?
- POST to
/leader/key
to perform atomic insertion of this node's membership. - GET
/leader/key?sorted=true
to read back out the current membership info. - If our membership is lowest sorted entry, this node is elected master.
- Otherwise, use etcd to watch the entry sorted immediately before this node, waiting for it to drop off. If it does, start from step 2.
- Perdiodically (TTL divided by 2) refresh our membership key to ensure it stays active.
Walk me through it
Let's assume we have initialised etcd-leader to use /master
as the master key, and we have three nodes, with node names foo
, bar
and quux
respectively.
foo
starts up first, it issues aPOST
to/master
(with a TTL of 10 seconds). It gets a createdIndex of "5".foo
begins refreshing its value every 5 seconds.foo
enumerates/master
to find lowest sorted createdIndex node. Discovers that it's itself.foo
is now master.bar
starts up next, it also issues aPOST
to/master
. It gets a createdIndex of "7".bar
begins refreshing its value every 5 seconds.bar
enumerates/master
, sees thatfoo
is the lowest createdIndex. Starts watching that node, waiting for it to disappear.quux
starts up, issues the POST and gets a createdIndex of "9".quux
begins refreshing its value every 5 seconds.quux
enumerates/master
, sees thatfoo
is the lowest createdIndex, and thatbar
is the node that immediately preceeds it.quux
starts watchingbar
's node for changes, waiting for it to disappear.