Search before asking
Motivation
In both the KvSnapshotAndLogBatchScanner proposed in Sub-Issue 1 and the existing LakeSnapshotAndLogSplitScanner, incremental log records are buffered in an in-memory TreeMap<InternalRow, KeyValueRow>:
// LakeSnapshotAndLogSplitScanner.java, line 67
private Map<InternalRow, KeyValueRow> logRows;
// ...
logRows = new TreeMap<>(rowComparator);
Problem: The volume of logs between two KV snapshots can be very large. With the default kv.snapshot.interval of 10 minutes, a high-throughput workload (e.g., 100 MB/s) can produce tens of GB of log data within a single interval. Buffering all of this in an in-memory TreeMap leads to OOM.
Solution
Replace the in-memory TreeMap with a local RocksDB instance to buffer, deduplicate, and sort log records:
- Write: Each fetched log record is written to a local temporary RocksDB as
key → value
- Deduplication: Subsequent writes for the same key automatically overwrite prior records (RocksDB's
put semantics provide natural deduplication)
- Deletion: DELETE and UPDATE_BEFORE records are written as tombstones to preserve the delete semantics and prevent data loss
- Sorting: RocksDB stores keys in sorted order; reading via
RocksIterator yields records sorted by primary key
- Merge: The RocksDB log iterator is passed to
SortMergeReader, which performs a two-way merge with the snapshot's SnapshotFilesReader
┌──────────────────────────────────────────────────────────┐
│ Client Side │
│ │
│ ┌─────────────┐ ┌──────────────┐ │
│ │ KV Snapshot │ │ LogScanner │ │
│ │ SST Files │ │ (incremental)│ │
│ │ (download) │ │ (fetch) │ │
│ └──────┬──────┘ └──────┬───────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌──────────────┐ │
│ │SnapshotFiles│ │ Log Buffer │ │
│ │ Reader │ │ (RocksDB) │ │
│ │ (RocksDB) │ │ (dedup+sort) │ │
│ └──────┬──────┘ └──────┬───────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────────────────────────┐ │
│ │ SortMergeReader │ │
│ │ (snapshot + log merge by PK) │ │
│ └──────────────┬───────────────────┘ │
│ │ │
│ ▼ │
│ Sorted InternalRow stream │
└──────────────────────────────────────────────────────────┘
Anything else?
No response
Willingness to contribute
Search before asking
Motivation
In both the
KvSnapshotAndLogBatchScannerproposed in Sub-Issue 1 and the existingLakeSnapshotAndLogSplitScanner, incremental log records are buffered in an in-memoryTreeMap<InternalRow, KeyValueRow>:Problem: The volume of logs between two KV snapshots can be very large. With the default
kv.snapshot.intervalof 10 minutes, a high-throughput workload (e.g., 100 MB/s) can produce tens of GB of log data within a single interval. Buffering all of this in an in-memoryTreeMapleads to OOM.Solution
Replace the in-memory
TreeMapwith a local RocksDB instance to buffer, deduplicate, and sort log records:key → valueputsemantics provide natural deduplication)RocksIteratoryields records sorted by primary keySortMergeReader, which performs a two-way merge with the snapshot'sSnapshotFilesReaderAnything else?
No response
Willingness to contribute