Downloading Recent Committed Ledger Entries #8207
Replies: 3 comments
|
Thanks Amaury, this would really help us index fresher data. Just a few questions: 1. Will turning this on slow the node down? We use 100MB ledger chunks in ACL/MST and poll for new committed chunks every 15 seconds. That's a lot bigger than the 5MB default, so just want to confirm the cost for us. The write-up says the node copies the entries while holding the ledger state lock. Is that the same lock the node needs to commit new transactions? If so, roughly how long is it held for a large prefix like ours? I think this probably also depends on how the synchronizer should poll, which way were you recommending:
Which way should we go with for our case? Also, should the node put a size cap on how much it materializes at once, so a client like ledger synchronizer can't accidentally make it do a lot of work? 2. When is it safe to delete a Our setup has two parts: one component (ledger synchronizer) downloads chunks to a file share, and a separate one indexes from that share on a slightly slower schedule. So Our assumption is: we can delete a prefix covering entries 101–140 once we've downloaded real We can participate and give real numbers or benchmark our setup at 100MB chunks and production write rates. Thanks so much Amaury! |
The number and size of prefix files will be decided by the node, same as today for committed files. Let us run some numbers before we go too deep into this.
|
|
taicchoumsft draft implementation in #8214, I probably won't have time to review in depth until next week, but if you want to take an early look, please do. |
Uh oh!
There was an error while loading. Please reload this page.
Proposal: Downloading Recent Committed Ledger Entries
Problem
The existing
GETandHEAD /node/ledger_chunkendpoints expose only ledgerfiles whose on-disk names end in
.committed. This is safe, but it can lag theservice's commit point: the current ledger file may contain a committed prefix
followed by uncommitted entries, and it is not renamed until the file is
complete and all of its entries are committed.
Clients that need the latest committed history must currently force a chunk
boundary and wait for the new
.committedfile. The API could insteadmaterialize a valid, immutable ledger chunk from the committed prefix without
reading or exposing any uncommitted entry. These synthetic resources use a
.committed_prefixsuffix so they cannot be confused with canonical physical.committedfiles.Proposed API
Extend the existing locator with an opt-in query parameter:
Without
include_committed_prefix=true, behavior remains unchanged.With the option enabled, the locator first looks for a normal
.committedfile, as it does today. If none is available, but the requested sequence number
is locally available and no later than the node's committed index, it selects
an exact committed range and returns:
Add an exact-range endpoint:
This endpoint:
.committed_prefixchunk name;404unless every requested entry is locally available and committed;bytes, and positions table;
x-ms-ccf-ledger-chunk-nameto the.committed_prefixname; andx-ms-ccf-ledger-chunk-kind: committed-prefixandCache-Control: no-store; andRange,ETag,If-None-Match,Want-Repr-Digest,and
Repr-Digestbehavior.The exact URL is important. Although the commit index may advance, the bytes
identified by
ledger_<start>-<end>.committed_prefixnever change. A clientcan therefore retry or resume that download safely.
Cache-Control: no-storeprevents HTTP caches from retaining the response, while the suffix and
chunk-kind header tell application clients that this is not a canonical
physical chunk and should not be archived or installed as a
.committedfile.no-cacheis not sufficient because it permits storage and only requiresrevalidation.
The locator should use
307 Temporary Redirect, rather than the existing308for this case, because the selected end may advance between requests. Its
redirects and
404responses should includeCache-Control: no-storeso thata cache cannot pin an older range or cache the temporary absence of a range.
Current node redirect behavior should otherwise remain: a backup that cannot
locate a recent native chunk redirects to the primary, while any node that can
validate and reconstruct an exact range may serve the exact-range request.
Why More Than One Such Chunk Can Exist
The synthetic chunks are immutable views, not aliases for a mutable physical
file. For example:
.committedfile ends at sequence number 100.index is 140. The API emits
ledger_101-140.committed_prefix.index is 165. The next request starts at 141, so the API emits
ledger_141-165.committed_prefix.Both synthetic chunks remain valid even though they came from the same
in-progress physical file. Extending or replacing the first response would
break stable names, resumable downloads, and incremental backup.
There can also be two contiguous prefixes available at the same time because
physical chunking can run ahead of the commit watermark. For example:
ledger_1-100.committed.unsuffixed files
ledger_101-150andledger_151-200, plus the active fileledger_201.been published with
.committednames.ledger_101-150.committed_prefixandledger_151-200.committed_prefix.These two resources are distinct, contiguous, and contain only committed
entries. The implementation should preserve the existing physical boundaries
rather than collapse them into one response, and must iterate all eligible
unsuffixed files rather than assuming there is only one.
Implementation Sketch
an immutable
{start, end, bytes}result. Under the ledger state lock, itshould snapshot the committed index, reject a start beyond it, copy only
entries at or below it, and choose an end at a valid signature boundary.
layout already produced by
LedgerFile::complete()andpython/src/ccf/split_ledger.py: an offset header, raw entries, and 32-bitentry positions. Do not alter transaction bytes.
AbstractReadLedgerSubsystemInterfaceandReadLedgerSubsystem. Return owned bytes so the ledger lock is releasedbefore HTTP range handling and digest calculation.
src/node/rpc/file_serving_handlers.h. Preserve the opt-in parameter acrossnode redirects, use non-cacheable
307responses for synthetic discovery,add the chunk-kind and cache headers, and factor the existing file response
logic so it can also serve an in-memory buffer.
multiple consecutive synthetic chunks, and ranges spanning active files.
Add end-to-end coverage for redirects, cache headers on redirects and
404s,HEAD, byte ranges, digests, and parsing the downloaded result withccf.ledger.LedgerChunk..committed_prefixsupport to filename range parsing and directLedgerChunkreads, while ensuring committed-only directory discovery,read-only ledger directories, recovery, and cleanup continue to recognize
only canonical
.committedfiles. Promotion of a prefix for recovery, ifever needed, should be an explicit validation and conversion step.
benchmark-labelled performance test covering representative prefixsizes such as 64 KB, 1 MB, 5 MB (the default ledger chunk size), and 50 MB.
After a warm-up, repeat each case enough times to report the average
materialization and HTTP response cost, throughput, and peak memory. Compare
against serving an equivalent physical
.committedfile so the additionalcost of prefix construction is visible.
All reactions