Conversation
Signed-off-by: Charlie Getzen <charliegetzenlc@gmail.com>
Signed-off-by: Charlie Getzen <charliegetzenlc@gmail.com>
Signed-off-by: Charlie Getzen <charliegetzenlc@gmail.com>
Signed-off-by: Charlie Getzen <charliegetzenlc@gmail.com>
Signed-off-by: Charlie Getzen <charliegetzenlc@gmail.com>
Signed-off-by: Charlie Getzen <charliegetzenlc@gmail.com>
Signed-off-by: Charlie Getzen <charliegetzenlc@gmail.com>
|
Hi @cgetzen, welcome and thank you for your contribution. We will try to review your Pull Request as quickly as possible. In the meantime, please take a look at the contribution guidelines if you have not done so already. |
|
CC @envoyproxy/api-shepherds: Your approval is needed for changes made to |
|
@cgetzen can we please move this to an issue with a proposed design that we can iterate on before we go to code? From there it might be more efficient to also iterate in a gdoc as part of the issue (up to you where you want to start). A few quick comments:
I don't see a huge issue here (though it really depends as always on a memory <-> CPU/locking/complexity), and I would definitely do pre-computation if possible in the MVP, so I would probably have the max shards / hosts per shard be configurable so the user can clearly understand what the memory implications are? Also, if you implement as a thread aware load balancer I think you can do the pre-computation once on the main thread and then share the LB on all the other threads like maglev/ring do.
My preference would be to do away with caching, etc. and do pre-computation, unless we show this is unreasonable. Also, I have general questions on whether the choosing has to be perfect or it could be probabilistically close enough. Imagine for example the following theoretical implementations:
All of ^ have trade-offs. cc @tonya11en also who is into this kind of thing. Anyway, I would suggest we move to an issue and writeup a doc to look at this in more detail. Interesting stuff! |
|
FWIW I just looked at the AWS reference code and I think https://github.com/awslabs/route53-infima/blob/master/src/main/java/com/amazonaws/services/route53/infima/SimpleSignatureShuffleSharder.java is basically my (1) above in spirit. But like I said there are a lot of trade-offs here depending on requirements. |
|
Going to close this for now in favor of the issue and design doc. |
Title: Shuffle Sharding to combinatorially isolate clients
Description:
Hi @mattklein123, thank you for the response! There's a lot to unpack there.
On the shuffle-shard math: You're right -- using shard_size=total_size/2 yields the worst case scenario. However, choosing more reasonable shard sizes still results in many shards (which is kind of the point, isolation!). I think the following are more reasonable shard sizes:
30 choose 5 = 142,506 shards
50 choose 3 = 19,600 shards
Should envoy impose a limit to how many hosts a shard can contain?
If having ~10^4 - 10^5 shards in memory is reasonable, I will turn off turn off cache eviction and potentially pre-calculate all shards.
How will shards be configured?
They are currently configured dynamically on chooseHost(..) when the shard doesn't exist in the cache.
The cache key is a combinatoric index (0 to nCk-1). The hosts each shard adds are also configured with this index through a "combo(i, n, k)" method, which finds the ith combination of n choose k. Maybe there is a more performant method?
How will shards be chosen?
Currently, the cache index is calculated with route.RouteAction.HashPolicy, by taking context->computeHashKey() % num_shards.
So it seems like a 2 layer approach with a mechanism to create shards, a mechanism to hash to shards, and then a 2nd tier LB in each shard would work out nicely?
In full agreement.
Some other thoughts that may spark better ideas: