docs(architecture): ADR-008 — trait size probe, fleet GC, fs-tier engines; requirements anchor
- requirements.md (new): the three use cases pinned as REQ-1..4 with the node/pool/fleet/engine vocabulary defined once — ends per-session re-derivation of consumer facts. REQ-2 (replicator fleet over one shared pg pool, incl. large-blob serving) is recorded as a planning fact predating all POCs, on the operator's authority. - ADR-008: Backend trait gains size(key) length probe (before any backend ships data — ADR-002 one-way-door discipline); fleet GC mechanism (DB-backed pin rows committed atomically with entries, TTL+renewal semantics, liveness = embedder-owned table, protect callback is single-node-only, advisory-locked single sweeper, staged re-arbitrated delete window on both engines); fs tier becomes engine-selectable (local default; pg-lo named candidate) with the fleet locality contract (shared media or re-routing; mixed tiers are a documented deployment invariant, not a constructor-provable one). - poc-pglo-spec.md (new): POC #7 spec — pg Large Objects as the fs tier's pg-lo engine; instruments, decision gate, registered in phase-0.md OQ-BL-06. - ADR-003/005 status amendments point to ADR-008's extensions; specs ripple (backends/store-api/gc/ops/overview/README). - open-questions.md: deferral-policy header gains the decisions-vs- sequenced-work distinction; pg-lo's why-not-parked audit trail recorded. - research fixes: postgres POC renumbered #4->#5 to the canonical register (phase-0 OQ-BL-06), redb cross-refs fixed, thinking- artifact sentence in B1 replaced with the honest reading. Verification: docs-only change; reference-integrity sweep across the tree (ADR/REQ/POC refs resolve); architecture-reviewer pass on the delta — original 3 criticals addressed, its follow-up (fleet liveness form, pin TTL, staged-delete semantics, enforceability, shared-media caveats) fixed in this commit.
This commit is contained in:
1 parent
395d58cf3f
commit
281c37876e
16 files changed
+689
-88
No files matched your search
@@ -11,13 +11,13 @@ last_updated: 2026-10-02
|
||||
> crate `/workspace/alkblobs-redb-poc` — a copy of the POC crate with the
|
||||
> pg arm replaced by a `RedbKv` backend (`redb` 4.3, the engine iroh-blobs'
|
||||
> fs store uses for its metadata tables). The inherited sqlite/fs arms and
|
||||
> the 14-test suite are byte-identical to POC #3/#4's methodology.
|
||||
> the 14-test suite are byte-identical to POC #3/#5's methodology.
|
||||
> Date: 2026-10-02. Status: **passed** (14 tests, clippy `-D warnings`
|
||||
> clean, fmt clean).
|
||||
|
||||
## What this POC set out to decide
|
||||
|
||||
The "opposite route" from POC #4: postgres is complicated, we only need a
|
||||
The "opposite route" from POC #5: postgres is complicated, we only need a
|
||||
kv — what about a high-performance *embedded* kv like redb, which the
|
||||
DESIGN.md lineage (iroh-blobs' "faster than the filesystem for small
|
||||
items") and downstream folklore put anywhere from **2-7× over sqlite**,
|
||||
@@ -26,11 +26,11 @@ margin at equal semantics, the kv tier's engine pin (ADR-003) is again
|
||||
informed rather than hypothetical — and so is the anti-recommendation if
|
||||
it doesn't.
|
||||
|
||||
Same 2D instrument as POC #4 (the shape of the question, learned there):
|
||||
Same 2D instrument as POC #5 (the shape of the question, learned there):
|
||||
|
||||
1.Solo sweep (inherited `bench_small` harness, redb/sqlite/fs arms at
|
||||
1-256 KiB, identical working set) — where the 2-7× claim should show up.
|
||||
2. **Worker scale-out probe** (`redb_conc`, plus the POC #4 `sqlite_conc`
|
||||
2. **Worker scale-out probe** (`redb_conc`, plus the POC #5 `sqlite_conc`
|
||||
head-to-head) — redb is a single-file single-writer engine; does it
|
||||
degrade like sqlite's WAL or survive like postgres?
|
||||
|
||||
@@ -129,17 +129,17 @@ were never the bottleneck axis (sqlite was already the fastest get at
|
||||
adding threads only adds internal transaction-lock contention plus the
|
||||
None-durability freelist growth penalty (pages freed between durable
|
||||
commits accumulate until an Immediate commit collects them — redb's
|
||||
documented "rapid growth" behavior). Contrast POC #4: sqlite's
|
||||
documented "rapid growth" behavior). Contrast POC #5: sqlite's
|
||||
contentioned WAL plateaued ~1.2k, pg *scaled* to 28k+. redb's None mode
|
||||
is the only arm in three POCs where throughput goes **down** as workers
|
||||
go up.
|
||||
|
||||
### Finding C5 (the decisive one): redb write scale-out is perfectly flat — ~40-44 ops/s at 1, 2, 4, and 8 threads
|
||||
|
||||
`redb_conc` Immediate mode (same fresh-key discipline as POC #4's
|
||||
`redb_conc` Immediate mode (same fresh-key discipline as POC #5's
|
||||
`pgdiag6`/`sqlite_conc`):
|
||||
|
||||
| workers | redb Immediate | sqlite (same probe) | pg (from POC #4) |
|
||||
| workers | redb Immediate | sqlite (same probe) | pg (from POC #5) |
|
||||
|---------|---------------|---------------------|------------------|
|
||||
| 1 | ~42-44 ops/s | ~700-800/s | ~2.5-3.2k/s |
|
||||
| 2 | ~40 ops/s | ~1.0-1.1k/s | ~4.6-5.5k/s |
|
||||
@@ -168,7 +168,7 @@ go up.
|
||||
crash-consistent (unpersisted commits can leave the file failing to
|
||||
open until repaired — the freelist bookkeeping itself is lost on
|
||||
crash), `Immediate` pays a full fdatasync per commit. The
|
||||
durability-posture comparison that POC #4 could tune continuously
|
||||
durability-posture comparison that POC #5 could tune continuously
|
||||
(`synchronous_commit=off` on pg) doesn't exist here.
|
||||
- redb's `Database` is process-lifetime; concurrency modes
|
||||
(`ExclusiveWriter` default, `SingleWriter`, `MultiWriter`) only matter
|
||||
@@ -208,7 +208,7 @@ go up.
|
||||
- **Anti-recommendation adopted (ADR-007, 2026-10-02): redb stays
|
||||
ruled out** — recorded in the decision so the question does not
|
||||
reopen implicitly. SQLite's engine pin now has four-way triangulated
|
||||
evidence (POC #3 fs, POC #4/#5 pg, POC #6 redb, plus the lineage
|
||||
evidence (POC #3 fs, POC #5 pg, POC #6 redb, plus the lineage
|
||||
citation), and ADR-007 ships the kv tier as sqlite + postgres. If a
|
||||
future consumer wanted redb-shaped durability trade-offs (ephemeral
|
||||
cache tier), that's a *different* tier than the kv engine slot.
|
||||
@@ -222,7 +222,7 @@ go up.
|
||||
- clippy `-D warnings` clean, fmt clean.
|
||||
- **Honest caveats**: mdraid single dev box whose fdatasync latency
|
||||
ranged 0.24-30 ms during the session under co-resident load (pg
|
||||
container churn from POC #4 ran through the first bench; stopped
|
||||
container churn from POC #5 ran through the first bench; stopped
|
||||
before the final redbdiag re-run — relative conclusions unaffected,
|
||||
absolute redb-Immediate numbers are *device-pressure-dependent* and
|
||||
the honest statement is "1 fdatasync per commit, cost = device
|
||||
@@ -237,4 +237,4 @@ go up.
|
||||
`redbdiag2.rs` (None + periodic-flush group-commit emulation),
|
||||
`redbdiag3.rs` (commit-vs-insert split, per-put file growth),
|
||||
`redbdiag4.rs` (warm distribution), `redb_conc.rs` (scale-out, both
|
||||
durability modes), `sqlite_conc.rs` (copied head-to-head from #4).
|
||||
durability modes), `sqlite_conc.rs` (copied head-to-head from #5).
|
||||
Reference in new issue
Block a user