Optional Linux RocksDB io_uring batch reads¶
RocksDB's SST MultiRead path can submit independent block reads through io_uring instead of issuing them serially. Native keyed-state probes already use the released binding's pinned batched MultiGet API. This change makes RocksDB's Linux read integration available through an optional build feature and a process-level runtime switch, without changing the pinned values, operators, write batches, checkpoint protocol, or dependency source.
The released librocksdb-sys defines a strong, always-true enable hook.
Defining that hook again would create a duplicate symbol; the Linux linker
wraps its calls instead. Feature-enabled Linux builds attempt io_uring by
default. The wrapper caches SF_ROCKSDB_IO_URING: unset or exactly true
enables it, while false or any other value disables it. This keeps the same
binary usable for OFF and ON tests. Unsupported or
sandbox-denied ring creation follows RocksDB's ordinary-read fallback.
Build and deployment settings
describe the optional liburing dependency.
Measurements and limits¶
On October 1, 2026 (EDT), an isolated experimental snapshot ran the Nexmark query suite with a generated row source and blackhole sink: 2,000,000 events, parallelism 4, native RocksDB, mini batching off, one-second checkpoints, release + mimalloc, Java 17, ordinary IPC shuffle, and Linux 6.18.40.1-microsoft-standard-WSL2 with 16 logical CPUs and about 10 GiB RAM. Both row/Arrow transpose boundaries remained in each query plan. The generated source, event schemas, watermarks, SQL and blackhole sink were unchanged; only runner selection, backend options, generator parallelism and recording were adjusted. There were no Kafka jobs or stock Flink references, as requested for this isolation experiment. This is not the Kafka README headline workload.
OFF ran before ON in fresh JVMs, with zero warmups and three measured trials per query per mode. All 23 queries (q6 excluded) passed: 138 measured trials plus one q4 backend-engagement preflight per mode. The same frozen binary and source were used in both modes. The complete pair took 876.8 seconds.
| Statistic | io_uring ON throughput change |
|---|---|
| Geometric mean, best of three | +3.93% |
| Median query, best of three | +0.80% |
| Geometric mean, median of three | +1.08% |
| Median query, median of three | +0.59% |
| Queries faster / slower by best time | 16 / 7 |
q3 improved by 57.8% using best times; q17 regressed by 9.7%, q19 by 4.5%, and q20 by 7.2%. Only q3 had all ON trials faster than all OFF trials; q17 and q19 had all ON trials slower than all OFF trials. These results are not a claim of a broad, repeatable speedup. The build feature remains opt-in; once compiled in, the runtime attempts io_uring automatically. Maintainer approval to submit the integration followed review of these measurements, including their modest aggregate gain and regressions.
Five-second host sampling observed at least 4.63 GiB available RAM, zero swap-out and no memory-pressure stalls. System-wide I/O full-stall time was 14.43% of the sampled interval. The blackhole sink removes output connector I/O, but RocksDB writes, checkpoints and database cleanup still affect timing; these samples do not attribute stalls to individual processes. Several short queries also include a substantial startup cost.
The measured baseline was a frozen worktree snapshot at commit
0d2ef488949ae80cee141d679e17f10fea08e8dd, including pre-existing worktree
changes and a shared Kafka prerequisite fix. It was not unmodified repository
HEAD. That shared fix is irrelevant to the blackhole sink and is not included
in this integration PR. The final PR is based on canonical main; the numbers
above describe the experimental snapshot, not a fresh benchmark of that PR.
The benchmark library SHA-256 was
63403851fddcb69b43bbaf25c7ba2ae60cd394020669b98d961781bf8c74c68c.
Per-query best times,
all three trial times and ranges,
configuration,
summary,
and completion audit
retain the full evidence. The
isolated runner patch
records how this variant was selected; it is not applied to the production
Nexmark harness in this PR. It is against the frozen experimental source,
whose prerequisites differ from canonical main. The patch has zero context;
apply it to that frozen source with git apply --unidiff-zero.
Reproduction¶
Use a release library built with the feature above. In the isolated snapshot with the runner patch, run:
SF_BENCHMARK=true SF_ROW_ROCKS_BENCH=true SF_ROWS=2000000 \
SF_PARALLELISM=4 SF_WARMUP=0 SF_RUNS=3 SF_ROCKSDB_IO_URING=false \
mvn -pl :streamfusion-runtime -Pbench \
-Dnative.build.skip=true -Dnative.test.resource.skip=true \
-Dtest=NexmarkMatrixBenchmark#rowDataRocksComparison test
Repeat with SF_ROCKSDB_IO_URING=true in a fresh JVM. Use Java 17 and UTC for
both. The native backend, mini-batch and checkpoint settings are pinned by the
runner method. Verification additionally uses a cold-SST pinned-read test with
block caching disabled and the pinned read executed before the legacy read,
so a warmed cache cannot hide whether the ring is used. Test-only cache
settings do not affect production options or benchmark jobs.
Integration validation on canonical main¶
The PR branch was rebuilt separately in release mode with the optional feature.
Before the automatic runtime default was introduced, the cold-SST pinned-read
test passed with unset, false, true and invalid runtime
settings, and with io_uring_setup forced to return EPERM. Syscall tracing
observed six io_uring_enter calls in the enabled case and none in the other
cases; the denied case preserved read correctness through upstream fallback.
Those syscall counts describe the original opt-in runtime default; unset now
selects the same enabled path as true.
Fresh-process checks of the updated wrapper passed for unset, true, false,
invalid, empty, uppercase and non-Unicode settings, including caching after
an environment change.
Fresh-process checks also confirmed the runtime setting remains cached after
an environment change. Disabled settings may still observe RocksDB's initial
capability probe; absence of submissions is the relevant read-path distinction.
All 31 native RocksDB SQL parity tests and five checkpoint/restore operator tests passed in both modes, with no skips. Rust formatting, whitespace and new documentation links passed. The PR validation record retains the rebuilt library hash, mode-specific syscall counts and test totals; its library is distinct from the frozen performance-measurement binary.