v0.1.0
First release.
Maglev consistent hashing, following section 3.4 of Eisenbud et al., Maglev: A Fast and Reliable Software Network Load Balancer (NSDI '16).
A Maglev table gives every backend an almost equal share of a fixed-size slot table, and keeps most keys pointing at the same backend when the backend set changes. Lookups are a single tuple index, independent of the number of backends.
Highlights
- Distribution within one slot. Every backend claims either
div(size, count)ordiv(size, count) + 1slots, whatever the table size. - Weighted backends. Integer weights, so the arithmetic assigning slots is exact and independently configured nodes cannot diverge on rounding.
- Independent of input order. Backends are sorted by encoded key before construction, so a given set yields one table however it arrives. The published algorithm fills slots in index order, which would otherwise let two nodes reading the same set from service discovery disagree about every key.
- Callable from Erlang. Plain functions over a struct; options are proplists.
Performance
Measured at 1000 backends and a 65537-slot table:
| Operation | Cost |
|---|---|
| Build | 19.0 ms, 1.00 MB |
lookup/2 |
~43 ns |
lookup_index/2 |
~21 ns |
The fill runs over :atomics, which measures 3.9x faster and uses 44x less memory than a map-based equivalent. A map implementation is retained as the behavioural definition, with an equivalence property checking the two agree slot for slot.
Verification
The guarantees stated in the paper are encoded as property tests rather than fixed examples: slot counts differing by at most one, completeness, order independence, and agreement with the worked example in table 1. Table movement under backend removal replicates figure 12.
Full coverage, dialyzer clean, tested on Elixir 1.14/OTP 25, 1.16/OTP 26 and 1.19/OTP 27.
See the CHANGELOG for the full list.