[enh] Broker - Shared subscription: run filters in a separate (per-subscription) thread (dispatcherDispatchMessagesInSubscriptionThread) - #16603
Conversation
| dispatcherMaxReadBatchSize=100 | ||
|
|
||
| # Dispatch messages and execute broker side filters in a per-subscription thread | ||
| dispatcherDispatchMessagesInSubscriptionThread=true |
There was a problem hiding this comment.
Should we keep it false by default? Most of the users don't have broker-side filters. Enabled by default will introduce more thread switching.
There was a problem hiding this comment.
I am adding this flag only to rollback in case of problem with particular workloads.
We are doing performance testing, I believe that this new behaviour is generally better, not only for the case of server side filters, but especially in these cases:
- multiple subscriptions on the same topic
- concurrent produce and consume
| } | ||
|
|
||
| protected void sendMessagesToConsumers(ReadType readType, List<Entry> entries) { | ||
| protected synchronized void sendMessagesToConsumers(ReadType readType, List<Entry> entries) { |
There was a problem hiding this comment.
It's better to have a check and only apply the lock if dispatcherDispatchMessagesInSubscriptionThread is enabled.
There was a problem hiding this comment.
sendMessagesToConsumers is usually called by readEntriesComplete, that is already synchronized
the JVM is smart enough to understand that there is no need for extra work for synchronized
There was a problem hiding this comment.
Alternatively, I think you could add a synchronized (this) block around the runnable's call to this method.
There was a problem hiding this comment.
there is no difference.
I think that this is not a problem.
@codelipenghui do you agree ?
| topic.getBrokerService().getTopicOrderedExecutor() | ||
| .executeOrdered(name, | ||
| safeRun(() -> sendMessagesToConsumers(readType, entries))); |
There was a problem hiding this comment.
We can have a pinned executor instead of selecting the executor for each operation.
There was a problem hiding this comment.
this is an interesting point.
Let me investigate.
I am not sure about the threadpool that we can use here as "pinned", I would like to pick a thread from "TopicOrderedExecutor"
There was a problem hiding this comment.
@codelipenghui I have pinned the Subscription to a thread.
I think that this is what you suggested
thanks
| // sendMessagesToConsumers is responsible for running broker-side filters | ||
| // that may be quite expensive | ||
| topic.getBrokerService().getTopicOrderedExecutor() | ||
| .executeOrdered(name, |
There was a problem hiding this comment.
- do we care about potential (unchecked) RejectedExecutionException here?
- we may need to prevent this code from submitting unlimited amount of runnables into that executor / handle long backlog.
There was a problem hiding this comment.
do we care about potential (unchecked) RejectedExecutionException here?
we usually don't deal with RejectedExecutionException in Dispatcher code.
in any case even if the execution is rejected the Dispatcher will read more entries for some other reasons
we may need to prevent this code from submitting unlimited amount of runnables into that executor / handle long backlog.
This shouldn't be a problem because there is a "natural" backpressure mechanism here, we trigger this code when new entries are read from storage (BK/Offloaders) but we request new reads from Storage after dispatching them to Consumers.
So usually there is only one of this tasks that is pending for the subscription.
|
@eolivelli Please provide a correct documentation label for your PR. |
019493d to
7d80f8b
Compare
…ead (dispatcherDispatchMessagesInSubscriptionThread) (cherry picked from commit 9d0ae97)
709c3ad to
5c1cf84
Compare
…ersistent/PersistentStickyKeyDispatcherMultipleConsumersTest.java Co-authored-by: Lari Hotari <lhotari@users.noreply.github.com>
|
/pulsarbot rerun-failure-checks |
… (per-subscription) thread (dispatcherDispatchMessagesInSubscriptionThread) (apache#16603)" Fixes apache#16802 This reverts commit abe5d15.
### Motivation See apache#16802 and the discussion in apache#16803. Before reverting apache#16603, disabling the `dispatcherDispatchMessagesInSubscriptionThread` option first. ### Modifications Change the default value of `dispatcherDispatchMessagesInSubscriptionThread` to false.
|
This enhancement may fix the |
|
And this PR has bug, the fix PR at here: #16812 |
|
Hi, @gaoran10 |
|
@eolivelli Please provide a correct documentation label for your PR. |
|
@eolivelli just wanted to check in - any docs required to be updated for this improvement? |
Motivation
Server side filters may be very heavy weight, and currently they are running (very often) in the same thread that handles writes and also all the subscriptions.
We want to improve performances in presence of heavy server side filters:
Modifications
Add a new flag,
dispatcherDispatchMessagesInSubscriptionThread, enabled by default, to dispatch messages to consumers in a Shared subscription using a separate thread than the BK executor thread.With this patch we choose a thread depending on the topic + subscription name and we run the actual dispatching of messages (sendMessagesToConsumers) in such thread.
Verifying this change
I did some manual testing with a dummy filter that slows down (Thread.sleep(100)) consumption and even with a simply workload (50k msg/s) I have verified that: