Skip to content

Step 1 of 5 · Reading · ~3 min

Read

Production

Putting It All Together

You have built every piece of a consistent-hashing router separately. In this lesson you assemble them into one program: a weighted ring that places keys, lists replicas, changes weights, and reports exactly which keys move when membership changes.

PieceWhere you built it
Why modulo fails, the K/N goalWhy Consistent Hashing?
Clockwise successor with wrap-aroundThe Hash Ring
Many points per node, a hash that mixesVirtual Nodes
Who moves when membership changesRebalance on Add/Remove
Points proportional to weight, gradual drainWeighted Ring
Preference lists of distinct nodesReplication on the Ring

The result is the same feature set as memcached's ketama ring (weights included) plus the replication rule that Cassandra and Riak layer on top of theirs.

One structure, four rules

The program keeps one sorted list of (position, node) entries and a record of each node's point count. Everything else is a rule applied to that list.

  • Placement. A node of weight w places 128 * w points at h32(name + "#" + i). A key belongs to the first entry at or after h32(key), wrapping at the end.
  • Replication. Walk clockwise from the key and collect distinct node names. Weights never enter the walk: a heavy node is the primary more often, but it appears at most once in any list.
  • Reweighting. SETWEIGHT removes the node's points and places new ones with the same labels, which gives the same ring as if the node had been added with that weight.
  • Measuring. Track a set of keys, change something, then diff the owners.

Here is the measurement on a ring that none of the earlier lessons used: P (weight 1), Q (3), R (1), S (2), with 4,000 tracked keys. Lowering Q to weight 1 and then raising it to 3 again:

SETWEIGHT Q 1          SETWEIGHT Q 3
Q -> P: 217            P -> Q: 217
Q -> R: 276            R -> Q: 276
Q -> S: 455            S -> Q: 455
moved=948/4000         moved=948/4000

Every key that moved left Q on the way down and returned on the way up, because the labels are the same both ways. The ring holds 896 points (7 units of weight times 128).

Composition traps

Removal must erase every point. A weight-2 node owns 256 points. Leave one behind and it still wins lookups for its arc, which is why POINTS is in the command set.

A node with weight 0 is still a node. It has no points, so it is never a primary or a replica, but WEIGHTS, LOAD and SPREAD list it with a zero. A ring where every weight is 0 answers NONE.

The default weight is 1. A bare ADD_NODE A places 128 points, not zero and not a crash. Adding a name that exists changes nothing and prints EXISTS, even if a different weight is given.

Unknown names. REMOVE_NODE and SETWEIGHT on a name that is not on the ring print UNKNOWN.

What separates this from production

A real hash (MD5 or MurmurHash3 across the whole key), persistence of ring state across restarts, rack-aware replica placement, streaming of data alongside ownership, and agreement between clients (gossip or a config service) so that every client builds the same ring. Without that last item two clients route the same key to different owners.

The next three lessons replace the ring when its trade-offs pinch: jump hash (no memory, buckets numbered 0..N-1), Maglev (a precomputed table for line-rate lookups) and bounded loads (the ring plus a hard cap per node). The ring with vnodes stays the right default because it handles named nodes, arbitrary adds and removes, weights and replication with a single structure.

Your exercise

The starter gives you h32 and the command loop. You implement the ring, the replica walk, the reports and the diff, using what the previous lessons taught.

Up nextJump Consistent HashModern Algorithms

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…