본문으로 건너뛰기

Recovery Validation 실측 가이드 (실 NVMe)

이 PR이 검증하는 것 (io_uring block + POSIX). io_uring_cmd(passthrough)는 passthrough read 버그로 이 PR 제외uring_cmd_recovery_followup.md.

#구현검증 방법
1io_uring batched recovery (block, non-uring_cmd)벤치 §3 + 정확성 §4
2queue_depth 단위 bounded batch 분할 (P2)벤치 §3 (N>queue_depth) + 단위테스트 §2
3batch I/O 에러 per-slot fallback단위테스트 §2
4벤치 --io-engine 파라미터화§3 자체

0. 환경 요구사항

  • block device /dev/nvmeXn1 (덮어써도 되는 전용/빈 namespace. ⚠️ --prepare가 device를 덮어씀. 부팅/데이터 디스크 금지)
  • 커널 io_uring 지원, Python 3.12 venv + Rust extension 빌드 (io_uring_cmd char device는 이 PR 범위 아님 — followup 참조)

1. 브랜치 가져오기 + 빌드

# (현재 PC) origin(fork)에 push
git push origin perf/iouring-recovery-batched-read
# (실측 PC) fetch + checkout (= 87638cb)
git fetch origin && git checkout perf/iouring-recovery-batched-read
uv venv --python 3.12 && source .venv/bin/activate
uv pip install torch && uv pip install -e . --no-build-isolation
uv pip install -r requirements/test.txt

Rust lmcache_rust_raw_block_io가 빌드돼야 함(없으면 단위테스트 importorskip, 벤치 import 에러).

2. 단위 테스트 (device 불필요)

pytest -xvs tests/v1/storage_backend/test_raw_block_core.py # 기대: 14 passed

핵심 항목:

  • test_read_slot_headers_batched_splits_into_queue_depth_batches — queue_depth 분할 + 순서 보존(P2)
  • test_read_slot_headers_batched_falls_back_to_per_slot_on_error — fallback 격리(에러 시 1개만 None)
  • test_validate_loaded_entries_iouring_uses_batched_read / _uring_cmd_uses_sequential — dispatch
  • test_raw_block_core_drops_checkpoint_entry_with_stale_slot_header — stale 헤더 1개만 drop

3. 벤치 실측 (성능 + 정확성)

# fixture 준비 (block device). N = (cache-space - meta) / slot-bytes
sudo python benchmarks/storage_backend_io/raw_block_recovery_bringup_bench.py \
--device-path /dev/nvme0n1 --cache-space-gb 50 --slot-bytes 1048576 \
--prepare --i-understand-this-overwrites-device
# 측정: posix(threads 스윕) vs io_uring(block, batched)
sudo python benchmarks/storage_backend_io/raw_block_recovery_bringup_bench.py \
--device-path /dev/nvme0n1 --cache-space-gb 50 --slot-bytes 1048576 \
--measure --io-engine posix io_uring --threads 1 8 --repeats 5
  • posix--threads(1,8) → serial vs threadpool, io_uring은 block batched 단일
  • use_odirect 기본 True → posix/io_uring 모두 OS page cache 우회(실 device latency)

4. 결과 해석

  • 정확성(필수): 모든 라벨 indexed=가 prepare한 N과 동일.
  • 성능: 실 NVMe + 큰 N에서 io_uring(block)이 serial 대비 speedup>1. ⚠️ tmpfs/소량 N은 device latency≈0이라 무의미 — 반드시 실 NVMe + 큰 N.

실측 결과 (2026-06-23, 524,272 entries, /dev/nvme6n1)

경로medianspeedup
posix serial (t=1)70.7s
posix threadpool (t=8)16.3s4.35×
io_uring batched (block)11.6s6.08×

→ io_uring(block) batched가 threadpool보다 1.4× 빠르고 serial 대비 6.08×. 검증 완료. (io_uring_cmd는 indexed=0/EINVAL — followup 참조.)

5. 주의

  • ⚠️ --prepare는 device 메타/헤더를 덮어씀. 빈/전용 namespace만.
  • fallback(배드섹터 격리)은 실 device 인위 I/O 에러가 어려워 §2 단위테스트로 검증. stale 헤더 케이스(_drops_..._stale_slot_header)로 "1개만 drop"은 실 device서도 확인 가능(검증 mismatch 경로).