Skip to content
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

Use sync.Map in the endpointregistry #2795

Merged
merged 1 commit into from
Dec 21, 2023
Merged

Conversation

RomanZavodskikh
Copy link
Contributor

@RomanZavodskikh RomanZavodskikh commented Dec 13, 2023

This PR is intended to make endpointregistry component lock-free

  • use sync.Map to get entries by key
  • convert all entry fields to atomics
  • make GetMetrics method return the entry instead of copy to decrease complexity in general and number of calls to sync.Map's Load in particular

The benchmark results show that it could be slow to call GetMetrics too much, but if the user will find a way to reuse its return value, the performance will be much better both than current master and new version:

goos: linux
goarch: amd64
pkg: github.com/zalando/skipper/routing
cpu: AMD Ryzen 7 PRO 4750U with Radeon Graphics
                                       │   master.txt   │     endpointregistrySyncMap.txt     │
                                       │     sec/op     │   sec/op     vs base                │
GetInflightRequests/1_goroutines-16      163.900n ±  7%   6.977n ± 2%  -95.74% (p=0.000 n=15)
GetInflightRequests/2_goroutines-16      202.100n ±  3%   3.792n ± 3%  -98.12% (p=0.000 n=15)
GetInflightRequests/3_goroutines-16      232.500n ±  8%   2.966n ± 4%  -98.72% (p=0.000 n=15)
GetInflightRequests/4_goroutines-16      252.500n ± 13%   2.572n ± 3%  -98.98% (p=0.000 n=15)
GetInflightRequests/5_goroutines-16      253.500n ±  8%   2.484n ± 4%  -99.02% (p=0.000 n=15)
GetInflightRequests/6_goroutines-16      251.900n ± 12%   2.148n ± 4%  -99.15% (p=0.000 n=15)
GetInflightRequests/7_goroutines-16      277.900n ± 10%   2.061n ± 4%  -99.26% (p=0.000 n=15)
GetInflightRequests/8_goroutines-16      268.800n ± 13%   1.834n ± 5%  -99.32% (p=0.000 n=15)
GetInflightRequests/12_goroutines-16     297.600n ± 22%   2.077n ± 3%  -99.30% (p=0.000 n=15)
GetInflightRequests/16_goroutines-16     270.100n ±  8%   2.578n ± 3%  -99.05% (p=0.000 n=15)
GetInflightRequests/24_goroutines-16     270.800n ± 14%   2.588n ± 2%  -99.04% (p=0.000 n=15)
GetInflightRequests/32_goroutines-16     279.400n ± 13%   2.593n ± 1%  -99.07% (p=0.000 n=15)
GetInflightRequests/48_goroutines-16     280.200n ± 10%   2.591n ± 1%  -99.08% (p=0.000 n=15)
GetInflightRequests/64_goroutines-16     298.500n ± 10%   2.593n ± 1%  -99.13% (p=0.000 n=15)
GetInflightRequests/128_goroutines-16    318.300n ±  9%   2.583n ± 1%  -99.19% (p=0.000 n=15)
GetInflightRequests/256_goroutines-16    325.700n ±  6%   2.598n ± 1%  -99.20% (p=0.000 n=15)
GetInflightRequests/512_goroutines-16    299.500n ± 16%   2.679n ± 3%  -99.11% (p=0.000 n=15)
GetInflightRequests/768_goroutines-16    327.800n ± 12%   2.752n ± 1%  -99.16% (p=0.000 n=15)
GetInflightRequests/1024_goroutines-16   331.000n ±  7%   2.810n ± 2%  -99.15% (p=0.000 n=15)
GetInflightRequests/1536_goroutines-16   252.300n ± 19%   2.830n ± 2%  -98.88% (p=0.000 n=15)
GetInflightRequests/2048_goroutines-16   245.500n ± 16%   2.874n ± 4%  -98.83% (p=0.000 n=15)
GetInflightRequests/4096_goroutines-16   213.200n ± 19%   2.784n ± 2%  -98.69% (p=0.000 n=15)
IncInflightRequests/1_goroutines-16       20.440n ±  9%   7.043n ± 1%  -65.54% (p=0.000 n=15)
IncInflightRequests/2_goroutines-16        30.88n ±  7%   10.26n ± 4%  -66.77% (p=0.000 n=15)
IncInflightRequests/3_goroutines-16        81.16n ± 16%   11.63n ± 3%  -85.67% (p=0.000 n=15)
IncInflightRequests/4_goroutines-16        94.71n ± 15%   13.48n ± 6%  -85.77% (p=0.000 n=15)
IncInflightRequests/5_goroutines-16        97.11n ± 20%   11.22n ± 4%  -88.45% (p=0.000 n=15)
IncInflightRequests/6_goroutines-16       110.70n ± 11%   10.81n ± 2%  -90.23% (p=0.000 n=15)
IncInflightRequests/7_goroutines-16       109.00n ± 16%   10.71n ± 1%  -90.17% (p=0.000 n=15)
IncInflightRequests/8_goroutines-16       108.50n ± 13%   10.73n ± 2%  -90.11% (p=0.000 n=15)
IncInflightRequests/12_goroutines-16      126.10n ± 11%   10.21n ± 3%  -91.90% (p=0.000 n=15)
IncInflightRequests/16_goroutines-16     117.200n ± 13%   9.842n ± 5%  -91.60% (p=0.000 n=15)
IncInflightRequests/24_goroutines-16       97.68n ± 18%   10.27n ± 4%  -89.49% (p=0.000 n=15)
IncInflightRequests/32_goroutines-16     131.300n ± 13%   9.871n ± 4%  -92.48% (p=0.000 n=15)
IncInflightRequests/48_goroutines-16     116.100n ± 25%   9.925n ± 3%  -91.45% (p=0.000 n=15)
IncInflightRequests/64_goroutines-16      89.740n ± 20%   9.986n ± 1%  -88.87% (p=0.000 n=15)
IncInflightRequests/128_goroutines-16     141.70n ± 10%   10.05n ± 3%  -92.91% (p=0.000 n=15)
IncInflightRequests/256_goroutines-16     153.00n ±  9%   10.26n ± 2%  -93.29% (p=0.000 n=15)
IncInflightRequests/512_goroutines-16     143.90n ±  8%   10.56n ± 3%  -92.66% (p=0.000 n=15)
IncInflightRequests/768_goroutines-16      92.80n ± 45%   10.67n ± 4%  -88.50% (p=0.000 n=15)
IncInflightRequests/1024_goroutines-16    131.30n ± 12%   10.41n ± 4%  -92.07% (p=0.000 n=15)
IncInflightRequests/1536_goroutines-16    106.10n ± 11%   10.26n ± 4%  -90.33% (p=0.000 n=15)
IncInflightRequests/2048_goroutines-16     98.52n ± 19%   10.28n ± 3%  -89.57% (p=0.000 n=15)
IncInflightRequests/4096_goroutines-16     89.42n ± 40%   10.30n ± 1%  -88.48% (p=0.000 n=15)
GetDetectedTime/1_goroutines-16                           7.075n ± 4%
GetDetectedTime/2_goroutines-16                           6.989n ± 4%
GetDetectedTime/3_goroutines-16                           5.359n ± 6%
GetDetectedTime/4_goroutines-16                           4.589n ± 4%
GetDetectedTime/5_goroutines-16                           4.480n ± 5%
GetDetectedTime/6_goroutines-16                           4.389n ± 2%
GetDetectedTime/7_goroutines-16                           4.396n ± 2%
GetDetectedTime/8_goroutines-16                           4.521n ± 2%
GetDetectedTime/12_goroutines-16                          5.307n ± 2%
GetDetectedTime/16_goroutines-16                          6.109n ± 1%
GetDetectedTime/24_goroutines-16                          6.081n ± 2%
GetDetectedTime/32_goroutines-16                          5.974n ± 2%
GetDetectedTime/48_goroutines-16                          5.993n ± 3%
GetDetectedTime/64_goroutines-16                          6.039n ± 3%
GetDetectedTime/128_goroutines-16                         5.996n ± 7%
GetDetectedTime/256_goroutines-16                         5.848n ± 5%
GetDetectedTime/512_goroutines-16                         5.963n ± 3%
GetDetectedTime/768_goroutines-16                         5.870n ± 4%
GetDetectedTime/1024_goroutines-16                        5.984n ± 4%
GetDetectedTime/1536_goroutines-16                        5.986n ± 2%
GetDetectedTime/2048_goroutines-16                        5.941n ± 3%
GetDetectedTime/4096_goroutines-16                        5.939n ± 1%
geomean                                    159.8n         5.394n       -96.69%

                                       │  master.txt  │       endpointregistrySyncMap.txt       │
                                       │     B/op     │    B/op     vs base                     │
