Comments (4)
from phoenix_pubsub.
Hi José,
thanks for your quick reply. After a quick fight with Firenest I was able to start the benchmark.
With two partitions it doesn't max out all schedulers but still takes ages (stopped the benchmark after 2 minutes for 500k subscriptions) , the reduction counts clearly show both PIDPartition
processes as the ones taking the time.
Increasing the number of partitions increases the load, with 8 partitions leading to the same pattern of 8/8 schedulers being maxed out, the runtime is equivalent: https://dsh.re/aa50c
from phoenix_pubsub.
Sooo..I figured it out, damn synthetic benchmarks.
I subscribed the test processes to all the same channels, so I basically had 10 channels with 50k subscribers each. Each deletion then is a lookup in the pid
ETS table for finding subscriptions (fast as it's a lookup by key) plus 10 match_delete
. The match_delete
then finds the key in ETS (quick) but has to iterate through all 50k items to find the pid. This occurs 10 times for each item.
If my (rather bad) mathematics are correct the worst case number of lookups that goes key by key would be (500000^2 + 500000)/2 which is roughly 125 billion lookups.
I now rebuilt my sample with a random set of 100 channels I subscribe to, this changes the picture drastically, sadly the benchmarking becomes a lot more complex since picking the random channels makes subscribing slow.
In conclusion I suspect there is a huge bottleneck in the cleanup when lots of subscribers subscribe to the same topic, as this means ETS has to go through all items with the shared topic key to find which exact element to delete.
Edit: I see one viable workaround if one would still want to have lots of subscribers on a single key: Subscribe the processes to key + rand(0, n)
, sending to all by sending to key+0
up to key+n
.
This will then distribute the number of duplicates in the table equally over 1/n keys and therefore drastically reduce the impact of this issue. As sending is a simple lookup the overhead on the sending site is negligible.
Edit^2:
I Implemented my workaround:
def distributed_publish(id, message) do
for i <- 1..128 do
Firenest.PubSub.broadcast(FFL.PubSub, id <> "-part" <> Integer.to_string(i), message)
end
end
def distributed_subscribe(id) do
distributed_id = id <> "-part" <> Integer.to_string(:rand.uniform(128))
Firenest.PubSub.subscribe(FFL.PubSub, distributed_id)
end
This improves the behaviour drastically (first bump is starting, then waiting, the terminating all instances):
Compared to not distributing:
I would implement this a little nicer if there is interest, possibly hashing the key or something similar.
from phoenix_pubsub.
Now that we have sharding in place, this should be much improved. Thanks!
from phoenix_pubsub.
Related Issues (20)
- Latest Version of Phoenix.PubSub in Hex HOT 1
- broadcast_from!/4 is undefined or private HOT 1
- Network traffic up for 20 minutes after a server restart
- Release v1.1.3 suppressing warnings HOT 1
- Where is version 2.0? HOT 1
- It may be helpful for users, if parallel option can be provided when starting Registry. Without it partitions in registry executes sequentially. HOT 1
- unknown registry: XXX.PubSub HOT 4
- RFC: Provide a way to mass update presences HOT 1
- topic forced to be string HOT 1
- Race condition causing data inconsistency when nodes are coming up
- Does Phoenix.PubSub itself support subscribing to wildcard topics? HOT 1
- PubSub registry fails to start or race condition when testing? HOT 3
- [Feature Request] Be able to transform a module into a Pub.Sub HOT 6
- Unsubscribe all HOT 2
- v2.1 and v2.0 are incompatible
- Odd Jason Encoding error after new release HOT 2
- Broken Build Status link
- Presence list keep growing when using Presence.update HOT 3
- Presence stops working after ~1 week HOT 5
- Politely request release of 2.1.4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from phoenix_pubsub.