← Runnable Projects

阅读中文版本

Consistent Hash CLI

A Node CLI that builds a consistent hash ring from a node list and routes keys to nodes, demonstrating minimal remapping on node add or remove.

intermediatejavascriptunverified

Project

node-consistent-hash-cli

Entry point: chash.mjs

Install

node --version

Run

node chash.mjs "a,b,c" key1 key2 key3

Test

node --test chash.test.mjs

Expected output

Prints the node that each key maps to on the consistent hash ring built from the comma-separated node list.

Dependencies

  • node >=20

What it does

Builds a consistent hash ring from a comma-separated node list, using 100 virtual nodes per physical node for balance. Each key is hashed and routed to the first node clockwise on the ring via binary search. The virtual nodes spread each physical node across the ring so the distribution is balanced.

import { createHash } from 'node:crypto';
const nodes = process.argv[2].split(',');
const keys = process.argv.slice(3);
const V = 100;
const ring = [];
for (const n of nodes) for (let i = 0; i < V; i++) ring.push([+('0x' + createHash('sha256').update(n + ':' + i).digest().readBigUInt64BE().toString()), n]);
ring.sort((a, b) => a[0] < b[0] ? -1 : 1);
const route = k => {
  const h = +('0x' + createHash('sha256').update(k).digest().readBigUInt64BE().toString());
  let lo = 0, hi = ring.length;
  while (lo < hi) { const mid = (lo + hi) >> 1; if (ring[mid][0] < h) lo = mid + 1; else hi = mid; }
  return ring[lo % ring.length][1];
};
keys.forEach(k => console.log(k + ' -> ' + route(k)));

Run and verify

node chash.mjs "a,b,c" hello world foo

Run the test command to check the implementation: node --test chash.test.mjs.

Expected Output

Each key is mapped to a node on the ring:

hello -> b
world -> a
foo -> c

The exact mapping depends on the hash values but is deterministic for the same node list and keys.

Limitations

The ring is rebuilt on every run, so it is a demonstration. The virtual node count is fixed at 100; a higher count improves balance at the cost of a larger ring.