-
Notifications
You must be signed in to change notification settings - Fork 818
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
Fix #629: Adding subscriptions is very slow #633
Conversation
f4fae07
to
2d978f3
Compare
80f1f9c
to
7d02977
Compare
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.
Hi @amzexin
the PR changes a lot the original data structure which was inspired on lock free algorithms on CTrie hash.
I would prefer a PR that only resolve the problem on the loop used in the insertion. The copy of constructor, and the copy in general shouldn't be a problem, as demonstrated by the CTrie hashmap. The copy and the presence of INode (indirect node) is fundamental for correct concurrent access to data structure.
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.
Hi @amzexin
thank's for your contribution but, as I described in my previous comment, the changes you are proposing other then resolving the slow search loop also completely changes the spirit of the original data structure that was inspired by CTrie.
I'm happy to review a PR that just resolve the problem on the slow search loop replacing it hash lookup.
Hi @andsel CAS is a good idea of concurrency lock-free, but it doesn't seem appropriate on CTrie. Because the original Set and List must be copied before adding a subscription or inode in CNode. Take an exaggerated example:if CNode has 1000000 Subscriptions, when we need to add the 1000001st subscription, we must copy these 1000000 Subscription first, then add 1 Subscription, then replace the original CNode by CAS, and when CTrie.insert returns Action.REPEAT, we need to do it again. And this will cause the project to start very slowly, because CTrieSubscriptionDirectory.init will call ctrie.addToTree method. CTrie added 620k Subscriptions need cost 85 minutes, this means that it takes 85 minutes for the project to start, which is very dreadful😱
Finally, I have a question. Ctrie must be lock-free? If the answer is yes, can you provide some optimization ideas for CNode.copy? I'm willing to try. |
Hi @amzexin
the answer is yes, because CTrie is accessed concurrently by the subscriber and publisher threads.
As was initially explained in this comment the slowness was related to the linear scan on insertion and not to the copy. |
The immediate problem is the looping. This is especially bad because it also happens when matching subscriptions for a publish action. I think that needs to be fixed first. Hashtables are a possible solution, but simply sorting the array by token already improves things drastically. See my experiment in #630. The copy is bad under high load, on large trees, since many failed inserts will happen, and many re-tries, and this will increase the load even further. A simple test should be made if adding a lock-on-update to the current code is faster under load than the current retry-until-success. Reading can remain lock-free that way. |
This is already fixed by #630, please @timeway could you check if it solves your issue and in case close the PR please 🙏 ? |
Indeed, this is yet another use-case. This one has few topics, but each topic has many subscribers. |
In #758 I converted the HashSet to an ArrayList, since copying an array is much faster than copying a Set. The test is still the slowest of the three (23 seconds), but it doesn't time out any more. |
Converted subscription from HashSet to ArrayList Copying a Set is much slower than copying an ArrayList. Since the slow part in the code is the copy step, using an ArrayList is much faster overall. Since the code using the subscriptions only iterates over them, the change from Set to List makes no real difference. Fixes #633
refactor CTrie