Skip to content

[feat][ml] Add stateless RandomReader to ManagedLedger - #25880

Open
dao-jun wants to merge 3 commits into
apache:masterfrom
dao-jun:dev/ml_add_readentries
Open

[feat][ml] Add stateless RandomReader to ManagedLedger#25880
dao-jun wants to merge 3 commits into
apache:masterfrom
dao-jun:dev/ml_add_readentries

Conversation

@dao-jun

@dao-jun dao-jun commented May 27, 2026

Copy link
Copy Markdown
Member

Motivation

Add stateless RandomReader to ML.

Today every read path in managed-ledger goes through a ManagedCursor. A cursor is comparatively heavyweight for several access patterns:

  1. Cursorless reads for downstream consumers. Reading via a cursor requires acknowledging entries — any un-acked read grows the backlog and interferes with retention/trimming. Reading messages scattered across arbitrary positions further requires repeated seek operations. A lightweight, stateless reader (no position, no
    ack, no backlog, no trimming hold) lets downstream projects batch-read entries directly by position, without those side effects.
  2. Cursorless batch reads for Pulsar itself. Internal components that only need to fetch entries at given positions (backfill, repair, offset-based lookups) currently pay the full cursor overhead. A cursorless primitive gives them a cheaper path.
  3. Groundwork for a future RandomReader client. This PR provides the server-side managed-ledger primitive that a planned RandomReader client will build on. That client is intended to support both pure random reads (serving metadata-style lookups) and sequential reads (serving stream-processing frameworks such as Flink).

Modifications

  • Introduce RandomReader, a cursorless, stateless reader (public final class ... implements AutoCloseable) in the managed-ledger impl package — renamed from the former RandomReaderImpl; the previous RandomReader interface is removed. A reader maintains no read position, performs no ack, contributes no backlog, and does
    not prevent ledger trimming; reads do not wait for future entries, and callers must release every returned Entry. Reads honor count, position (maxPosition, inclusive), and estimated-size limits.
  • Back it with RandomReaders (a per-managed-ledger reader registry) and OpRandomReadEntries (the cross-ledger batch-read operation), both in the impl package. RandomReader instances are created only via RandomReaders#create(boolean populateCache) (package-private constructor).
  • Expose creation through ManagedLedgerImpl#randomReaders() (returning the registry) rather than on the ManagedLedger interface, since RandomReader support is bound to ManagedLedgerImpl's entry cache and is not a pluggable contract. Reader lifecycle is tied to managed-ledger close/fence.
  • Integrate with the entry cache: a populateCache=true reader writes read misses back to the cache and seeds the write tail, and contributes to the add-path expectedReadCount (via OpAddEntry / EntryReadCountHandlerImpl) so cache-eviction weight reflects active random readers; shouldCacheAddedEntry() now also accounts for
    them. A populateCache=false reader serves cache hits without write-back, avoiding cache pollution for truly random, low-frequency access (cache integration touches EntryCache / RangeEntryCacheImpl).
  • Add unit tests in ManagedLedgerTest covering read semantics, position/size boundaries, cross-ledger reads, error/partial results, close/fence lifecycle, and both cache modes.

Verifying this change

  • Make sure that the change passes the CI checks.

(Please pick either of the following options)

This change is a trivial rework / code cleanup without any test coverage.

(or)

This change is already covered by existing tests, such as (please describe tests).

(or)

This change added tests and can be verified as follows:

(example:)

  • Added integration tests for end-to-end deployment with large payloads (10MB)
  • Extended integration test for recovery after broker failure

Does this pull request potentially affect one of the following parts:

If the box was checked, please highlight the changes

  • Dependencies (add or upgrade a dependency)
  • The public API
  • The schema
  • The default values of configurations
  • The threading model
  • The binary protocol
  • The REST endpoints
  • The admin CLI options
  • The metrics
  • Anything that affects deployment

@dao-jun
dao-jun force-pushed the dev/ml_add_readentries branch from b6556fc to f6acd6d Compare July 16, 2026 04:39
# Conflicts:
#	managed-ledger/src/test/java/org/apache/bookkeeper/mledger/impl/ManagedLedgerTest.java
@dao-jun dao-jun changed the title [feat][pip] PIP-480: Add readEntries method to ManagedLedger [feat][pip] PIP-480: Add stateless RandomReader to ManagedLedger Jul 17, 2026
@dao-jun
dao-jun force-pushed the dev/ml_add_readentries branch from 68960bc to 28bd3dd Compare July 17, 2026 14:21
@dao-jun dao-jun modified the milestones: 5.0.0-M1, 5.0.0-M2 Jul 17, 2026

@BewareMyPower BewareMyPower 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.

expected read count is not taken carefully.

In EntryImpl:

    protected void deallocate() {
        if (decreaseReadCountOnRelease && readCountHandler != null) {
            readCountHandler.markRead();
        }

The read count will always be decreased no matter whether the read op is on a RandomReader. This could affect the cache eviction strategy

@dao-jun

dao-jun commented Jul 22, 2026

Copy link
Copy Markdown
Member Author

@BewareMyPower fixed, PTAL

Comment thread managed-ledger/src/main/java/org/apache/bookkeeper/mledger/ManagedLedger.java Outdated
@dao-jun dao-jun changed the title [feat][pip] PIP-480: Add stateless RandomReader to ManagedLedger [feat] Add stateless RandomReader to ManagedLedger Jul 23, 2026
@dao-jun dao-jun changed the title [feat] Add stateless RandomReader to ManagedLedger [feat][ml] Add stateless RandomReader to ManagedLedger Jul 23, 2026
@dao-jun dao-jun removed the type/PIP label Jul 23, 2026
Comment thread managed-ledger/src/main/java/org/apache/bookkeeper/mledger/RandomReader.java Outdated
@dao-jun
dao-jun force-pushed the dev/ml_add_readentries branch from e1e90b5 to 62153b9 Compare July 23, 2026 16:57
@dao-jun
dao-jun force-pushed the dev/ml_add_readentries branch from 62153b9 to 7789c55 Compare July 23, 2026 19:44
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.

2 participants