Description
Summary
As most recently seen in NCBC-3171, bugs in clients can result in keys being mapped to a non-canonical vBucket ID - which should be:
(((zlib.crc32(key.encode())) >> 16) & 0x7fff) & (len(vbuckets) - 1) |
To detect such bugs before they cause issue, we should investigate performing the same CRC mapping server-side, and rejecting any keys which have a non-canonical vBucket.
Context & History
KV-Engine is agnostic to which vBucket is used for a key - one can write any key into any vBucket one wishes. This is mostly for historical reasons going back to the evolution of CB Server from memcached, which also used client-side hashing (Ketama).
Some very old SDK clients (libcouchbase & Java v1.x?) allowed the application to explicitly specify the "hash key" to use. This was designed to allow documents with different keys to be co-located in a specific vBucket - for example key "user::daver" might map to vBucket 298 (by CRC32), but the user may wish to store a related document "user::daver::profile" to the same vBucket, even though it's canonical vBucket is 202. By issuing a request similar to:
bucket.get(key="user::daver::profile", hashkey="user::daver") |
They would have both documents located in the same vBucket (the primary motivation for doing so is for the app to be more resistant towards node failures. If one need X documents in order to server a single user in a game one would make sure that it would only be the users stored within that single node which became unavailable upon that node failure instead of all users which happened to have at least one fragment stored on the node).
However this was never supported on all SDKs, and current SDK 3 does not specify such an API. From discussions with SDK team (Michael Nitschinger and Charles Dixon), Java, .NET and Go SDKs are all confirmed to not have such functionality in SDK 3.
Given the little (zero?) benefit of allowing clients to override the vBucket, and the potential cost when software bugs cause it to be incorrect, perhaps now is the time to enforce the mapping in the server?
Attachments
Issue Links
- relates to
-
NCBC-3171 Request keys are corrupted when connected to mixed-node cluster running 7.0.3 and < 7.x
- Resolved
Gerrit Reviews
For Gerrit Dashboard: MB-51574 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
173408,6 | MB-51574: Enforce document->vbucket mapping [1/n] | master | kv_engine | Status: NEW | 0 | +1 |