-
Notifications
You must be signed in to change notification settings - Fork 816
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
Packed Allocation is very not packed #783
Comments
/cc @ilkercelikyilmaz as this will likely impact your performance work |
Just thinking about this statistically (Least I think I am - let me know if my math/logic is off here 😄 ). If I remember/read the logic right - with the current model - which is definitely more aimed at throughput we:
Which is awesome for throughput and contention, but doesn't seem to pack very well (unless this changes at scale in a way I'm not seeing? That would be super nice) But at first pass in my head - this feels statically less likely to pack, then not. For example:
Drawing this out, we could end up in scenarios at are something akin to [1,2,4,30,30,30,3] (or similar), and it seems very unlikely we'll actually fill those first nodes. And at scale, this seems like a big waste of resources our users would need to pay for. The only other thought is that fleet scale down logic (we scale down from the nodes with the least gameservers on them first) will help solve this (at least somewhere) -- need to think about this more. Not quite sure how to retain the throughput, but also keep things more packed though. |
@markmandel - is this a regression from previous releases or just something that hadn't yet been tested? |
@markmandel I was thinking about the source of the problem and think that we should look for packedComparator() function enhancement. |
Solution proposed above does not fix the problem, fleet is still not packed. Need to add logging to debug what is the root cause.
where in
|
@roberthbailey good question. It is a regression - but the sacrifice was made to allow better throughput. To be honest, I didn't realise it was quite this sub-optimal until I started poking at it now. (Lesson: write more tests 😄 ) For comparison, if we do the same things with root@30dacd3ba219:/go/src/agones.dev/agones# kubectl get gs | grep Alloc
xonotic-przc8-2npn8 Allocated 35.236.55.223 7505 gke-test-cluster-default-f11755a7-pgzl 4h
xonotic-przc8-7zcpb Allocated 35.236.55.223 7740 gke-test-cluster-default-f11755a7-pgzl 4h
xonotic-przc8-9n94z Allocated 35.236.55.223 7131 gke-test-cluster-default-f11755a7-pgzl 4h
xonotic-przc8-g5gbv Allocated 35.236.55.223 7681 gke-test-cluster-default-f11755a7-pgzl 4h
xonotic-przc8-mwkcf Allocated 35.236.55.223 7002 gke-test-cluster-default-f11755a7-pgzl 4h
xonotic-przc8-x9sfx Allocated 35.236.55.223 7812 gke-test-cluster-default-f11755a7-pgzl 4h
xonotic-przc8-xqfrw Allocated 35.236.55.223 7049 gke-test-cluster-default-f11755a7-pgzl 4h But this is throttled by a mutex among other things. The current idea i have floating around my head is to presort the gameservers, and essentially have a queue that we can pop values off on each allocation. Even if the sorting is only eventually consistent, we'll avoid contention issues, and get a better packed result. Something like this might work: https://github.com/wangjia184/sortedset The only trickiness I'm seeing is keeping the gameservers sorted regularly without slowing down the allocation process. Maybe a full resync every 30 seconds or something happening in a different goroutine? (The sortedset sorts by score, and then lexigraphically, so it should in theory work pretty well). I might give the implementation a shot, and see how it pans out. Be curious to hear thoughts? |
Taking a stab at this here: https://github.com/markmandel/agones/tree/perf/sorted-set - curious to see how the approach performs at scale once complete. |
Arg, I forgot that we have the required/preferred selectors, doh!. My approach needs to be tweaked / may not work 😞 |
Revised plan - not 100% sure it's optimal for throughput + packing, but I think it's worth a shot - but also happy to hear dissenting opinions if you can see holes in the logic. This is based on the assumption that the selectors for a GameServerAllocation are likely to not change very often, and generally work on large fleets - rather than very specific small groups (although this might work okay for small groups at lower throughput?)
Two potential issues and/or solutions
Both of these could drive contention as they would be attempting to pop the same GameServers on each run. Potential solution: add jitter from 0-1 to each score, so that within a node, the order within a node (or those with the same allocated counts) is randomised per cache. This could potentially be increased to more than 0-1 if we need more randomness. |
This implements a batching algorithm for Packed and Distributed GameServerAllocations (GSA). This ensures that we can still get high throughout on GSA's, while retaining a tight packing of Allocated GameServers on each node with the Packed strategy. The Distributed strategy is now implemented with a randomised Allocation process, so ensure distributed load under this strategy. Closes googleforgames#783
This implements a batching algorithm for Packed and Distributed GameServerAllocations (GSA). This ensures that we can still get high throughout on GSA's, while retaining a tight packing of Allocated GameServers on each node with the Packed strategy. The Distributed strategy is now implemented with a randomised Allocation process, so ensure distributed load under this strategy. Closes googleforgames#783
This implements a batching algorithm for Packed and Distributed GameServerAllocations (GSA). This ensures that we can still get high throughout on GSA's, while retaining a tight packing of Allocated GameServers on each node with the Packed strategy. The Distributed strategy is now implemented with a randomised Allocation process, so ensure distributed load under this strategy. Closes googleforgames#783
* Batched Packed and Distributed Allocations This implements a batching algorithm for Packed and Distributed GameServerAllocations (GSA). This ensures that we can still get high throughout on GSA's, while retaining a tight packing of Allocated GameServers on each node with the Packed strategy. The Distributed strategy is now implemented with a randomised Allocation process, so ensure distributed load under this strategy. Closes #783 * Move updateQueue into allocationUpdateWorkers. * Add large explanatory code block.
What happened:
What you expected to happen:
Gameservers should have been allocated to the same node (or at least as close as we can get given some performance constraints)
This is far less than ideal, as this will cost our users quite large $$$ at large scale as they will be unable to scale down resources that may be mostly empty. It also defies the "Packed" contract.
How to reproduce it (as minimally and precisely as possible):
Create any of the fleets we have, push it up to a scale such that it will encompass multiple nodes (xonotic is good for this, as it has a larger memory footprint).
Then allocate several gameservers, and
kubectl get gs
to see the results.Environment: Linux
kubectl version
): 1.11.xThe text was updated successfully, but these errors were encountered: