I’ve been kicking the tires of the libring
package to help distribute work/data across multiple nodes in a deterministic way.
Given a ring like so:
iex> ring = HashRing.new()
|> HashRing.add_node(:a@localhost)
|> HashRing.add_node(:b@localhost)
#<Ring[:b@localhost, :a@localhost]>
You can ask it which n
nodes a given key should map to, e.g.
iex> HashRing.key_to_nodes(ring, 13, 2)
[:a@localhost, :b@localhost]
But what’s strange is that certain numbers seem to cause problems. For example, the lucky number 14
comes out with only ONE node assigned to it instead of the 2
that were asked for:
iex> HashRing.key_to_nodes(ring, 14, 2)
[:a@localhost]
But more curious is that the problematic keys seem to be related to the names of the hosts, e.g. using hostnames :a
and :b
works as expected:
iex> ring2 = HashRing.new() |> HashRing.add_node(:a) |> HashRing.add_node(:b)
#<Ring[:a, :b]>
iex> HashRing.key_to_nodes(ring2, 14, 2)
[:b, :a]
The docs say that “Will return either count
results or the number of nodes, depending on which is smaller.”, but this seems to not be the case with the lucky number 14
.
Can someone explain this? This is easy enough to avoid by wrapping calls to HashRing.key_to_nodes/3
to return all nodes when the count
is equal to the number of available nodes, but it sure caught me by surprise!