Home

Awesome

hash_ring

hex.pm version Build Status Code Coverage License: MIT

An implementation of consistent hashing algorithm.

This algorithm determines which nodes handles which items by hashing.

Consisntent hashing is suitable to manage nodes in environments in which nodes dynamically joins and leaves.

For example, if a node leaves the cluster, the items handled by the node should be reassigned to other nodes. But other items can remain in the current nodes. Thus in average case, only 1/N items are affected by the leaving (where 'N' is the number of nodes in the cluster).

See Reference for more information.

Build

To build the library for stand-alone usage:

$ git clone https://github.com/sile/hash_ring.git
$ cd hash_ring
$ rebar3 compile
$ rebar3 shell
$ > hash_ring:module_info().

If you want to use from your application:

%% In your 'rebar.config'

%% Add following lines
{deps,
 [
   hash_ring
 ]}.

Example

%% Builds a consistent hash ring
> Nodes = hash_ring:list_to_nodes([a,b,c,d,e]).
[{hash_ring_node,a,a,1},
 {hash_ring_node,b,b,1},
 {hash_ring_node,c,c,1},
 {hash_ring_node,d,d,1},
 {hash_ring_node,e,e,1}]

> Ring0 = hash_ring:make(Nodes).

%% Finds the node which handles the item
> hash_ring:find_node(item_1, Ring0).
{ok,{hash_ring_node,c,c,1}}

%% Collects four nodes in descending order of priority
> hash_ring:collect_nodes(item_1, 4, Ring0).
[{hash_ring_node,c,c,1},
 {hash_ring_node,e,e,1},
 {hash_ring_node,b,b,1},
 {hash_ring_node,d,d,1}]

%% Addition of a node
> Ring1 = hash_ring:add_node(hash_ring_node:make(g), Ring0).
> hash_ring:collect_nodes(item_1, 4, Ring1).
[{hash_ring_node,c,c,1},
 {hash_ring_node,e,e,1},
 {hash_ring_node,b,b,1},
 {hash_ring_node,g,g,1}] % The fourth node is changed from 'd' to 'g'

%% Removal of a node
> Ring2 = hash_ring:remove_node(c, Ring1).
> hash_ring:collect_nodes(item_1, 4, Ring2).
[{hash_ring_node,e,e,1}, % 'c' is removed but the remaining order is unchanged
 {hash_ring_node,b,b,1},
 {hash_ring_node,g,g,1},
 {hash_ring_node,d,d,1}]

API

See EDoc Documents

Reference

Benchmark

A simple benchmark result for a 500 nodes ring.

Environment

Result

A result of hash_ring_bench:bench(500, []).

Toal Time and Heap Size

modulemake_timeadd_timeremove_timefind_timeheap_size
hash_ring_static178 ms7166 ms2162 ms0.722 ms1406 KB
hash_ring_dynamic396 ms381 ms367 ms1.141 ms6191 KB

Average Time per Node (or Item)

moduleadd_timeremove_timefind_time
hash_ring_static14.332 ms4.323 ms0.00144 ms
hash_ring_dynamic0.762 ms0.734 ms0.00228 ms

License

This library is released under the MIT License. See the LICENSE file for full license information.