GetInflightRequests/1_goroutines-16      32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/2_goroutines-16      32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/3_goroutines-16      32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/4_goroutines-16      32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/5_goroutines-16      32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/6_goroutines-16      32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/7_goroutines-16      32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/8_goroutines-16      32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/12_goroutines-16     32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/16_goroutines-16     32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/24_goroutines-16     32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/32_goroutines-16     32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/48_goroutines-16     32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/64_goroutines-16     32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/128_goroutines-16    32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/256_goroutines-16    32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/512_goroutines-16    32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/768_goroutines-16    32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/1024_goroutines-16   32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/1536_goroutines-16   32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/2048_goroutines-16   32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/4096_goroutines-16   32.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=15)
IncInflightRequests/1_goroutines-16      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/2_goroutines-16      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/3_goroutines-16      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/4_goroutines-16      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/5_goroutines-16      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/6_goroutines-16      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/7_goroutines-16      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/8_goroutines-16      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/12_goroutines-16     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/16_goroutines-16     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/24_goroutines-16     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/32_goroutines-16     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/48_goroutines-16     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/64_goroutines-16     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/128_goroutines-16    0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/256_goroutines-16    0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/512_goroutines-16    0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/768_goroutines-16    0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/1024_goroutines-16   0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/1536_goroutines-16   0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/2048_goroutines-16   0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/4096_goroutines-16   0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
GetDetectedTime/1_goroutines-16                         0.000 ± 0%
GetDetectedTime/2_goroutines-16                         0.000 ± 0%
GetDetectedTime/3_goroutines-16                         0.000 ± 0%
GetDetectedTime/4_goroutines-16                         0.000 ± 0%
GetDetectedTime/5_goroutines-16                         0.000 ± 0%
GetDetectedTime/6_goroutines-16                         0.000 ± 0%
GetDetectedTime/7_goroutines-16                         0.000 ± 0%
GetDetectedTime/8_goroutines-16                         0.000 ± 0%
GetDetectedTime/12_goroutines-16                        0.000 ± 0%
GetDetectedTime/16_goroutines-16                        0.000 ± 0%
GetDetectedTime/24_goroutines-16                        0.000 ± 0%
GetDetectedTime/32_goroutines-16                        0.000 ± 0%
GetDetectedTime/48_goroutines-16                        0.000 ± 0%
GetDetectedTime/64_goroutines-16                        0.000 ± 0%
GetDetectedTime/128_goroutines-16                       0.000 ± 0%
GetDetectedTime/256_goroutines-16                       0.000 ± 0%
GetDetectedTime/512_goroutines-16                       0.000 ± 0%
GetDetectedTime/768_goroutines-16                       0.000 ± 0%
GetDetectedTime/1024_goroutines-16                      0.000 ± 0%
GetDetectedTime/1536_goroutines-16                      0.000 ± 0%
GetDetectedTime/2048_goroutines-16                      0.000 ± 0%
GetDetectedTime/4096_goroutines-16                      0.000 ± 0%
geomean                                             ²               ?                       ² ³
¹ all samples are equal
² summaries must be >0 to compute geomean
³ ratios must be >0 to compute geomean

                                       │  master.txt  │       endpointregistrySyncMap.txt       │
                                       │  allocs/op   │ allocs/op   vs base                     │
GetInflightRequests/1_goroutines-16      1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/2_goroutines-16      1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/3_goroutines-16      1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/4_goroutines-16      1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/5_goroutines-16      1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/6_goroutines-16      1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/7_goroutines-16      1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/8_goroutines-16      1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/12_goroutines-16     1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/16_goroutines-16     1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/24_goroutines-16     1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/32_goroutines-16     1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/48_goroutines-16     1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/64_goroutines-16     1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/128_goroutines-16    1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/256_goroutines-16    1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/512_goroutines-16    1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/768_goroutines-16    1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/1024_goroutines-16   1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/1536_goroutines-16   1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/2048_goroutines-16   1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
GetInflightRequests/4096_goroutines-16   1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=15)
IncInflightRequests/1_goroutines-16      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/2_goroutines-16      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/3_goroutines-16      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/4_goroutines-16      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/5_goroutines-16      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/6_goroutines-16      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/7_goroutines-16      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/8_goroutines-16      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/12_goroutines-16     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/16_goroutines-16     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/24_goroutines-16     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/32_goroutines-16     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/48_goroutines-16     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/64_goroutines-16     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/128_goroutines-16    0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/256_goroutines-16    0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/512_goroutines-16    0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/768_goroutines-16    0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/1024_goroutines-16   0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/1536_goroutines-16   0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/2048_goroutines-16   0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
IncInflightRequests/4096_goroutines-16   0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=15) ¹
GetDetectedTime/1_goroutines-16                         0.000 ± 0%
GetDetectedTime/2_goroutines-16                         0.000 ± 0%
GetDetectedTime/3_goroutines-16                         0.000 ± 0%
GetDetectedTime/4_goroutines-16                         0.000 ± 0%
GetDetectedTime/5_goroutines-16                         0.000 ± 0%
GetDetectedTime/6_goroutines-16                         0.000 ± 0%
GetDetectedTime/7_goroutines-16                         0.000 ± 0%
GetDetectedTime/8_goroutines-16                         0.000 ± 0%
GetDetectedTime/12_goroutines-16                        0.000 ± 0%
GetDetectedTime/16_goroutines-16                        0.000 ± 0%
GetDetectedTime/24_goroutines-16                        0.000 ± 0%
GetDetectedTime/32_goroutines-16                        0.000 ± 0%
GetDetectedTime/48_goroutines-16                        0.000 ± 0%
GetDetectedTime/64_goroutines-16                        0.000 ± 0%
GetDetectedTime/128_goroutines-16                       0.000 ± 0%
GetDetectedTime/256_goroutines-16                       0.000 ± 0%
GetDetectedTime/512_goroutines-16                       0.000 ± 0%
GetDetectedTime/768_goroutines-16                       0.000 ± 0%
GetDetectedTime/1024_goroutines-16                      0.000 ± 0%
GetDetectedTime/1536_goroutines-16                      0.000 ± 0%
GetDetectedTime/2048_goroutines-16                      0.000 ± 0%
GetDetectedTime/4096_goroutines-16                      0.000 ± 0%
geomean                                             ²               ?                       ² ³
¹ all samples are equal
² summaries must be >0 to compute geomean
³ ratios must be >0 to compute geomean

@AlexanderYastrebov
Copy link
Member

AlexanderYastrebov commented Dec 14, 2023

Please add a benchmark showing performance and allocations of reading metrics (especially detected time).

@RomanZavodskikh
Copy link
Contributor Author

@AlexanderYastrebov I posted the benchmark inside PR description.
tl;dr It's good as far as user does not call GetMetrics too much.

@RomanZavodskikh RomanZavodskikh force-pushed the endpointregistrySyncMap branch 2 times, most recently from b576936 to d229720 Compare December 14, 2023 15:22
@RomanZavodskikh RomanZavodskikh force-pushed the endpointregistrySyncMap branch 4 times, most recently from d37a6a0 to a599912 Compare December 15, 2023 15:01

// There is ongoing effort to move data from Metrics and Detected to this field to simplify addition of new metrics
// and to make them host-wide instead of route-wide
MetricsFromRegistry atomic.Value // Metrics
Copy link
Contributor Author

@RomanZavodskikh RomanZavodskikh Dec 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This field is:

  • stored by endpointregistry postprocessor
  • loaded by fadein postprocessor
  • will be loaded by loadbalancer

I am not sure whether it is safe to store and load concurently (even when stored value is equal to the current value), so I have decided to make this field atomic.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets add this field in a separate PR. It also does not have to be atomic.Value because it is only read by proxy

Copy link
Contributor Author

@RomanZavodskikh RomanZavodskikh Dec 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I will be able to resolve comment without this field, I am able to add it in the separate PR.
#2795 (comment)

@@ -235,6 +235,7 @@ func (p *postProcessor) Do(r []*routing.Route) []*routing.Route {
}

ep.Detected = detected
ep.MetricsFromRegistry.Load().(routing.Metrics).SetDetected(detected)
Copy link
Member

@AlexanderYastrebov AlexanderYastrebov Dec 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should set value to the registry similar the code above

metrics := r.GetMetrics(ep.Host)
if endpointsCreated[key].After(metrics.DetectedTime()) {
	metrics.SetDetected(endpointsCreated[key])
}

or something like that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have to introduce additional argument to the fadein postprocessor constructor then, because there is no other way to pass endpointregistry here:
https://github.com/zalando/skipper/pull/2795/files#diff-9eb07484b61cb4592f195fc77b141796af8db69d01115364678c0de48abd6c70R202

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pre- and PostProcessors are normally fine to change.

Signed-off-by: Roman Zavodskikh <roman.zavodskikh@zalando.de>
@szuecs szuecs self-assigned this Dec 19, 2023
@szuecs szuecs self-requested a review December 19, 2023 17:58
e.lastSeen.Store(ts)
}

func newEntry() (result *entry) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why named return value?
This looks much better:

func newEntry() *entry {
	result := &entry{}
	result.SetDetected(time.Time{})
	result.SetLastSeen(time.Time{})
	return result
}

return &EndpointRegistry{
data: map[string]*entry{},
lastSeen: map[string]time.Time{},
result := &EndpointRegistry{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why store result if you can just return it?

@szuecs
Copy link
Member

szuecs commented Dec 20, 2023

@RomanZavodskikh more nits than very important findings.

👍

}

func BenchmarkGetDetectedTime(b *testing.B) {
goroutinesNums := []int{1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 24, 32, 48, 64, 128, 256, 512, 768, 1024, 1536, 2048, 4096}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why stop at 4096 and not 8192?

I see one cluster has regular close to 10k goroutines and one outlier cluster that had in the last 8h 31k.
So maybe 32768 makes even sense to test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The benchmarks are fine up to 32k goroutines, I will update results and this code in the next PR.

@szuecs
Copy link
Member

szuecs commented Dec 20, 2023

👍

@szuecs szuecs added the minor no risk changes, for example new filters label Dec 20, 2023
@RomanZavodskikh
Copy link
Contributor Author

The loadtests of this PR showed it is good to go, so will merge now.

@RomanZavodskikh
Copy link
Contributor Author

👍

@RomanZavodskikh RomanZavodskikh merged commit 377b9e0 into master Dec 21, 2023
14 checks passed
@RomanZavodskikh RomanZavodskikh deleted the endpointregistrySyncMap branch December 21, 2023 17:15
Comment on lines +203 to +205
if options.EndpointRegistry == nil {
options.EndpointRegistry = routing.NewEndpointRegistry(routing.RegistryOptions{})
}
Copy link
Member

@AlexanderYastrebov AlexanderYastrebov Dec 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes no sense as this registry instance will not be visible outside of this postprocessor.
The code should call GetMetrics only when registry is not nil instead.

RomanZavodskikh pushed a commit that referenced this pull request Jan 3, 2024
#2795

Signed-off-by: Roman Zavodskikh <roman.zavodskikh@zalando.de>
RomanZavodskikh added a commit that referenced this pull request Jan 3, 2024
#2795

Signed-off-by: Roman Zavodskikh <roman.zavodskikh@zalando.de>
Co-authored-by: Roman Zavodskikh <roman.zavodskikh@zalando.de>
AlexanderYastrebov added a commit that referenced this pull request Jan 12, 2024
EndpointRegistry.GetMetrics always allocates new entry even when
data for the key already exists.

sync.Map does not provide lazy initialization for new value, see
golang/go#44159

This change uses suggested best-effort to avoid allocating new value.

Follow up on #2795

Signed-off-by: Alexander Yastrebov <alexander.yastrebov@zalando.de>
AlexanderYastrebov added a commit that referenced this pull request Jan 12, 2024
EndpointRegistry.GetMetrics always allocates new entry even when
data for the key already exists.

sync.Map does not provide lazy initialization for the new value,
see golang/go#44159

This change uses suggested best-effort to avoid allocating
a new value on each load.

Follow up on #2795

Signed-off-by: Alexander Yastrebov <alexander.yastrebov@zalando.de>
AlexanderYastrebov added a commit that referenced this pull request Jan 12, 2024
EndpointRegistry.GetMetrics always allocates new entry even when
data for the key already exists.

sync.Map does not provide lazy initialization for the new value,
see golang/go#44159

This change uses suggested best-effort to avoid allocating
a new value on each load.

Follow up on #2795

Signed-off-by: Alexander Yastrebov <alexander.yastrebov@zalando.de>
szuecs pushed a commit that referenced this pull request Jan 12, 2024
…2847)

EndpointRegistry.GetMetrics always allocates new entry even when
data for the key already exists.

sync.Map does not provide lazy initialization for the new value,
see golang/go#44159

This change uses suggested best-effort to avoid allocating
a new value on each load.

Follow up on #2795

Signed-off-by: Alexander Yastrebov <alexander.yastrebov@zalando.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
minor no risk changes, for example new filters
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants