본문으로 건너뛰기

raw_block 성능 분석 — 종합 우선순위

[!tldr] 업무 관점 takeaway raw_block 스택(Rust io_uring 엔진 + Python RawBlockCore + L2 어댑터)을 종단 분석해 뽑은 개선 항목 우선순위 맵. 분류 기준 = correctness > 측정가능 성능 > 조건부 성능 > 설계 위험 > latent. 우리 업무 직결 항목: T1(delete TOCTOU 버그), L1/L2(put_many 락·배치), B2+P2(_free_slots deque+set — FDP wear leveling 선행), P0(io_uring batched API — io_uring/FDP 효과의 전제). 이 표가 raw_block 기여 PR들의 출처다 (이미 [[raw_block-batched-remove-PR|#3494]] 진행 중).

근거: raw/docs/notes/raw_block_priority.md, raw/docs/notes/raw-block-perf-findings.md (based-on-commit 29bbd553 / eaa2bfee, 2026-05-28). 라벨 체계가 둘 있다 — 이 페이지(T1/L1/P0…)는 종합 분석 렌즈, [raw_block-개선-Task]독립 PR 후보 렌즈. 같은 코드를 다른 각도로 본 것이라 항목이 일부 겹친다(예: 여기 B2+P2 ↔ 거기 H1+H2).


Tier 1 — 즉시 (correctness 버그, 재현됨)

#항목경로영향증명
T1delete() TOCTOU → _total_bytes_used 영구 과대 계상MPeviction 조기 발동, 불필요 key 삭제✅ mock sleep 재현

수정: delete_manywas_indexed를 반환하도록 변경 (난이도 낮음). 리뷰 노트: raw/work/reviews/cr-9fc5a901-rawblock-delete-toctou.md.


Tier 2 — 단기 (측정 가능한 성능, 수정 쉬움)

#항목영향증명
L1put_many 키당 락 4→2회N=100 배치에서 락 400→200회perf_counter
L2legacy batched_submit_put_task N-key 배치를 1-key×N coroutine으로 분해배치 이점 전무 + 이벤트루프 N배 오버헤드✅ 배치 크기별 latency

⚠️ L1 수정 시 inflight_io_count 일괄 관리가 D2(idle 판단)에 영향 → 확인 필요. 참고: 같은 "락 N→소수" 패턴의 삭제 경로 버전이 [[raw_block-batched-remove-PR|batched_remove(#3494)]]로 이미 upstream 진행 중.


Tier 3 — 조건부 단기 (적용 조건 있음)

#항목조건영향증명
B2+P2_free_slotsdeque+set으로 교체 (LIFO→FIFO, O(1) dedup)FDP/HC-SSD 도입 시FDP에서 RU wear leveling✅ slot histogram → nvme fdp stats
P1_snapshot_state lock 내 shallow copy 분리entry > ~10,000lock 보유 시간 단축✅ lock timing

B2+P2는 한 번의 deque+set 교체로 동시 해결 — [[raw_block-개선-Task]] H1(O(1))·H2(FIFO)와 같은 변경. FDP placement hint 도입 전 선행 작업으로 우리 업무에 직접 걸린다.


Tier 4 — 코드 품질 (기능 영향 없음)

OptionalX | None(Q1), Any 명시화(Q2), zip(strict=True)(Q3), except: passlogger.debug(Q4). LMCache 코딩 표준(§2 typing 등) 위반 정리 — [[LMCache-기여-가이드]] 규칙과 직결.


Tier 5 — 중기 설계

#항목영향난이도
D2max_dirty_threshold 추가 — 지속 I/O 중 checkpoint 미발생 방지비정상 종료 시 index 손실낮음
D1JSON checkpoint 용량 초과 silent skip 대응수만 entry 시 crash 후 index 전체 유실중간
L3io_uring SQ 활용률 (depth 256 대비 실제 2~4 SQE)io_uring 이점 미사용중간 (단기 대안: worker 수↑)

D1 = [[S2-checkpoint-overflow|S2 버그]]와 동일 사안. 여기선 설계 tier로 분류했지만 HC SSD 스케일에선 correctness 급. L3 = io_uring SQ 미활용 → 아래 P0와 짝.


Tier 6~7 — latent / Rust 연동

  • L4 legacy close() 10ms polling → threading.Condition (최대 10ms shutdown 지연)
  • T2 batched_async_contains pin N×2 lock (기능 안전, eviction 시 낭비)
  • D3 단일 글로벌 lock 분리 (현재 I/O가 lock 밖 → 경합 제한적)
  • P3+L3 pwrite_batch/pread_batch Rust API → io_uring SQ 완전 활용 (선행: Rust 바인딩 확장 + put_many 재설계)

Rust io_uring 엔진 분석 (perf-findings §1) — P0/P1

rust/raw_block/src/lib.rs 종단 분석에서 나온 별도 우선순위:

우선순위항목효과
P0put_many/load_many_into → io_uring batched API 활용 (현재 키 단위 직렬 I/O)쓰기·읽기 처리량 대폭↑
P0batched_writenotify_one N→1회 감소 (notify-one 폭풍)CPU 오버헤드↓
P1wait_iouring timeout busy-wait(10μs) → condvar.wait()idle CPU 낭비 제거
P1_snapshot_state lock 구간 축소대용량 인덱스 I/O 블로킹 방지
P1register_fixed_buffers 실제 호출 (구현됐으나 Python 미호출) → zero-copy 활성화io_uring 경로 copy 1회 제거

P0(batched API)가 우리 io_uring/FDP 작업의 전제 — 지금은 SQ depth 256인데 실제 2~4 SQE만 채움(L3). 키 단위 직렬 제출을 배치 제출로 바꿔야 io_uring·FDP placement의 효과가 측정 가능해진다.


실행 순서

T1 (버그) → L1+L2 (측정하며 수정, 세트)
→ B2+P2 (FDP 준비에 포함) → P1 (대용량 NVMe 확정 시)
→ D2 → D1(=S2) (설계 안정화)
→ L3 단기대안(worker 수 튜닝) → P3+L3 근본해결(Rust batched API)

관련 페이지

  • [[raw_block-개선-Task]] — 독립 PR 후보 렌즈 (H1/H2/M1/M2/S2)
  • [[raw_block-batched-remove-PR]] — 진행 중 PR #3494 (락 N→2, 삭제 경로)
  • [[raw_block-종단-분석]] — L1~L4 전계층, FDP 삽입 포인트
  • [[raw_block-내부구조]] — put_many/delete_many/_free_slots/_snapshot_state 코드 근거
  • [[raw_block-io_uring-cmd]] — io_uring/NVMe passthrough (P0·L3 배경)
  • [[S2-checkpoint-overflow]] — D1 = checkpoint overflow 상세