Skip to content

InflightReadsLimiter - limit the memory used by reads end-to-end (from storage/cache to the write to the consumer channel) - #18245

Merged
Jason918 merged 8 commits into
apache:masterfrom
eolivelli:impl/max-inflight-requests
Nov 11, 2022
Merged

InflightReadsLimiter - limit the memory used by reads end-to-end (from storage/cache to the write to the consumer channel)#18245
Jason918 merged 8 commits into
apache:masterfrom
eolivelli:impl/max-inflight-requests

Conversation

@eolivelli

@eolivelli eolivelli commented Oct 28, 2022

Copy link
Copy Markdown
Contributor

Motivation

Broker can go out of memory due to many reads enqueued on the PersistentDispatcherMultipleConsumers dispatchMessagesThread (that is used in case of dispatcherDispatchMessagesInSubscriptionThread set to true, that is the default value) The limit of the amount of memory retained due to reads MUST take into account also the entries coming from the Cache.

When dispatcherDispatchMessagesInSubscriptionThread is false (the behaviour of Pulsar 2.10) there is some kind of natural (but still unpredictable!!) back pressure mechanism because the thread that receives the entries from BK of the cache dispatches immediately and synchronously the entries to the consumer and releases them

Modifications

  • Add a new component (InflightReadsLimiter) that keeps track of the overall amount of memory retained due to inflight reads.
  • Add a new configuration entry managedLedgerMaxReadsInFlightSizeInMB
  • The feature is disabled by default
  • Add new metrics to track the status of the broker

Documentation

  • doc
  • doc-required
  • doc-not-needed
  • doc-complete

Matching PR in forked repository

PR in forked repository: eolivelli#19

Enrico Olivelli and others added 4 commits October 31, 2022 15:53
…m storage/cache to the write to the consumer channel)

Motivation:

Broker can go out of memory due to many reads enqueued on the PersistentDispatcherMultipleConsumers dispatchMessagesThread (that is used in case of dispatcherDispatchMessagesInSubscriptionThread set to true, that is the default value)
The limit of the amount of memory retained due to reads MUST take into account also the entries coming from the Cache.

When dispatcherDispatchMessagesInSubscriptionThread is false (the behaviour of Pulsar 2.10) there is some kind of natural (but still unpredictable!!) back pressure mechanism because the thread that receives the entries from BK of the cache dispatches immediately and synchronously the entries to the consumer and releases them

Modifications:

- Add a new component (InflightReadsLimiter) that keeps track of the overall amount of memory retained due to inflight reads.
- Add a new configuration entry managedLedgerMaxReadsInFlightSizeInMB
- The feature is disabled by default
- Add new metrics to track the values
@eolivelli
eolivelli force-pushed the impl/max-inflight-requests branch from 82ab48f to e1bdef6 Compare October 31, 2022 14:53
@codelipenghui

Copy link
Copy Markdown
Contributor

Broker can go out of memory due to many reads enqueued on the PersistentDispatcherMultipleConsumers dispatchMessagesThread

@eolivelli Does it only happen when the broker has many subscriptions? For one subscription, we always trigger the new read entries operation after sending messages to consumers. We only have a single active read entries operation at a time. Is it able to reproduce?

@eolivelli

Copy link
Copy Markdown
Contributor Author

@codelipenghui you are correct, the problems arise when you have a broker with many subscriptions on the same topic (and many topics).
There is no broker level guardrail at the moment.
With this patch the memory used to handle outbound traffic is capped and the limit is independent from the number of active subscriptions on the broker

@codecov-commenter

codecov-commenter commented Nov 10, 2022

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 35.17241% with 94 lines in your changes missing coverage. Please review.
✅ Project coverage is 47.20%. Comparing base (6373180) to head (9cc5757).
⚠️ Report is 3430 commits behind head on master.

Files with missing lines Patch % Lines
...eeper/mledger/impl/cache/InflightReadsLimiter.java 30.35% 37 Missing and 2 partials ⚠️
...keeper/mledger/impl/cache/RangeEntryCacheImpl.java 22.44% 36 Missing and 2 partials ⚠️
.../org/apache/bookkeeper/mledger/impl/EntryImpl.java 0.00% 10 Missing and 1 partial ⚠️
...ersistentStreamingDispatcherMultipleConsumers.java 0.00% 4 Missing ⚠️
...sistent/PersistentDispatcherMultipleConsumers.java 66.66% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##             master   #18245      +/-   ##
============================================
+ Coverage     47.00%   47.20%   +0.19%     
- Complexity    10358    10430      +72     
============================================
  Files           692      693       +1     
  Lines         67773    67916     +143     
  Branches       7258     7273      +15     
============================================
+ Hits          31860    32061     +201     
+ Misses        32365    32280      -85     
- Partials       3548     3575      +27     
Flag Coverage Δ
unittests 47.20% <35.17%> (+0.19%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...bookkeeper/mledger/ManagedLedgerFactoryConfig.java 87.50% <100.00%> (+0.83%) ⬆️
...keeper/mledger/impl/cache/PendingReadsManager.java 40.24% <100.00%> (+0.24%) ⬆️
...mledger/impl/cache/RangeEntryCacheManagerImpl.java 53.84% <100.00%> (+1.84%) ⬆️
...ache/pulsar/broker/ManagedLedgerClientFactory.java 62.16% <100.00%> (+1.05%) ⬆️
.../pulsar/broker/service/AbstractBaseDispatcher.java 60.81% <100.00%> (+2.89%) ⬆️
...pulsar/broker/service/PulsarCommandSenderImpl.java 73.84% <100.00%> (+9.44%) ⬆️
...sistent/PersistentDispatcherMultipleConsumers.java 58.49% <66.66%> (+1.14%) ⬆️
...ersistentStreamingDispatcherMultipleConsumers.java 0.00% <0.00%> (ø)
.../org/apache/bookkeeper/mledger/impl/EntryImpl.java 69.62% <0.00%> (-11.27%) ⬇️
...keeper/mledger/impl/cache/RangeEntryCacheImpl.java 45.79% <22.44%> (-6.31%) ⬇️
... and 1 more

... and 51 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@nicoloboschi nicoloboschi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

@codelipenghui codelipenghui left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Great change.
I have some minor comments.

Comment thread managed-ledger/src/main/java/org/apache/bookkeeper/mledger/impl/EntryImpl.java Outdated
Comment thread managed-ledger/src/main/java/org/apache/bookkeeper/mledger/impl/EntryImpl.java Outdated
public void readEntriesComplete(List<Entry> entries, Object ctx) {
if (!entries.isEmpty()) {
long size = entries.get(0).getLength();
estimatedEntrySize = size;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we use the avgMessagesPerEntry from the consumer?
The RangeEntryCacheImpl.java is shared across all the topics. If calculated at the topic level, we should be able to get a more precise estimated entry size.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately here we are in "managed-ledger" module and in order to get a value from the Dispatcher/Consumer I would have to change many internal APIs.

If the size of entries in the topics is similar for all the entries that I think that this is a good estimate.

@codelipenghui

Copy link
Copy Markdown
Contributor

/pulsarbot run-failure-checks

@eolivelli
eolivelli force-pushed the impl/max-inflight-requests branch from a843dff to 8efc1a1 Compare November 11, 2022 07:45
private long entryId;
ByteBuf data;

private Runnable onDeallocate;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is not volatile, but it seems that deallocate() could be called in other threads?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this is the pattern we use for every recyclable object, the same comment may apply to all the other fields.

@Jason918
Jason918 merged commit 6fec66b into apache:master Nov 11, 2022
@Technoboy- Technoboy- modified the milestones: 2.12.0, 2.11.0 Nov 14, 2022
Technoboy- pushed a commit that referenced this pull request Nov 14, 2022
…m storage/cache to the write to the consumer channel) (#18245)

* InflightReadsLimiter - limit the memory used by reads end-to-end (from storage/cache to the write to the consumer channel)

Motivation:

Broker can go out of memory due to many reads enqueued on the PersistentDispatcherMultipleConsumers dispatchMessagesThread (that is used in case of dispatcherDispatchMessagesInSubscriptionThread set to true, that is the default value)
The limit of the amount of memory retained due to reads MUST take into account also the entries coming from the Cache.

When dispatcherDispatchMessagesInSubscriptionThread is false (the behaviour of Pulsar 2.10) there is some kind of natural (but still unpredictable!!) back pressure mechanism because the thread that receives the entries from BK of the cache dispatches immediately and synchronously the entries to the consumer and releases them

Modifications:

- Add a new component (InflightReadsLimiter) that keeps track of the overall amount of memory retained due to inflight reads.
- Add a new configuration entry managedLedgerMaxReadsInFlightSizeInMB
- The feature is disabled by default
- Add new metrics to track the values

* Change error message

* checkstyle

* Fix license

* remove duplicate method after cherry-pick

* Rename onDeallocate
liangyepianzhou pushed a commit that referenced this pull request Sep 15, 2023
…m storage/cache to the write to the consumer channel) (#18245)

* InflightReadsLimiter - limit the memory used by reads end-to-end (from storage/cache to the write to the consumer channel)

Motivation:

Broker can go out of memory due to many reads enqueued on the PersistentDispatcherMultipleConsumers dispatchMessagesThread (that is used in case of dispatcherDispatchMessagesInSubscriptionThread set to true, that is the default value)
The limit of the amount of memory retained due to reads MUST take into account also the entries coming from the Cache.

When dispatcherDispatchMessagesInSubscriptionThread is false (the behaviour of Pulsar 2.10) there is some kind of natural (but still unpredictable!!) back pressure mechanism because the thread that receives the entries from BK of the cache dispatches immediately and synchronously the entries to the consumer and releases them

Modifications:

- Add a new component (InflightReadsLimiter) that keeps track of the overall amount of memory retained due to inflight reads.
- Add a new configuration entry managedLedgerMaxReadsInFlightSizeInMB
- The feature is disabled by default
- Add new metrics to track the values

* Change error message

* checkstyle

* Fix license

* remove duplicate method after cherry-pick

* Rename onDeallocate

(cherry picked from commit 6fec66b)
liangyepianzhou added a commit to streamnative/pulsar-archived that referenced this pull request Sep 28, 2023
* InflightReadsLimiter - limit the memory used by reads end-to-end (from storage/cache to the write to the consumer channel) (apache#18245)

* InflightReadsLimiter - limit the memory used by reads end-to-end (from storage/cache to the write to the consumer channel)

Motivation:

Broker can go out of memory due to many reads enqueued on the PersistentDispatcherMultipleConsumers dispatchMessagesThread (that is used in case of dispatcherDispatchMessagesInSubscriptionThread set to true, that is the default value)
The limit of the amount of memory retained due to reads MUST take into account also the entries coming from the Cache.

When dispatcherDispatchMessagesInSubscriptionThread is false (the behaviour of Pulsar 2.10) there is some kind of natural (but still unpredictable!!) back pressure mechanism because the thread that receives the entries from BK of the cache dispatches immediately and synchronously the entries to the consumer and releases them

Modifications:

- Add a new component (InflightReadsLimiter) that keeps track of the overall amount of memory retained due to inflight reads.
- Add a new configuration entry managedLedgerMaxReadsInFlightSizeInMB
- The feature is disabled by default
- Add new metrics to track the values

* Change error message

* checkstyle

* Fix license

* remove duplicate method after cherry-pick

* Rename onDeallocate

(cherry picked from commit 6fec66b)
(cherry picked from commit 47c98e5)

* [fix][broker][branch-2.10] limit the memory used by reads end-to-end

(cherry picked from commit eeb80e1)

* remove gpg plugin

* remove release profile

* remove release plugin

* Revert "remove release plugin"

This reverts commit 20522ea.

* Revert "remove release profile"

This reverts commit 64627fd.

* Revert "remove gpg plugin"

This reverts commit 8054d59.

---------

Co-authored-by: Enrico Olivelli <eolivelli@apache.org>
mattisonchao pushed a commit to streamnative/pulsar-archived that referenced this pull request Dec 28, 2023
* InflightReadsLimiter - limit the memory used by reads end-to-end (from storage/cache to the write to the consumer channel) (apache#18245)

* InflightReadsLimiter - limit the memory used by reads end-to-end (from storage/cache to the write to the consumer channel)

Motivation:

Broker can go out of memory due to many reads enqueued on the PersistentDispatcherMultipleConsumers dispatchMessagesThread (that is used in case of dispatcherDispatchMessagesInSubscriptionThread set to true, that is the default value)
The limit of the amount of memory retained due to reads MUST take into account also the entries coming from the Cache.

When dispatcherDispatchMessagesInSubscriptionThread is false (the behaviour of Pulsar 2.10) there is some kind of natural (but still unpredictable!!) back pressure mechanism because the thread that receives the entries from BK of the cache dispatches immediately and synchronously the entries to the consumer and releases them

Modifications:

- Add a new component (InflightReadsLimiter) that keeps track of the overall amount of memory retained due to inflight reads.
- Add a new configuration entry managedLedgerMaxReadsInFlightSizeInMB
- The feature is disabled by default
- Add new metrics to track the values

* Change error message

* checkstyle

* Fix license

* remove duplicate method after cherry-pick

* Rename onDeallocate

(cherry picked from commit 6fec66b)
(cherry picked from commit 47c98e5)

* [fix][broker][branch-2.10] limit the memory used by reads end-to-end

(cherry picked from commit eeb80e1)

* remove gpg plugin

* remove release profile

* remove release plugin

* Revert "remove release plugin"

This reverts commit 20522ea.

* Revert "remove release profile"

This reverts commit 64627fd.

* Revert "remove gpg plugin"

This reverts commit 8054d59.

---------

Co-authored-by: Enrico Olivelli <eolivelli@apache.org>
narmathaansp pushed a commit to sajithsebastian/pulsar that referenced this pull request Feb 14, 2024
…che#5920)

* InflightReadsLimiter - limit the memory used by reads end-to-end (from storage/cache to the write to the consumer channel) (apache#18245)

* InflightReadsLimiter - limit the memory used by reads end-to-end (from storage/cache to the write to the consumer channel)

Motivation:

Broker can go out of memory due to many reads enqueued on the PersistentDispatcherMultipleConsumers dispatchMessagesThread (that is used in case of dispatcherDispatchMessagesInSubscriptionThread set to true, that is the default value)
The limit of the amount of memory retained due to reads MUST take into account also the entries coming from the Cache.

When dispatcherDispatchMessagesInSubscriptionThread is false (the behaviour of Pulsar 2.10) there is some kind of natural (but still unpredictable!!) back pressure mechanism because the thread that receives the entries from BK of the cache dispatches immediately and synchronously the entries to the consumer and releases them

Modifications:

- Add a new component (InflightReadsLimiter) that keeps track of the overall amount of memory retained due to inflight reads.
- Add a new configuration entry managedLedgerMaxReadsInFlightSizeInMB
- The feature is disabled by default
- Add new metrics to track the values

* Change error message

* checkstyle

* Fix license

* remove duplicate method after cherry-pick

* Rename onDeallocate

(cherry picked from commit 6fec66b)
(cherry picked from commit 47c98e5)

* [fix][broker][branch-2.10] limit the memory used by reads end-to-end

(cherry picked from commit eeb80e1)

* remove gpg plugin

* remove release profile

* remove release plugin

* Revert "remove release plugin"

This reverts commit 20522ea.

* Revert "remove release profile"

This reverts commit 64627fd.

* Revert "remove gpg plugin"

This reverts commit 8054d59.

---------

Co-authored-by: Enrico Olivelli <eolivelli@apache.org>
coderzc pushed a commit to coderzc/pulsar that referenced this pull request Aug 14, 2024
…che#5920)

* InflightReadsLimiter - limit the memory used by reads end-to-end (from storage/cache to the write to the consumer channel) (apache#18245)

* InflightReadsLimiter - limit the memory used by reads end-to-end (from storage/cache to the write to the consumer channel)

Motivation:

Broker can go out of memory due to many reads enqueued on the PersistentDispatcherMultipleConsumers dispatchMessagesThread (that is used in case of dispatcherDispatchMessagesInSubscriptionThread set to true, that is the default value)
The limit of the amount of memory retained due to reads MUST take into account also the entries coming from the Cache.

When dispatcherDispatchMessagesInSubscriptionThread is false (the behaviour of Pulsar 2.10) there is some kind of natural (but still unpredictable!!) back pressure mechanism because the thread that receives the entries from BK of the cache dispatches immediately and synchronously the entries to the consumer and releases them

Modifications:

- Add a new component (InflightReadsLimiter) that keeps track of the overall amount of memory retained due to inflight reads.
- Add a new configuration entry managedLedgerMaxReadsInFlightSizeInMB
- The feature is disabled by default
- Add new metrics to track the values

* Change error message

* checkstyle

* Fix license

* remove duplicate method after cherry-pick

* Rename onDeallocate

(cherry picked from commit 6fec66b)
(cherry picked from commit 47c98e5)

* [fix][broker][branch-2.10] limit the memory used by reads end-to-end

(cherry picked from commit eeb80e1)

* remove gpg plugin

* remove release profile

* remove release plugin

* Revert "remove release plugin"

This reverts commit 20522ea.

* Revert "remove release profile"

This reverts commit 64627fd.

* Revert "remove gpg plugin"

This reverts commit 8054d59.

---------

Co-authored-by: Enrico Olivelli <eolivelli@apache.org>
nodece pushed a commit to nodece/pulsar that referenced this pull request Sep 10, 2024
…m storage/cache to the write to the consumer channel) (apache#18245)

* InflightReadsLimiter - limit the memory used by reads end-to-end (from storage/cache to the write to the consumer channel)

Motivation:

Broker can go out of memory due to many reads enqueued on the PersistentDispatcherMultipleConsumers dispatchMessagesThread (that is used in case of dispatcherDispatchMessagesInSubscriptionThread set to true, that is the default value)
The limit of the amount of memory retained due to reads MUST take into account also the entries coming from the Cache.

When dispatcherDispatchMessagesInSubscriptionThread is false (the behaviour of Pulsar 2.10) there is some kind of natural (but still unpredictable!!) back pressure mechanism because the thread that receives the entries from BK of the cache dispatches immediately and synchronously the entries to the consumer and releases them

Modifications:

- Add a new component (InflightReadsLimiter) that keeps track of the overall amount of memory retained due to inflight reads.
- Add a new configuration entry managedLedgerMaxReadsInFlightSizeInMB
- The feature is disabled by default
- Add new metrics to track the values

* Change error message

* checkstyle

* Fix license

* remove duplicate method after cherry-pick

* Rename onDeallocate

(cherry picked from commit 6fec66b)
Signed-off-by: Zixuan Liu <nodeces@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants