ketama
TypeScript icon, indicating that this package has built-in type declarations

1.0.0 • Public • Published

ketama

Actions Status

Ketama is a JavaScript/TypeScript implementation of the libketama hash ring. The primary advantage of ketama-style hashing is that it reduces the amount of work which is shuffled to other servers when the hashring membership changes.

npm install --save ketama

Then go forth with confidence:

// alternatively: const { HashRing } = require('ketama');
import { HashRing } from 'ketama';

const ring = new HashRing();

ring.addNode('127.0.0.1'); // add with default weight
ring.addNode('127.0.0.2', 2); // weight of 2 = twice as likely to choose this one

export function onDoWork(input) {
  // hashes the input and choses a server based on it:
  const server = ring.getNode(input);
  doWorkOn(server);
}

export function doWorkOnMultipleServers(input) {
  // picks two "replica" servers from the ring to do work on
  for (const server of ring.getNodes(input, 2)) {
    doWorkOn(server);
  }
}

Table of Contents

HashRing([nodes], [hashFunction])

Creates a new HashRing, optionally with the initial set of nodes. The nodes can be either a string, or an object with a string property "key" which will be used internally to hash against, for example:

new HashRing(['127.0.0.1', { key: '127.0.0.2', port: 1337 }]);

When giving the nodes in the constructor, you can specify a weight by providing an object with the node and its weight. Weights are proportional; a node with a weight of 2 is twice as likely to be chosen than one with the default weight of 1. For example:

new HashRing([
  { node: '127.0.0.1', weight: 2 },
  { node: { key: '127.0.0.2', port: 1337 }, weight: 3
]);

Finally, you can also specify the hashing function to use. This can be either the name of an algorithm the require('crypto').createHash implements, or a custom function that returns an int32 given a Buffer. Defaults to sha1. For example:

new HashRing([], 'md5'); // hash with md5 instead
new HashRing([], buf => myCustomHash().readInt32BE()); // custom function

hashRing.addNode(node[, weight])

Adds a new node to the existing hashring. The node can be either a string, or an object with a string property "key" which will be used internally to hash against.

ring.addNode('127.0.0.1');
ring.addNode({ key: '127.0.0.2', port: 1337 });

You can optionally specify a weight as the second argument. Weights are proportional; a node with a weight of 2 is twice as likely to be chosen than one with the default weight of 1.

If the node already exists, it is replaced; for example, you can call addNode multiple times to update a node's weight.

hashRing.removeNode(node)

Removes a node previously added to the hash ring.

ring.removeNode('127.0.0.1');

No-op if the node is not in the ring.

hashRing.getNode(input)

Gets the node on which work should be done for the given input, which should be either a string or buffer. Returns the object or string originally given to addNode or new HashRing(), or returns undefined if the ring is empty.

const server = ring.getNode(inputData);
doWorkOn(server);

hashRing.getNodes(input, replicas)

Gets the "replicas" number of nodes that should handle the input, which should be either a string or buffer. The returned array length wiill equal the number of replicas, except if there are fewer nodes available than replicas requested, in which case all nodes are returned.

for (const server of ring.getNodes(input, 2)) {
  doWorkOn(server);
}

Package Sidebar

Install

npm i ketama

Weekly Downloads

170

Version

1.0.0

License

MIT

Unpacked Size

39.8 kB

Total Files

16

Last publish

Collaborators

  • connor.peet