[improve][ml] Parse message metadata at entry cache insert time instead of under the wrapper write lock - #26463
Open
merlimat wants to merge 1 commit into
Open
Conversation
…ad of under the wrapper write lock Motivation Profiling showed EntryImpl.initializeMessageMetadataIfNeeded being called from RangeCacheEntryWrapper.withWriteLock on the cache read path. Entries inserted from the add path (OpAddEntry) carried no parsed metadata, so the first cache read of every tailing entry took the wrapper write lock, parsed the metadata and serialized all concurrent readers of that entry behind it. Modifications - RangeEntryCacheImpl.insert parses the message metadata once before creating the cached entry, so both the add path and the read-miss path insert entries that already carry metadata. - RangeCacheEntryWrapper marks messageMetadataInitialized at creation when the value already has metadata, so reads never take the write lock for it. The lazy initialization remains as a fallback for values inserted without it. - Add a unit test covering insert-time parsing.
Member
There's a PR to reduce metadata parsing on the publish path, #25555. The metadata gets parsed multiple times currently. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Profiling a broker under a tailing workload showed
EntryImpl.initializeMessageMetadataIfNeededbeing invoked fromRangeCacheEntryWrapper.withWriteLock, i.e. a write lock taken on the entry cache read path.Entries reach the cache through two paths. The read-miss path in
RangeEntryCacheImpl.readFromStoragealready parses the message metadata before inserting. The tailing-write path inOpAddEntryinserts entries with no parsed metadata, so the first cache read of every freshly published entry has to take the wrapper write lock, parse the metadata inside it, and every other cursor reading the same entry is serialized behind that lock. With several subscriptions tailing a topic this is the common case, not the exception.Modifications
RangeEntryCacheImpl.insertnow parses the message metadata once before creating the cached entry. Sinceinsertis the single chokepoint for both the add path and the read-miss path, the cached copy always carries its metadata. On the read-miss path this is a no-op because the entry is already parsed.RangeCacheEntryWrapper.withNewInstancemarksmessageMetadataInitializedwhen the value already has metadata, so reads stay on the optimistic-read branch and never enter the write lock for it. The lazy initialization is kept as a fallback for values inserted without metadata (non-EntryImplvalues or a failed parse).The parse cost itself is not removed, it moves from the first read to the add path on the managed ledger executor. The net effect is that each entry is parsed exactly once, with no lock and no cross-cursor contention on the read path.
Verifying this change
This change added tests and can be verified as follows:
RangeEntryCacheImplTest.testInsertParsesMessageMetadata, which inserts an entry built from a real serialized message with no pre-parsed metadata and asserts that the insert itself populated it.RangeCacheTest,RangeCacheRemovalQueueTestandRangeEntryCacheImplTestpass.Does this pull request potentially affect one of the following parts:
If the box was checked, please highlight the changes