-
Notifications
You must be signed in to change notification settings - Fork 249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide pluggable hashing and lookup strategy for NodeLocator #154
Draft
jasonk000
wants to merge
2
commits into
master
Choose a base branch
from
jkoch/fast-locator
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
A HashRingAlgorithm defines the algorithm that will be used to split a node into a ring. It assumes the ring will be Ketama-styled in that one node can be responsible for multiple keyspace ranges. Hash-rings can also be 'Simple' when they have a 1:1 mapping (one node receives one keyspace). A NodeLocatorLookup carries the data layout and associated search functions to locate a node for a given hash in the hashring. We also wire in the EVCacheNodeLocator to use the existing default implementations.
This introduces a combination of options for hash-ring generation and for the node lookup locator. This does not change any of the default configuration, but paves the way for future configuration to use the new code. In the right configuration this will generate anywhere from a 30% to a 10x increase in throughput while still allowing the choice of a backwards-compatible configuration. Also introduce some tests and benchmarks to demonstrate the impact. Node lookup - legacy uses the existing TreeMap implementation, this is the existing implementation. - array uses a straightforward sorted array of all values and binary-search, this is backwards compatible. - eytzinger uses a BFS-sorted array with a more efficient search tree (aka Eytzinger index), this is backwards compatible. - direct uses an efficient direct-array index approximation of the ketama hash-space, this is not backwards compatible as the hash space is split at slightly different locations. Hash ring - the ketama-md5 ring is the existing Ketama implementation using MD5 for a 128-bit hash - the ketama-murmur3 ring is the Ketama implementation modified to use Murmur3 as a 128-bit hash - the simple-fnv1a ring uses a simple (not-Ketama) ring, using FNV-1A hash Benchmark (hashRing) (keyCount) (keyTailLength) (locator) (nodeCount) Mode Cnt Score Error Units testGetPrimary ketama-md5 2000 0 legacy 10 thrpt 15 2607.833 ± 52.342 ops/s <-- testGetPrimary ketama-md5 2000 0 legacy 120 thrpt 15 2137.626 ± 22.707 ops/s <-- testGetPrimary ketama-md5 2000 50 legacy 10 thrpt 15 1798.278 ± 27.627 ops/s <-- testGetPrimary ketama-md5 2000 50 legacy 120 thrpt 15 1539.314 ± 13.284 ops/s <-- testGetPrimary ketama-murmur3 2000 0 legacy 10 thrpt 15 5589.163 ± 125.725 ops/s testGetPrimary ketama-murmur3 2000 0 legacy 120 thrpt 15 3730.209 ± 46.291 ops/s testGetPrimary ketama-murmur3 2000 50 legacy 10 thrpt 15 4160.228 ± 55.954 ops/s testGetPrimary ketama-murmur3 2000 50 legacy 120 thrpt 15 2925.185 ± 66.501 ops/s testGetPrimary ketama-md5 2000 0 array 10 thrpt 15 2856.391 ± 29.325 ops/s testGetPrimary ketama-md5 2000 0 array 120 thrpt 15 2567.685 ± 58.148 ops/s testGetPrimary ketama-md5 2000 50 array 10 thrpt 15 1918.709 ± 11.799 ops/s testGetPrimary ketama-md5 2000 50 array 120 thrpt 15 1764.622 ± 10.229 ops/s testGetPrimary ketama-murmur3 2000 0 array 10 thrpt 15 8139.093 ± 391.241 ops/s testGetPrimary ketama-murmur3 2000 0 array 120 thrpt 15 5646.702 ± 192.760 ops/s testGetPrimary ketama-murmur3 2000 50 array 10 thrpt 15 4894.453 ± 143.582 ops/s testGetPrimary ketama-murmur3 2000 50 array 120 thrpt 15 3910.925 ± 189.508 ops/s testGetPrimary ketama-md5 2000 0 eytzinger 10 thrpt 15 2939.745 ± 21.005 ops/s <-- testGetPrimary ketama-md5 2000 0 eytzinger 120 thrpt 15 2661.046 ± 25.636 ops/s <-- testGetPrimary ketama-md5 2000 50 eytzinger 10 thrpt 15 1939.034 ± 12.243 ops/s <-- testGetPrimary ketama-md5 2000 50 eytzinger 120 thrpt 15 1822.782 ± 10.516 ops/s <-- testGetPrimary ketama-murmur3 2000 0 eytzinger 10 thrpt 15 7761.497 ± 47.165 ops/s testGetPrimary ketama-murmur3 2000 0 eytzinger 120 thrpt 15 6125.655 ± 100.586 ops/s testGetPrimary ketama-murmur3 2000 50 eytzinger 10 thrpt 15 4920.855 ± 42.134 ops/s testGetPrimary ketama-murmur3 2000 50 eytzinger 120 thrpt 15 4084.432 ± 26.123 ops/s testGetPrimary ketama-md5 2000 0 direct 10 thrpt 15 3982.198 ± 42.075 ops/s <-- testGetPrimary ketama-md5 2000 0 direct 120 thrpt 15 3908.419 ± 41.634 ops/s <-- testGetPrimary ketama-md5 2000 50 direct 10 thrpt 15 2359.383 ± 14.831 ops/s <-- testGetPrimary ketama-md5 2000 50 direct 120 thrpt 15 2332.527 ± 12.630 ops/s <-- testGetPrimary ketama-murmur3 2000 0 direct 10 thrpt 15 25727.606 ± 236.122 ops/s <-- testGetPrimary ketama-murmur3 2000 0 direct 120 thrpt 15 24404.013 ± 223.451 ops/s <-- testGetPrimary ketama-murmur3 2000 50 direct 10 thrpt 15 8182.122 ± 43.455 ops/s <-- testGetPrimary ketama-murmur3 2000 50 direct 120 thrpt 15 7798.550 ± 90.895 ops/s <-- testGetPrimary simple-fnv1a 2000 0 legacy 10 thrpt 15 16497.086 ± 237.651 ops/s testGetPrimary simple-fnv1a 2000 0 legacy 120 thrpt 15 15026.541 ± 64.791 ops/s testGetPrimary simple-fnv1a 2000 50 legacy 10 thrpt 15 5256.310 ± 88.628 ops/s testGetPrimary simple-fnv1a 2000 50 legacy 120 thrpt 15 3969.989 ± 15.371 ops/s testGetPrimary simple-fnv1a 2000 0 array 10 thrpt 15 33851.510 ± 320.860 ops/s testGetPrimary simple-fnv1a 2000 0 array 120 thrpt 15 25844.239 ± 106.294 ops/s testGetPrimary simple-fnv1a 2000 50 array 10 thrpt 15 5650.150 ± 181.146 ops/s testGetPrimary simple-fnv1a 2000 50 array 120 thrpt 15 4232.681 ± 212.107 ops/s testGetPrimary simple-fnv1a 2000 0 eytzinger 10 thrpt 15 34050.744 ± 83.166 ops/s testGetPrimary simple-fnv1a 2000 0 eytzinger 120 thrpt 15 29417.993 ± 484.761 ops/s testGetPrimary simple-fnv1a 2000 50 eytzinger 10 thrpt 15 5699.404 ± 17.079 ops/s testGetPrimary simple-fnv1a 2000 50 eytzinger 120 thrpt 15 4516.383 ± 144.211 ops/s testGetPrimary simple-fnv1a 2000 0 direct 10 thrpt 15 44406.089 ± 290.314 ops/s testGetPrimary simple-fnv1a 2000 0 direct 120 thrpt 15 43076.871 ± 1227.180 ops/s testGetPrimary simple-fnv1a 2000 50 direct 10 thrpt 15 7761.636 ± 252.395 ops/s testGetPrimary simple-fnv1a 2000 50 direct 120 thrpt 15 7564.380 ± 218.651 ops/s
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
A significant part of the
getBulk
with large keylists is spent performing NodeLocator lookups (getPrimary
) to identify which node to send traffic to. The current Ketama configuration is based on MD5 which is no longer best-in-class, and uses a Java TreeMap which is not the most efficient approach for large arrays.This PR makes the components of the NodeLocator pluggable with different hash/ring functions and different strategies for storage of the hash-ring-to-node lookup function. It then provides a number of alternative implementations. It does NOT change any of the existing implementation / configuration, which would need to come in a follow-up.
Implementation configuration choices range from 30% faster to ~10x faster.