Raw Block Storage Stack — 종합 우선순위
세부 근거: [[core_py_analysis]], [[raw_block_stack_analysis]]
분류 기준: correctness > 측정 가능한 성능 > 조건부 성능 > 설계 위험 > latent > 정리
Tier 1 — 즉시 (correctness bug, 재현 가능)
| # | 항목 | 경로 | 영향 | 수치 증명 |
|---|---|---|---|---|
| T1 | delete() TOCTOU → _total_bytes_used 영구 과대 계상 | MP | eviction 조기 발동, 불필요한 key 삭제 | ✅ mock sleep으로 재현 |
수정 난이도: 낮음 — delete_many가 was_indexed 반환하도록 변경.
Tier 2 — 단기 (측정 가능한 성능, 수정 쉬움)
| # | 항목 | 경로 | 영향 | 수치 증명 |
|---|---|---|---|---|
| L1 | put_many key당 4→2 lock | core (양쪽) | N=100 배치 기준 lock 400→200회 | ✅ perf_counter |
| L2 | legacy batched_submit_put_task N-key 배치를 1-key × N coroutine으로 분해 | legacy | put_many 배치 이점 전무, 이벤트루프 N배 오버헤드 | ✅ 배치 크기별 latency |
⚠️ L1 수정 시
inflight_io_count일괄 관리가 D2 idle 판단에 영향 → 확인 필요.
Tier 3 — 조건부 단기 (적용 조건 있음)
| # | 항목 | 조건 | 영향 | 수치 증명 |
|---|---|---|---|---|
| B2+P2 | _free_slots deque+set 교체 (LIFO→FIFO, O(1) dedup) | FDP/HC-SSD 도입 시 | B2 단독 효과 낮음; FDP에서 RU wear leveling | ✅ slot histogram → nvme fdp stats |
| P1 | _snapshot_state lock 내 shallow copy 분리 | entry > ~10,000 | lock 보유 시간 단축 | ✅ lock timing |
B2+P2는 한 번의 deque+set 교체로 동시 해결 — 수정 단가 낮음.
Tier 4 — 코드 품질 (기능 영향 없음)
| # | 항목 | 위치 |
|---|---|---|
| Q1 | Optional → X | None | core.py:9 |
| Q2 | Any 타입 힌트 명시화 | core.py:58-62 |
| Q3 | zip(strict=False) → strict=True | core.py:463 |
| Q4 | except Exception: pass → logger.debug | core.py:602 |
Tier 5 — 중기 설계 (더 큰 변경 필요)
| # | 항목 | 경로 | 영향 | 난이도 |
|---|---|---|---|---|
| D2 | max_dirty_threshold 추가 — 지속 I/O 중 checkpoint 미발생 방지 | core | 비정상 종료 시 index 손실 위험 | 낮음 |
| D1 | JSON checkpoint 용량 초과 시 silent skip 대응 | core | 수만 entry 시 crash 후 index 전체 유실 | 중간 |
| L3 | io_uring SQ 활용률 (SQ depth 256 대비 실제 2~4 SQE) | 양쪽 | io_uring 이점 미사용 | 중간 (단기 대안: worker 수 증가) |
Tier 6 — 사소 / latent (기능적으로 현재 안전)
| # | 항목 | 경로 | 비고 |
|---|---|---|---|
| L4 | legacy close() 10ms polling → threading.Condition | legacy | 최대 10ms shutdown 지연 |
| B1 | checkpoint_now() 동시 호출 제약 docstring 명시 | core | 현재 호출 경로 없음, latent only |
| T2 | batched_async_contains pin N×2 lock | legacy | 기능적으로 안전, 중간 eviction 시 낭비 |
| D3 | 단일 글로벌 lock 분리 | core | 현재 I/O가 lock 밖 → 경합 제한적 |
Tier 7 — 장기 / Rust 연동
| # | 항목 | 선행 조건 |
|---|---|---|
| P3+L3 | pwrite_batch/pread_batch Rust API → io_uring SQ 완전 활용 | Rust 바인딩 확장 + put_many 재설계 |
실행 순서
T1 (버그 수정)
→ L1 + L2 (측정하면서 수정, 세트로 가능)
→ B2+P2 (FDP 준비 작업에 포함)
→ P1 (대용량 NVMe 설계 확정 시)
→ D2 → D1 (설계 안정화)
→ L3 단기 대안 (worker 수 튜닝)
→ P3+L3 근본 해결 (Rust)