Zoned Namespace SSDs are cheaper and free of the garbage-collection stalls that plague conventional flash, but no RAID existed for them — and classic RAID cannot work on zones that forbid overwrites, since you cannot update parity after a small write, cannot overwrite the orphaned half of a torn stripe, and cannot even rewrite a superblock in place — so RAIZN rebuilds the redundancy layer on ZNS terms, log-structuring all metadata with per-zone generation counters, logging partial parity for incomplete stripes (immutability means the data itself never needs relogging), relocating stripe units stranded by power loss, and write-ahead-logging zone resets — matching mdraid's performance while staying immune to the garbage-collection collapse that costs conventional arrays up to 93% of throughput and 14× tail latency.
The argument in one glance
-
Problem
The best new SSDs cannot be put in arrays
Zoned Namespace (ZNS) SSDs move flash management from the drive to the host: the address space becomes large zones that must be written strictly in order and erased as whole units. In exchange, the drive needs no on-device garbage collection, less DRAM, and less spare flash — lower cost per byte, and none of the sudden performance collapses of conventional SSDs. Single-device studies showed 90% lower 99.99th-percentile latency and 2× write throughput. But datacenters do not deploy single devices; they deploy arrays with striping and parity — and for ZNS, no RAID existed.
-
What people did
Software RAID on conventional SSDs
The standard answer is mdraid over ordinary flash: stripe data and parity across devices, overwrite freely, keep the superblock at a fixed location, journal if you want atomicity. It works — because the drive's flash translation layer absorbs every overwrite behind the block interface.
-
Why it fell short
RAID's mechanics assume overwrites; ZNS forbids them — and FTLs charge for the privilege
Two failures, one per direction. Porting RAID to ZNS breaks on correctness: a small write's parity can never be updated once written (yet must be persisted before acking, or a device failure loses data); a stripe half-persisted at power loss leaves a "stripe hole" that can be neither read nor overwritten; a logical zone reset spanning five devices can be torn by power loss; even the superblock cannot be updated in place. Staying on conventional SSDs breaks on predictability instead: when the drives' spare blocks run out, on-device garbage collection cuts mdraid's throughput by up to 93% and inflates tail latency 14× — at times the host can neither predict nor control.
-
This paper's idea
Rebuild redundancy on ZNS terms
RAIZN (from CMU, Virginia Tech, and Western Digital) is a Linux device-mapper volume that stripes RAID-5-style parity across ZNS SSDs and exposes — itself — a ZNS interface, so zoned applications run unmodified. Every mechanism is re-derived under the no-overwrite rule: all metadata is log-structured into a few reserved zones, validated by per-zone generation counters; partial-stripe parity is logged incrementally (the data itself never needs relogging — immutability guarantees it cannot change); stripe units stranded by power loss are relocated to metadata zones with a small remap table; zone resets are write-ahead logged on two devices before executing; and a persistence bitmap enforces ZNS's sequential-persistence contract for FUA writes across devices. Result: within 2% of raw aggregate throughput, parity with mdraid on RocksDB and MySQL — and flat, GC-free performance where mdraid collapses, plus rebuilds that scale with valid data instead of array capacity.
Why this problem is worth solving
Conventional SSDs sell a comfortable illusion: an address
space you can overwrite at will, on top of flash that
physically cannot overwrite anything. The
the firmware inside a
conventional SSD that maintains the illusion of overwritable
blocks: it redirects every write to fresh flash pages, keeps a
huge logical-to-physical mapping in on-device DRAM, and runs
garbage collection — copying still-valid pages out of
partially-stale erase blocks so they can be erased and reused.
GC competes with user I/O at times the host cannot predict,
and the spare (“overprovisioned”) flash it needs raises
cost-per-byte
Zoned Namespace SSDs drop the illusion. The
address space is divided into large zones (1077 MiB on the
paper’s devices) that must be written strictly sequentially —
each zone has a write pointer marking the only writable
position — and can be erased only as whole units via a zone
reset. The host takes over data placement and garbage
collection; the drive keeps only media-level duties like
wear-leveling. No on-device GC, minimal DRAM, minimal
overprovisioning
striping data across an array of devices with
rotating parity (RAID-5 style) — any single device can fail
and its contents are reconstructed by XOR-ing the survivors.
The classic hazards are small writes (parity must be updated
read-modify-write) and the write hole (data and parity
de-synchronized by a crash between their updates)
What people did before, and where it broke
- mdraid on conventional SSDs. The deployed standard. Correct, mature, journaled if desired — and hostage to device-level garbage collection it cannot see or schedule. The FTL also stacks under any application: log-structured systems like RocksDB end up garbage-collecting on top of an FTL garbage-collecting beneath them, multiplying write amplification.
- Host-side FTLs over ZNS (dm-zap, dm-zoned). Re-create the block interface in software so unmodified RAID stacks run — but that reintroduces exactly the translation layer and GC that ZNS exists to remove.
- RAID for other novel interfaces. KVSSD RAID exists but struggles with space-efficient parity for small objects; SMORE stripes cold multi-megabyte objects on shingled disks (zoned, but a narrow workload); none address ZNS’s combination of small writes, resets, and strict persistence ordering.
- Why naive porting fails, concretely. RAID-5’s arithmetic address mapping assumes any block can be rewritten: parity updates for sub-stripe writes are read-modify-write; a torn stripe is fixed by overwriting it; the superblock lives at a fixed address. Every one of those verbs is illegal on a zone.
How RAIZN works
RAID-5 re-derived under a no-overwrite rule
-
A ZNS volume made of ZNS devices new
RAIZN is a Linux device-mapper target over D+P drives (evaluated: 4+1). It exposes a single logical ZNS device — logical zones, write pointers, resets — so any zoned application (F2FS, RocksDB via ZenFS-style backends) runs unmodified. Logical zone N = physical zone N on every device; LBA-to-PBA translation is pure arithmetic, so reads need no lookups. Stripe units of 64 KiB; parity rotates per stripe.
-
Log-structured metadata + generation counters new
Nothing can be updated in place, so every metadata type (superblock, reset logs, counters, relocations, partial parity) is appended as log entries with a 4 KiB header into a few reserved zones — one for partial parity, one general, one swap zone for GC. Validity is settled by GENERATION COUNTERS: a 64-bit counter per logical zone, bumped on every reset (and for empty zones on every mount). A log entry whose counter is stale is dead — no tombstones needed. Metadata GC checkpoints live in-memory state into the swap zone and resets the old zone; crashes mid-GC leave harmless duplicates that the counters disambiguate.
-
Partial parity logging (the small-write answer) new
A write that ends mid-stripe cannot ack until enough redundancy is persisted — but the stripe's final parity cannot be written yet (it would need updating later, which ZNS forbids). RAIZN logs only the PARTIAL PARITY — the XOR of what has arrived — to the parity metadata zone, and keeps the running stripe in one of 8 pre-allocated in-memory stripe buffers per open zone (bounded by the device's 14-open-zone limit). When the stripe completes, final parity is written to its real location. Immutability is the discount: logged data cannot change beneath the log, so only parity, never data, is relogged.
-
Stripe holes and relocation (the crash answer) new
Power loss can persist some stripe units of a stripe but not enough to reconstruct the rest — a stripe hole. On mount, RAIZN compares physical write pointers per logical zone, takes the maximum as the logical write pointer, and checks the last stripe. If parity can rebuild it, it does; if not, the hole is hidden: the logical write pointer is pulled back, and the NEXT write to those addresses is redirected to a metadata zone as a RELOCATED STRIPE UNIT, tracked in a small hashmap consulted only for flagged zones. Past a threshold of relocations, the zone is rewritten clean via the swap zone.
-
Zone-reset write-ahead logs (the atomicity answer) new
A logical reset fans out to D+P physical resets that can be torn by power loss — and a partially-reset zone whose first stripe unit survived is indistinguishable from a partial stripe write. So RAIZN logs the INTENT to reset on two devices (the one holding the zone's first stripe unit and the one holding its parity, rotated per zone), and only then resets. On mount, a non-empty zone with a valid reset log is finished off; no log, no reset — the data is intact.
-
Persistence bitmaps (the FUA answer) new
ZNS promises that an address is readable only if all earlier addresses in its zone are readable — so acking a forced-unit-access write means guaranteeing everything before it in the logical zone is persisted, across all devices. RAIZN keeps a per-zone persistence bitmap (one bit per stripe unit); a FUA completion triggers flush sub-IOs to exactly the devices holding non-persisted earlier units. The sequential-write constraint means only the previous stripe needs checking. A side effect: acked FUA data can never be caught in a stripe hole.
The idea
Re-derive, don’t emulate. The tempting path was a software FTL under mdraid — re-creating overwrites so old code runs. RAIZN refuses, because the block-interface illusion is precisely the cost center ZNS eliminated. Instead it asks what each RAID mechanism was for and finds the ZNS-native equivalent: fixed-location superblock → append-anywhere logs validated by generation counters; read-modify-write parity → incremental partial-parity logging; overwrite-the-torn-stripe → relocation with a remap table; in-place metadata updates → a swap-zone checkpoint cycle. The reward for the discipline compounds: RAIZN’s volume is itself a ZNS device, so the entire stack above it — F2FS, RocksDB, MySQL — keeps the placement control and GC-freedom that motivated ZNS in the first place.
Immutability is a two-sided coin. The no-overwrite rule causes every problem in this paper — and quietly pays for the solutions. Partial-stripe recovery needs only the parity logged, never the data, because logged-against data cannot change afterward. Torn writes lose their most insidious form: a half-old-half-new block is impossible when blocks are never rewritten, and damage always takes the benign shape of lower addresses readable, higher ones erroring. Even the write hole — mdraid’s classic crash hazard, optionally closed by a journal device — closes here as a side effect, since parity and data can never de-synchronize when neither can change. The paper is a case study in reading an interface restriction as an invariant you can lean on.
The write pointer is free knowledge — spend it. A conventional array knows nothing about which blocks matter, so mdraid rebuilds a replaced drive by resyncing the entire address space, full or empty. ZNS write pointers tell RAIZN exactly where valid data ends in every zone, so rebuilds process only written stripes — active zones first, so degraded-mode writes end soonest — and time-to-repair scales with the data actually present, not the capacity purchased. The same knowledge powers mount-time consistency (write pointers are the crash record) and the persistence bitmap’s single-stripe check. The interface’s bookkeeping, exposed rather than hidden in firmware, keeps replacing entire subsystems of inference.
A volume’s eventful week
Five ZNS drives, RAID-5 style, through crash and failure
Stripe = 4 data units + 1 parity unit (64 KiB each), parity rotating per stripe. Logical zone = one physical zone per device. WP = write pointer. Numbers from the paper's 5-drive Western Digital ZN540 testbed.
Step 1 of 6
A small write lands mid-stripe
The filesystem writes 128 KiB — two stripe units — into an open logical zone, filling only half a stripe. The data goes straight to its two devices (its addresses are final; arithmetic mapping, no indirection). But RAIZN cannot ack yet: if a data device died now, nothing could reconstruct those units. It XORs the two units into a partial parity, appends it with a 4 KiB header to the parity metadata zone, and only then completes the write.
the running stripe also sits in one of 8 in-memory stripe buffers per open zone immutability discount: data is never relogged — it cannot change beneath the log
Why it works
- Zones forbid in-place updates → every RAID mechanism that assumed overwrite is re-derived as an append (parity → log, torn stripe → relocation, superblock → generational log) → correctness is restored without re-creating the translation layer ZNS removed.
- Written data is immutable → partial-stripe recovery needs only parity logged, torn writes cannot interleave old and new bytes, and data/parity can never de-synchronize → the RAID-5 write hole closes by construction, no journal device required.
- Generation counters pair every log entry with a zone lifetime → stale metadata self-invalidates on reset, GC crash-duplicates are harmless (highest counter wins), and consistency needs no scanning → under 100 MiB of metadata governs the whole array from memory.
- Write pointers expose exactly where valid data ends → mount is forensic (compare pointers, find holes), rebuilds skip unwritten space (time-to-repair scales with data, not capacity), and persistence checks stop at the previous stripe → the host does with arithmetic what conventional arrays do with full-device scans.
- No FTL means no on-device GC → the array’s performance is whatever the host’s placement policy earns, at every fill level → flat throughput where mdraid’s conventional drives collapse 93% and inflate tails 14×.
What it costs
- Small-write overhead. Every sub-stripe write pays a 4 KiB partial-parity header; at 4 KiB block sizes the relative cost is large, and RAIZN measurably trails mdraid on 4–64 KiB reads and writes (the paper argues NVMe per-block metadata descriptors could shrink this).
- No zone appends. The ZNS command that makes concurrent small writes fast is unsupported — on-device reordering would scramble stripe attribution after a crash. Serialized write submission (workers waiting on write pointers) fills in, at some cost; btrfs’s append-based zoned path cannot ride RAIZN yet.
- Giant logical zones. A logical zone spans one physical zone per device, so its capacity scales with array width (~4.2 GiB here). Coarser erase units make application-level garbage collection harder — the authors flag this as open work.
- Within-stripe atomicity only. The write hole closes, but writes spanning stripes can still tear; applications needing cross-stripe atomicity need a journal, exactly as with mdraid.
- Reserved capacity and memory. Three-plus metadata zones per device, stripe buffers (320 KiB × 8 per open zone), and the metadata cache — all modest, but real; and the evaluation covers one device model, 5-drive RAID-5-style arrays, on drives whose firmware trails conventional siblings by 2–4% raw throughput.
The evaluation
Real hardware throughout: five 2 TB Western Digital ZN540 ZNS SSDs against five conventional SSDs on the same platform (same hardware, FTL firmware), Dell R7515 with a 16-core EPYC. Microbenchmarks (fio), failure injection with rebuild timing, and full applications — F2FS, RocksDB (db_bench), MySQL/MyRocks (sysbench) — on both arrays.
Redundant arrays, with and without the translation layer
| Property | mdraid on conventional SSDs | Naive RAID-on-ZNS (the non-starter) | RAIZN on ZNS SSDs |
|---|---|---|---|
| Small (sub-stripe) writes | |||
| Crash mid-stripe / write hole | Stripe hole overwritten on next write; write hole open unless a journal device is configured | ||
| Steady-state performance | — | ||
| Rebuild after device replacement | — | ||
| What the stack above sees | — |
Check yourself
Check your understanding
1. Power fails after only two of a stripe's five units persist — too few for parity reconstruction. Predict why this "stripe hole" is fatal to naive RAID-on-ZNS, and how RAIZN escapes.
2. For a partial-stripe write, RAIZN logs only the running parity — never the data — before acknowledging. Classic RAID journals typically log both. What licenses the discount?
3. ZNS guarantees an address is readable only if all preceding addresses in its zone are. Why does this turn a simple FUA (forced-persist) write into a cross-device coordination problem, and what makes RAIZN's solution cheap?
4. RAIZN rebuilds a replaced drive in time proportional to the valid data, while mdraid always resyncs the full address space. What knowledge gap explains the difference — and when do the two tie?
Sources
- ACM DL: RAIZN: Redundant Array of Independent Zoned Namespaces — ASPLOS 2023 (open access)
- RAIZN source code