-
Notifications
You must be signed in to change notification settings - Fork 99
Make ConsistantHash have a better distribution #56
Conversation
1. Generate 512 points in the ring per peer to reduce the probability that a given peer will take more requests than others. 2. Change the default hashing algorithm from crc32 to fnv1 from github.com/segmentio/fasthash 3. Adjust internal implementation to have zero allocation and avoid map lookups. 4. Add tests and benchmarks, including distribution tests for hash functions. ``` BenchmarkConsistantHash/fasthash/fnv1 BenchmarkConsistantHash/fasthash/fnv1-8 18706365 65.4 ns/op 0 B/op 0 allocs/op ``` 5. Adjust functional tests to accomodate new distribution
Can one of the admins verify this patch? |
This prevents random test failures.
This is great! Thank you for spending the time to test and change this algorithm! I would love to get this merged before PR #55. As you say this will change distribution of keys on systems in production and that might not be desirable for a non major release (No ready to bump to v1.0 yet 😄). So my thought is that we keep the current Should also create Thoughts? |
These involve unsafe pointer arithmetic
That sounds good. I think that provides room for testing this on more data sets to verify distributions are fairly equal before establishing a default in a major release. I've made a variant on the proposed change and added it to the pull request. I named it
I also added tests for the original ConsistantHash (including a regression test to verify that the zero allocation improvement didn't change the distribution). For the original algorithm, I'm seeing the following distribution, which is similar to the real world data I was seeing:
I've added a config option via |
Thanks for making that change! I created a PR against your branch to allow users to pick the picker and algorithm. See bohde#1 If that looks okay to you, merge it into your branch and we can get this PR merged into master. |
Added GUBER_PEER_PICKER and GUBER_REPLICATED_HASH_REPLICAS
Merged! |
In a 3 peer cluster, I observed up to 60% of requests being routed to a single peer. I traced this back to the ConsistantHash algorithm only choosing one point in the ring per peer, which can skew the distribution. To alleviate this, I adjusted the algorithm in a few different ways:
This reduces the probability that a given peer will take more requests than others.
This has a better distribution than crc32 at lower number of points per peer.
ConsistantHash.Get
I've included tests and benchmarks for ConsistantHash for all hash functions in fasthash, including tests for how a set of requests are distributed amongst peers.
This is backwards incompatible in a few minor ways:
The signature of HashFunc now returns a uint64.
Requests will most likely route to a new peer, meaning peers with this code can't work with peers with the previous algorithm, since they won't agree on the canonical peer for a request.
Below are a results from the new distrubution tests and benchmarks. I've also deployed a variant of this to a test environment, and can confirm that requests are more evenly distributed.
Distributions
Benchmarks