-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Optimize locking for metric aggregations #7189
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
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #7189 +/- ##
======================================
Coverage 85.4% 85.5%
======================================
Files 271 275 +4
Lines 24391 24763 +372
======================================
+ Hits 20845 21181 +336
- Misses 3168 3197 +29
- Partials 378 385 +7
🚀 New features to boost your workflow:
|
9329437
to
778d81f
Compare
The benchmarks in the description now are the improvement on top of the change to attribute.Distinct. |
60c1c88
to
4adb38d
Compare
This is helpful for my work optimizing locking in #7189 ``` goos: linux goarch: amd64 pkg: go.opentelemetry.io/otel/sdk/metric cpu: Intel(R) Xeon(R) CPU @ 2.20GHz BenchmarkSyncMeasure/NoView/ExponentialFloat64Histogram/Attributes/0-24 43419 306.0 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/NoView/ExponentialFloat64Histogram/Attributes/0-24 40675 316.1 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/NoView/ExponentialFloat64Histogram/Attributes/0-24 53746 305.6 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/NoView/ExponentialFloat64Histogram/Attributes/0-24 38224 296.1 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/NoView/ExponentialFloat64Histogram/Attributes/0-24 53796 330.3 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/NoView/ExponentialFloat64Histogram/Attributes/0-24 47823 316.4 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/NoView/ExponentialFloat64Histogram/Attributes/1-24 32172 373.5 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/NoView/ExponentialFloat64Histogram/Attributes/1-24 33084 379.0 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/NoView/ExponentialFloat64Histogram/Attributes/1-24 29956 360.4 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/NoView/ExponentialFloat64Histogram/Attributes/1-24 33921 370.1 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/NoView/ExponentialFloat64Histogram/Attributes/1-24 34449 387.7 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/NoView/ExponentialFloat64Histogram/Attributes/1-24 29156 393.6 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/NoView/ExponentialFloat64Histogram/Attributes/10-24 10768 1040 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/NoView/ExponentialFloat64Histogram/Attributes/10-24 11190 1056 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/NoView/ExponentialFloat64Histogram/Attributes/10-24 11078 1176 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/NoView/ExponentialFloat64Histogram/Attributes/10-24 10929 1219 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/NoView/ExponentialFloat64Histogram/Attributes/10-24 10454 1066 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/NoView/ExponentialFloat64Histogram/Attributes/10-24 10501 1064 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/DropView/ExponentialFloat64Histogram/Attributes/0-24 5919898 1.879 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/DropView/ExponentialFloat64Histogram/Attributes/0-24 5834685 1.990 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/DropView/ExponentialFloat64Histogram/Attributes/0-24 5782334 2.433 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/DropView/ExponentialFloat64Histogram/Attributes/0-24 5320924 2.404 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/DropView/ExponentialFloat64Histogram/Attributes/0-24 5742800 2.109 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/DropView/ExponentialFloat64Histogram/Attributes/0-24 5885475 2.056 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/DropView/ExponentialFloat64Histogram/Attributes/1-24 4331547 2.758 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/DropView/ExponentialFloat64Histogram/Attributes/1-24 3848244 2.725 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/DropView/ExponentialFloat64Histogram/Attributes/1-24 4542189 2.636 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/DropView/ExponentialFloat64Histogram/Attributes/1-24 4201015 2.641 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/DropView/ExponentialFloat64Histogram/Attributes/1-24 4597094 2.608 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/DropView/ExponentialFloat64Histogram/Attributes/1-24 4869811 2.491 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/DropView/ExponentialFloat64Histogram/Attributes/10-24 4826077 2.329 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/DropView/ExponentialFloat64Histogram/Attributes/10-24 4866612 2.382 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/DropView/ExponentialFloat64Histogram/Attributes/10-24 5149305 2.310 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/DropView/ExponentialFloat64Histogram/Attributes/10-24 5101305 2.384 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/DropView/ExponentialFloat64Histogram/Attributes/10-24 4854940 2.440 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/DropView/ExponentialFloat64Histogram/Attributes/10-24 4874742 2.501 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/AttrFilterView/ExponentialFloat64Histogram/Attributes/0-24 55272 359.0 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/AttrFilterView/ExponentialFloat64Histogram/Attributes/0-24 52195 318.4 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/AttrFilterView/ExponentialFloat64Histogram/Attributes/0-24 52324 330.8 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/AttrFilterView/ExponentialFloat64Histogram/Attributes/0-24 49879 321.4 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/AttrFilterView/ExponentialFloat64Histogram/Attributes/0-24 56212 351.3 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/AttrFilterView/ExponentialFloat64Histogram/Attributes/0-24 43362 301.4 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/AttrFilterView/ExponentialFloat64Histogram/Attributes/1-24 30296 461.9 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/AttrFilterView/ExponentialFloat64Histogram/Attributes/1-24 24178 469.0 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/AttrFilterView/ExponentialFloat64Histogram/Attributes/1-24 24901 477.0 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/AttrFilterView/ExponentialFloat64Histogram/Attributes/1-24 21748 477.6 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/AttrFilterView/ExponentialFloat64Histogram/Attributes/1-24 23972 512.9 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/AttrFilterView/ExponentialFloat64Histogram/Attributes/1-24 28039 499.5 ns/op 0 B/op 0 allocs/op BenchmarkSyncMeasure/AttrFilterView/ExponentialFloat64Histogram/Attributes/10-24 7598 1646 ns/op 704 B/op 2 allocs/op BenchmarkSyncMeasure/AttrFilterView/ExponentialFloat64Histogram/Attributes/10-24 7452 1660 ns/op 704 B/op 2 allocs/op BenchmarkSyncMeasure/AttrFilterView/ExponentialFloat64Histogram/Attributes/10-24 7620 1644 ns/op 704 B/op 2 allocs/op BenchmarkSyncMeasure/AttrFilterView/ExponentialFloat64Histogram/Attributes/10-24 6459 1853 ns/op 704 B/op 2 allocs/op BenchmarkSyncMeasure/AttrFilterView/ExponentialFloat64Histogram/Attributes/10-24 7950 1575 ns/op 704 B/op 2 allocs/op BenchmarkSyncMeasure/AttrFilterView/ExponentialFloat64Histogram/Attributes/10-24 8948 1421 ns/op 704 B/op 2 allocs/op ```
We could also look into adopting https://www.youtube.com/watch?v=VmrEG-3bWyM&t=253s. |
dd1c720
to
fd8961b
Compare
I'm mostly happy with the current results. The single-threaded performance gets worse for histograms and exp histograms, but it seems worth it overall. In an ideal world, we would implement "lockless" histograms and exponential histograms like Prometheus does, but that is hard... Using RLock() for the common case seems like a reasonable first approach. The main blocker is that we don't have good concurrency testing around aggregations. I'll add that in a separate PR before I mark this ready for review. I'll also try and pull some of the small refactor changes out to be reviewed as separate changes. |
23411a4
to
126c5cf
Compare
126c5cf
to
9457877
Compare
Prerequisite for #7189. Add tests to try to catch race conditions for concurrent measurements.
Closing in favor of #7427 |
Related: #7037
Currently, when we record a measurement, we
Lock
a single lock (non-rw) for the whole instrument, and then we update the value and record exemplars.This PR uses a RWMutex for the map[attribute]->value, and splits this into 4 lock stages to reduce contention:
It also borrows an optimization from the prometheus client, since incrementing an integer is possible with atomics, but floats can't be incremented atomically as easily. See https://github.com/prometheus/client_golang/blob/14ccb93091c00f86b85af7753100aa372d63602b/prometheus/counter.go#L108. This is added in atomic.go.
I experimented with using atomic.Pointer to be able to use CompareAndSwap with histogram and exponential histogram types, but found that the result was slower than locking.
Multi-threaded benchmarks:
Single-threaded benchmarks: