-
Notifications
You must be signed in to change notification settings - Fork 42
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
Performance degradation over time with ETS backend #71
Comments
I've also tried to profile ETS backend and noticed that the workers
Note that time spent in |
Would there be any interest in optimizing the ETS backend? I'd be happy to work on that. The first step would be (I think) to add benchmarks and then compare the performance with and without poolboy to check if my guesses are right. |
The increasing wait time might point to a growing checkout queue in poolboy.iex(1)> Supervisor.which_children Hammer.Supervisor
[{:hammer_backend_single_pool, #PID<0.462.0>, :worker, [:poolboy]}]
# :queue is empty ( {[], []})
iex(2)> :sys.get_state(pid(0,462,0))
{:state, #PID<0.463.0>,
[#PID<0.469.0>, #PID<0.468.0>, #PID<0.467.0>, #PID<0.464.0>], {[], []},
#Reference<0.192931417.1724776450.239958>, 4, 0, 0, :lifo}
# start benchmark
iex(4)> :sys.get_state(pid(0,462,0))
{:state, #PID<0.463.0>,
[#PID<0.469.0>, #PID<0.468.0>, #PID<0.467.0>, #PID<0.464.0>], {[], []},
#Reference<0.192931417.1724776450.239958>, 4, 0, 0, :lifo}
iex(5)> :sys.get_state(pid(0,462,0))
{:state, #PID<0.463.0>, [#PID<0.464.0>, #PID<0.467.0>], {[], []},
#Reference<0.192931417.1724776450.239958>, 4, 0, 0, :lifo}
iex(6)> :sys.get_state(pid(0,462,0))
{:state, #PID<0.463.0>, [#PID<0.469.0>, #PID<0.464.0>], {[], []},
#Reference<0.192931417.1724776450.239958>, 4, 0, 0, :lifo}
iex(7)> :sys.get_state(pid(0,462,0))
{:state, #PID<0.463.0>, [],
{[
{{#PID<0.20229.0>,
[:alias | #Reference<0.0.2589315.192931417.1724973064.35897>]},
#Reference<0.192931417.1724907528.35896>,
#Reference<0.192931417.1724907522.62923>},
{{#PID<0.20236.0>,
[:alias | #Reference<0.0.2590211.192931417.1724973060.51696>]},
#Reference<0.192931417.1724907524.51695>,
#Reference<0.192931417.1724907522.62922>}
],
[
{{#PID<0.20235.0>,
[:alias | #Reference<0.0.2590083.192931417.1724973063.38309>]},
#Reference<0.192931417.1724907527.38308>,
#Reference<0.192931417.1724907522.62906>},
{{#PID<0.20238.0>,
[:alias | #Reference<0.0.2590467.192931417.1724973064.35881>]},
#Reference<0.192931417.1724907528.35880>,
#Reference<0.192931417.1724907522.62907>},
{{#PID<0.20237.0>,
[:alias | #Reference<0.0.2590339.192931417.1724973061.47663>]},
#Reference<0.192931417.1724907525.47662>,
#Reference<0.192931417.1724907522.62921>}
]}, #Reference<0.192931417.1724776450.239958>, 4, 0, 0, :lifo}
iex(8)> :sys.get_state(pid(0,462,0))
{:state, #PID<0.463.0>, [],
{[
{{#PID<0.30693.0>,
[:alias | #Reference<0.0.3928707.192931417.1724973061.85287>]},
#Reference<0.192931417.1724907525.85286>,
#Reference<0.192931417.1724907527.76715>},
{{#PID<0.30691.0>,
[:alias | #Reference<0.0.3928451.192931417.1724973057.98127>]},
#Reference<0.192931417.1724907521.98126>,
#Reference<0.192931417.1724907527.76712>},
{{#PID<0.30692.0>,
[:alias | #Reference<0.0.3928579.192931417.1724973062.86576>]},
#Reference<0.192931417.1724907526.86575>,
#Reference<0.192931417.1724907527.76711>},
{{#PID<0.30690.0>,
[:alias | #Reference<0.0.3928323.192931417.1724973061.85267>]},
#Reference<0.192931417.1724907525.85266>,
#Reference<0.192931417.1724907527.76708>},
{{#PID<0.30664.0>,
[:alias | #Reference<0.0.3924995.192931417.1724973063.76705>]},
#Reference<0.192931417.1724907527.76704>,
#Reference<0.192931417.1724907527.76707>},
{{#PID<0.30688.0>,
[:alias | #Reference<0.0.3928067.192931417.1724973060.89037>]},
#Reference<0.192931417.1724907524.89036>,
#Reference<0.192931417.1724907527.76706>},
{{#PID<0.30687.0>,
[:alias | #Reference<0.0.3927939.192931417.1724973061.85254>]},
#Reference<0.192931417.1724907525.85253>,
#Reference<0.192931417.1724907528.73877>},
{{#PID<0.30689.0>,
[:alias | #Reference<0.0.3928195.192931417.1724973062.86550>]},
#Reference<0.192931417.1724907526.86549>,
#Reference<0.192931417.1724907521.98095>},
{{#PID<0.30686.0>,
[:alias | #Reference<0.0.3927811.192931417.1724973061.85235>]},
#Reference<0.192931417.1724907525.85234>,
#Reference<0.192931417.1724907521.98094>},
{{#PID<0.30685.0>,
[:alias | #Reference<0.0.3927683.192931417.1724973062.86522>]},
#Reference<0.192931417.1724907526.86521>,
#Reference<0.192931417.1724907523.85084>}
],
[
{{#PID<0.30672.0>,
[:alias | #Reference<0.0.3926019.192931417.1724973059.85063>]},
#Reference<0.192931417.1724907523.85062>,
#Reference<0.192931417.1724907523.85083>}
]}, #Reference<0.192931417.1724776450.239958>, 4, 0, 0, :lifo}
iex(9)> :sys.get_state(pid(0,462,0))
{:state, #PID<0.463.0>, [],
{[
{{#PID<0.40217.0>,
[:alias | #Reference<0.0.953491.192931417.1724973060.124990>]},
#Reference<0.192931417.1724907524.124989>,
#Reference<0.192931417.1724907524.125000>},
{{#PID<0.40218.0>,
[:alias | #Reference<0.0.953619.192931417.1724973060.124974>]},
#Reference<0.192931417.1724907524.124973>,
#Reference<0.192931417.1724907524.124997>},
{{#PID<0.40216.0>,
[:alias | #Reference<0.0.953363.192931417.1724973057.131528>]},
#Reference<0.192931417.1724907521.131527>,
#Reference<0.192931417.1724907524.124996>},
{{#PID<0.40215.0>,
[:alias | #Reference<0.0.953235.192931417.1724973059.119283>]},
#Reference<0.192931417.1724907523.119282>,
#Reference<0.192931417.1724907524.124995>},
{{#PID<0.40202.0>,
[:alias | #Reference<0.0.951571.192931417.1724973061.121546>]},
#Reference<0.192931417.1724907525.121545>,
#Reference<0.192931417.1724907524.124994>},
{{#PID<0.40200.0>,
[:alias | #Reference<0.0.951315.192931417.1724973061.121533>]},
#Reference<0.192931417.1724907525.121532>,
#Reference<0.192931417.1724907524.124993>},
{{#PID<0.40204.0>,
[:alias | #Reference<0.0.951827.192931417.1724973060.124951>]},
#Reference<0.192931417.1724907524.124950>,
#Reference<0.192931417.1724907524.124992>},
{{#PID<0.40214.0>,
[:alias | #Reference<0.0.953107.192931417.1724973062.120287>]},
#Reference<0.192931417.1724907526.120286>,
#Reference<0.192931417.1724907528.108633>},
{{#PID<0.40213.0>,
[:alias | #Reference<0.0.952979.192931417.1724973059.119251>]},
#Reference<0.192931417.1724907523.119250>,
#Reference<0.192931417.1724907528.108632>},
{{#PID<0.40212.0>,
[:alias | #Reference<0.0.952851.192931417.1724973057.131489>]},
#Reference<0.192931417.1724907521.131488>,
#Reference<0.192931417.1724907528.108631>},
{{#PID<0.40211.0>,
[:alias | #Reference<0.0.952723.192931417.1724973063.111480>]},
#Reference<0.192931417.1724907527.111479>,
#Reference<0.192931417.1724907528.108621>},
{{#PID<0.40210.0>,
[:alias | #Reference<0.0.952595.192931417.1724973064.108613>]},
#Reference<0.192931417.1724907528.108612>,
#Reference<0.192931417.1724907528.108614>},
{{#PID<0.40209.0>,
[:alias | #Reference<0.0.952467.192931417.1724973057.131474>]},
#Reference<0.192931417.1724907521.131473>,
#Reference<0.192931417.1724907521.131476>}
],
[
{{#PID<0.40193.0>,
[:alias | #Reference<0.0.950419.192931417.1724973058.133850>]},
#Reference<0.192931417.1724907522.133849>,
#Reference<0.192931417.1724907521.131423>},
{{#PID<0.40201.0>,
[:alias | #Reference<0.0.951443.192931417.1724973064.108585>]},
#Reference<0.192931417.1724907528.108584>,
#Reference<0.192931417.1724907521.131444>},
{{#PID<0.40203.0>,
[:alias | #Reference<0.0.951699.192931417.1724973057.131443>]},
#Reference<0.192931417.1724907521.131442>,
#Reference<0.192931417.1724907521.131445>},
{{#PID<0.40205.0>,
[:alias | #Reference<0.0.951955.192931417.1724973063.111448>]},
#Reference<0.192931417.1724907527.111447>,
#Reference<0.192931417.1724907521.131460>},
{{#PID<0.40207.0>,
[:alias | #Reference<0.0.952211.192931417.1724973060.124916>]},
#Reference<0.192931417.1724907524.124915>,
#Reference<0.192931417.1724907521.131461>},
{{#PID<0.40208.0>,
[:alias | #Reference<0.0.952339.192931417.1724973063.111464>]},
#Reference<0.192931417.1724907527.111463>,
#Reference<0.192931417.1724907521.131475>}
]}, #Reference<0.192931417.1724776450.239958>, 4, 0, 0, :lifo}
iex(10)> :sys.get_state(pid(0,462,0))
{:state, #PID<0.463.0>, [],
{[
{{#PID<0.53151.0>,
[:alias | #Reference<0.0.2609043.192931417.1724973062.167102>]},
#Reference<0.192931417.1724907526.167101>,
#Reference<0.192931417.1724907522.180080>},
{{#PID<0.53150.0>,
[:alias | #Reference<0.0.2608915.192931417.1724973058.180073>]},
#Reference<0.192931417.1724907522.180072>,
#Reference<0.192931417.1724907522.180079>},
{{#PID<0.53147.0>,
[:alias | #Reference<0.0.2608531.192931417.1724973062.167086>]},
#Reference<0.192931417.1724907526.167085>,
#Reference<0.192931417.1724907522.180078>},
{{#PID<0.53130.0>,
[:alias | #Reference<0.0.2606355.192931417.1724973058.180059>]},
#Reference<0.192931417.1724907522.180058>,
#Reference<0.192931417.1724907522.180077>},
{{#PID<0.53146.0>,
[:alias | #Reference<0.0.2608403.192931417.1724973062.167060>]},
#Reference<0.192931417.1724907526.167059>,
#Reference<0.192931417.1724907522.180076>},
{{#PID<0.53149.0>,
[:alias | #Reference<0.0.2608787.192931417.1724973064.157754>]},
#Reference<0.192931417.1724907528.157753>,
#Reference<0.192931417.1724907522.180075>},
{{#PID<0.53148.0>,
[:alias | #Reference<0.0.2608659.192931417.1724973057.178486>]},
#Reference<0.192931417.1724907521.178485>,
#Reference<0.192931417.1724907522.180074>},
{{#PID<0.53145.0>,
[:alias | #Reference<0.0.2608275.192931417.1724973063.159113>]},
#Reference<0.192931417.1724907527.159112>,
#Reference<0.192931417.1724907527.159132>},
{{#PID<0.53144.0>,
[:alias | #Reference<0.0.2608147.192931417.1724973064.157735>]},
#Reference<0.192931417.1724907528.157734>,
#Reference<0.192931417.1724907527.159131>},
{{#PID<0.53143.0>,
[:alias | #Reference<0.0.2608019.192931417.1724973057.178467>]},
#Reference<0.192931417.1724907521.178466>,
#Reference<0.192931417.1724907527.159130>},
{{#PID<0.53140.0>,
[:alias | #Reference<0.0.2607635.192931417.1724973062.167033>]},
#Reference<0.192931417.1724907526.167032>,
#Reference<0.192931417.1724907527.159129>},
{{#PID<0.53138.0>,
[:alias | #Reference<0.0.2607379.192931417.1724973063.159094>]},
#Reference<0.192931417.1724907527.159093>,
#Reference<0.192931417.1724907527.159128>},
{{#PID<0.53133.0>,
[:alias | #Reference<0.0.2606739.192931417.1724973062.167020>]},
#Reference<0.192931417.1724907526.167019>,
#Reference<0.192931417.1724907527.159127>},
{{#PID<0.53137.0>,
[:alias | #Reference<0.0.2607251.192931417.1724973063.159081>]},
#Reference<0.192931417.1724907527.159080>,
#Reference<0.192931417.1724907527.159126>},
{{#PID<0.53142.0>,
[:alias | #Reference<0.0.2607891.192931417.1724973057.178448>]},
#Reference<0.192931417.1724907521.178447>,
#Reference<0.192931417.1724907527.159125>},
{{#PID<0.53139.0>,
[:alias | #Reference<0.0.2607507.192931417.1724973064.157715>]},
#Reference<0.192931417.1724907528.157714>,
#Reference<0.192931417.1724907527.159124>},
{{#PID<0.53141.0>,
[:alias | #Reference<0.0.2607763.192931417.1724973060.172514>]},
#Reference<0.192931417.1724907524.172513>,
#Reference<0.192931417.1724907527.159123>},
{{#PID<0.53136.0>,
[:alias | #Reference<0.0.2607123.192931417.1724973063.159068>]},
#Reference<0.192931417.1724907527.159067>,
#Reference<0.192931417.1724907527.159122>},
{{#PID<0.53135.0>,
[:alias | #Reference<0.0.2606995.192931417.1724973063.159055>]},
#Reference<0.192931417.1724907527.159054>,
#Reference<0.192931417.1724907527.159121>},
{{#PID<0.53134.0>,
[:alias | #Reference<0.0.2606867.192931417.1724973063.159018>]},
#Reference<0.192931417.1724907527.159017>,
#Reference<0.192931417.1724907527.159118>},
{{#PID<0.53132.0>,
[:alias | #Reference<0.0.2606611.192931417.1724973063.158998>]},
#Reference<0.192931417.1724907527.158997>,
#Reference<0.192931417.1724907527.159116>},
{{#PID<0.53131.0>,
[:alias | #Reference<0.0.2606483.192931417.1724973057.178415>]},
#Reference<0.192931417.1724907521.178414>,
#Reference<0.192931417.1724907527.159114>},
{{#PID<0.53129.0>,
[:alias | #Reference<0.0.2606227.192931417.1724973061.166048>]},
#Reference<0.192931417.1724907525.166047>,
#Reference<0.192931417.1724907525.166050>},
{{#PID<0.53128.0>,
[:alias | #Reference<0.0.2606099.192931417.1724973062.166969>]},
#Reference<0.192931417.1724907526.166968>,
#Reference<0.192931417.1724907525.166049>},
{{#PID<0.53127.0>,
[:alias | #Reference<0.0.2605971.192931417.1724973061.166034>]},
#Reference<0.192931417.1724907525.166033>,
#Reference<0.192931417.1724907525.166035>},
{{#PID<0.53125.0>,
[:alias | #Reference<0.0.2605715.192931417.1724973057.178391>]},
#Reference<0.192931417.1724907521.178390>,
#Reference<0.192931417.1724907525.166009>},
{{#PID<0.53126.0>,
[:alias | #Reference<0.0.2605843.192931417.1724973057.178378>]},
#Reference<0.192931417.1724907521.178377>,
#Reference<0.192931417.1724907525.166008>},
{{#PID<0.53121.0>,
[:alias | #Reference<0.0.2605203.192931417.1724973057.178359>]},
#Reference<0.192931417.1724907521.178358>,
#Reference<0.192931417.1724907525.166007>},
{{#PID<0.53120.0>,
[:alias | #Reference<0.0.2605075.192931417.1724973057.178346>]},
#Reference<0.192931417.1724907521.178345>,
#Reference<0.192931417.1724907525.166006>},
{{#PID<0.53124.0>,
[:alias | #Reference<0.0.2605587.192931417.1724973059.165475>]},
#Reference<0.192931417.1724907523.165474>,
#Reference<0.192931417.1724907525.166005>},
{{#PID<0.53123.0>,
[:alias | #Reference<0.0.2605459.192931417.1724973059.165462>]},
#Reference<0.192931417.1724907523.165461>,
#Reference<0.192931417.1724907526.166938>},
{{#PID<0.53122.0>,
[:alias | #Reference<0.0.2605331.192931417.1724973062.166932>]},
#Reference<0.192931417.1724907526.166931>,
#Reference<0.192931417.1724907526.166933>},
{{#PID<0.53119.0>,
[:alias | #Reference<0.0.2604947.192931417.1724973059.165428>]},
#Reference<0.192931417.1724907523.165427>,
#Reference<0.192931417.1724907526.166914>},
{{#PID<0.53118.0>,
[:alias | #Reference<0.0.2604819.192931417.1724973058.180000>]},
#Reference<0.192931417.1724907522.179999>,
#Reference<0.192931417.1724907526.166908>},
{{#PID<0.53117.0>,
[:alias | #Reference<0.0.2604691.192931417.1724973064.157672>]},
#Reference<0.192931417.1724907528.157671>,
#Reference<0.192931417.1724907526.166907>},
{{#PID<0.53116.0>,
[:alias | #Reference<0.0.2604563.192931417.1724973062.166900>]},
#Reference<0.192931417.1724907526.166899>,
#Reference<0.192931417.1724907526.166901>},
{{#PID<0.53115.0>,
[:alias | #Reference<0.0.2604435.192931417.1724973062.166879>]},
#Reference<0.192931417.1724907526.166878>,
#Reference<0.192931417.1724907526.166881>},
{{#PID<0.53113.0>,
[:alias | #Reference<0.0.2604179.192931417.1724973062.166858>]},
#Reference<0.192931417.1724907526.166857>,
#Reference<0.192931417.1724907526.166860>},
{{#PID<0.53114.0>,
[:alias | #Reference<0.0.2604307.192931417.1724973058.179975>]},
#Reference<0.192931417.1724907522.179974>,
#Reference<0.192931417.1724907526.166859>},
{{#PID<0.53112.0>,
[:alias | #Reference<0.0.2604051.192931417.1724973063.158948>]},
#Reference<0.192931417.1724907527.158947>,
#Reference<0.192931417.1724907527.158949>},
{{#PID<0.53111.0>,
[:alias | #Reference<0.0.2603923.192931417.1724973059.165382>]},
#Reference<0.192931417.1724907523.165381>,
#Reference<0.192931417.1724907523.165384>},
{{#PID<0.53110.0>, [...]}, #Reference<0.192931417.1724907527.158928>,
#Reference<0.192931417.1724907526.166834>},
{{#PID<0.53109.0>, ...}, #Reference<0.192931417.1724907522.179945>, ...}
],
[
{{#PID<0.53099.0>,
[:alias | #Reference<0.0.2602387.192931417.1724973063.158896>]},
#Reference<0.192931417.1724907527.158895>,
#Reference<0.192931417.1724907528.157625>},
{{#PID<0.53096.0>,
[:alias | #Reference<0.0.2602003.192931417.1724973058.179914>]},
#Reference<0.192931417.1724907522.179913>,
#Reference<0.192931417.1724907528.157626>},
{{#PID<0.53102.0>,
[:alias | #Reference<0.0.2602771.192931417.1724973060.172418>]},
#Reference<0.192931417.1724907524.172417>,
#Reference<0.192931417.1724907528.157627>},
{{#PID<0.53098.0>,
[:alias | #Reference<0.0.2602259.192931417.1724973064.157624>]},
#Reference<0.192931417.1724907528.157623>,
#Reference<0.192931417.1724907528.157628>},
{{#PID<0.53107.0>,
[:alias | #Reference<0.0.2603411.192931417.1724973063.158915>]},
#Reference<0.192931417.1724907527.158914>,
#Reference<0.192931417.1724907528.157635>},
{{#PID<0.53108.0>,
[:alias | #Reference<0.0.2603539.192931417.1724973058.179933>]},
#Reference<0.192931417.1724907522.179932>,
#Reference<0.192931417.1724907527.158916>}
]}, #Reference<0.192931417.1724776450.239958>, 4, 0, 0, :lifo}
# queue keeps growing |
I've been able to reproduce the problem outside of Plausible with this script 1..1_000_000
|> Task.async_stream(
fn i ->
if rem(i, 666) == 0 do # we need sampling
{t, r} =
:timer.tc(fn ->
Hammer.check_rate("ingest:site:loadtest.site", 60_000, 1_000_000)
end)
# since IO.inspect is too slow and allows Poolboy to clear the queue
IO.inspect(t, label: i)
r
else
# and the "actual overload" happens in this "fast" branch
Hammer.check_rate("ingest:site:loadtest.site", 60_000, 1_000_000)
end
end,
ordered: false,
max_concurrency: 500
)
|> Stream.run() You might need to play with
|
Hello! thanks for the detail report. I took over the project and there is bunch of work I want to try to find time to work on eventually. I have not run into this issue yet but yea the perf is either pool boy or ETS because we bypass the Genserver in the latest version and directly talk to ETS. That being Said, Pool boy is configurable. Have you tried tweaking it and make it bigger just to see how it behaves? Removing poolboy might be tricky because we do need for solution like REDIS and other backend so having a pool in front is helpful. We could consider removing the pool and see what happens ? One thing is that. ETS is not shared accross VM so not sure how many people use it because you will not be able to do rate limiting with multiple pods correctly (or it will have to be approximate and set a value that is pod number dependent) I ll see if I can spend some time in the coming weeks but if you have an MR or some idea, feel free to submit it as well. |
👋
That would just delay the inevitable, I think. As #71 (comment) shows the overload would happen anyway once Poolboy stops keeping up, the pool size largely doesn't matter unless it matches the number of clients.
The pooling strategy could be moved to the adapter, the Ecto way.
According to hex.pm's recent downloads, 119339 (~one third) if them are probably for the ETS backend.
It could be actually worked around with sticky sessions or Phx PubSub
I'm happy to work on this since it seems to directly affect Plausible, I just wanted to check with the project maintainers first :) |
I've started exploring various approaches and the current fastest one is PlugAttack: https://github.com/ruslandoga/rate_limit |
I am not too familiar with Atomics yet but sounds like a good idea. I am not against moving the pooling strategy, we will need to create a major version correctly for it and all of the backend then |
@ruslandoga are you still working on splitting the MR? there are changes I was you had that I was going to tackle but if you are not then I ll start working on them |
Hi @epinault ! I'm currently not working on this. I do plan to return to it this month though. |
Sorry for disappearing and not keeping my promise :) I'm going to continue working on my PRs |
let me know if you have any update? |
There is one PR open: #94 :) It doesn't change the API and already results in better performance. And I'll check what's left of #72 (comment) tomorrow. UPDATE: first pass on the new API is done: #104 |
Describe the bug
I've been benchmarking hot paths in https://github.com/plausible/analytics and noticed that ExHammer check here becomes slower over time, from 11us in the beginning of k6 benchmark (it hits the same site every time, so
:hammer_ets_buckets
has a single key throughout the benchmark) to over 100ms in the end. And in some requests (when user-agents are cached) thatcheck_rate
call becomes the largest slice in the request flamechart** Provide the following details
The text was updated successfully, but these errors were encountered: