-
Notifications
You must be signed in to change notification settings - Fork 336
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
Optimize for topology term #1310
Optimize for topology term #1310
Conversation
Hi @huww98. Thanks for your PR. I'm waiting for a kubernetes-csi member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
pkg/controller/topology.go
Outdated
@@ -39,8 +39,14 @@ import ( | |||
"k8s.io/klog/v2" | |||
) | |||
|
|||
type topologyKey struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find it strange to call something a Key
if it has a Key
field inside. topologyKeyValue
? topologyItem
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed to topologySegment, according to CSI spec.
/ok-to-test |
Compared with map, slice is a lot faster. And we can avoid allocation in the compare() func, which is a very hot path.
This allow us to get rid of the hash() func, which is slow and do too many allocations.
266c667
to
bd3b4a1
Compare
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: huww98, jsafrane The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
What type of PR is this?
/kind cleanup
What this PR does / why we need it:
Greatly reduce the CPU and memory usage, especially for drivers assign different topology to each host. Benchmark shows 30x CPU reduction and 21x memory allocation size reduction.
We were performing a stress test recently, and found the bottleneck to be the CPU usage of external-provisioner. From profiling,
topologyTerm.hash
takes almost all the CPU time (apart from logGRPC).Our setup is a 3k node cluster, each node has a distinct topology. It took about 50s for provisioning 3k immediate binding volumes, despite that we have raised the CPU limit to 10. external-provisioner also took ~3GiB memory, which is far higher than expected.
This is my initial attempt (not included in this PR) to optimize this. I re-implemented the compare function for sort to avoid hash() and added some benchmarks. The benchmark result is:
By comparing
compare
andbaseline
forBenchmarkDedupAndSortHost
, re-implementing compare already gives 3x speedup and 5x memory allocation size reduction. But when I try to replace the hash() func completely byslices.Compact
, the host case is faster, but the zone case becomes slower.While I'm trying to find more opportunity to optimize, I do another profile for
Host/slices.Sort
case:Making slice, accessing map, and sorting keys can all be avoid if we define topologyTerm as a sorted slice instead of map (the first commit of this PR). The benchmark result from the first commit is:
Host/slices.Sort
case is speedup several times again, theZone/slices.Sort
case is also improved because of the more efficient hash(). With the very cheap compare(), usingslices.Compact
to deduplicate becomes beneficial for both case!So, with the second commit, the hash() is removed completely.
Note that for fair comparation, the benchmark also includes
toCSITopology
invocation, because if topologyTerm is a slice, we need to convert it back to map for GRPC. Actually, after this refactor, most of the time is spent ontoCSITopology()
. If I remove it, the result is:This is ~78x speedup compared to the baseline, with zero allocation in deduplication and sort step!
Which issue(s) this PR fixes:
Fixes #
Special notes for your reviewer:
Does this PR introduce a user-facing change?: