Skip to content
Tech News
← Back to articles

Highest Random Weight in Elixir

read original get Elixir Random Weight Module → more articles
Why This Matters

This article highlights Rendezvous hashing (HRW) as a simpler, stateless alternative to traditional consistent hashing libraries like ExHashRing in Elixir. Its ease of use and minimal setup make it appealing for distributed systems, though its linear complexity may limit scalability with larger node lists. This development offers the tech industry a more straightforward method for key distribution in distributed applications, benefiting both developers and system performance.

Key Takeaways

Consistent hashing is a common building block for distributed Elixir and enables fairly low complexity and high value design patterns, like the distributed rate limiter or cache. I’ve written about it before.

The most common way of assigning keys to nodes, ensuring that any node participating in the cluster can figure out which node owns the given key, is Discord’s ExHashRing. This is an incredibly battle-tested and reliable library with excellent performance characteristics, and I’ve only had good experiences with it.

That said, it does have a downside. You have to start and manage the ring processes. It’s not a huge downside, you can give them global names and it’s trivial to look them up, but you still want them set up under your supervision tree and they are stateful persistent things that hang around. That state has to be managed. It’s not a big deal at all, but when I found a stateless alternative it did immediately catch my attention.

Rendezvous hashing

As described by the Wikipedia page: Rendezvous hashing is both much simpler and more general than consistent hashing. Also called HRW or Highest Random Weight. In practice, you can use it very much like you would ExHashRing.

ExHashRing example.

{ :ok , ring } = ExHashRing.Ring . start_link ( ) Ring . add_nodes ( ring , [ "a" , "b" , "c" ] ) Ring . find_node ( ring , "key1" ) => "b"

HRW example.

HRW . owner ( "key1" , [ "a" , "b" , "c" ] ) => "b"

That’s it. No stateful process, no setup. Just pure functional programming with inputs and outputs. Consistent across multiple machines. Avoids unnecessary drift when changing the list of nodes. You can see why it caught my eye!

... continue reading