FDP SSD for LMCache — 배치 전략 PoC
[!tldr] 업무 관점 takeaway LMCache KV 캐시를 어떤 기준으로 FDP 스트림에 나눌 것인가? 세 가지 전략 — prompt별, prefill/decode 단계별, TP 워커별. 핵심 도전은 "수명이 다른 데이터를 어떻게 구별하느냐"이다. 구현 경로는 Raw Block + io_uring_cmd (
dspec필드)가 명시적 배치를 위한 정석.
목표
LMCache 스토리지에서 FDP SSD를 활용해 수명(lifetime)이 다른 KV 캐시 스트림을 분리:
- WAF(Write Amplification Factor) 감소 → SSD 내구성 향상
- 멀티테넌트 환경에서 예측 가능한 I/O 성능 (GC 간섭 감소)
LMCache의 I/O 특성
| 특성 | 설명 |
|---|---|
| 대용량 I/O | KV 청크 수 MB ~ 수십 MB |
| 덮어쓰기 없음 | WORM(Write Once Read Many) |
| 순차 접근 | 자기회귀적 특성 → 앞 토큰부터 순서대로 prefix KV 읽기 |
구현 인터페이스 선택지
| 방식 | 장점 | 단점 |
|---|---|---|
| 파일 시스템 (write hints) | LMCache 변경 최소화 | FS가 스트림 혼합 가능; NVMe 스트림 패싱 미반영 |
| Raw Block (io_uring_cmd) | 명시적 배치; NVMe passthru 고성능 | 커스텀 스토리지 엔진 필요; NVMe 전문 지식 요구 |
→ io_uring_cmd가 정석. NvmeUringCmd.cdw13 (dspec 필드)에 placement handle 직접 embed.
배치 전략 3가지
1. Prompt별 배치 (Per-Prompt)
동기: KV 청크는 rolling hash 기반 prefix hash chain을 형성 → 같은 체인의 청크는 함께 hot/cold 전환.
stream = prompt_id % num_placement_handles
제약:
num_placement_handles최대 128개 (FDP SSD 하드웨어 한계)- 다른 prompt의 청크가 같은 그룹에 매핑될 수 있음
2. 단계 인식 배치 (Phase-aware)
동기:
- decode KV: 현재 요청 처리 중에만 사용 → 단명(short-lived)
- prefill KV: 여러 요청에 걸쳐 재사용 가능 → 장명(long-lived)
prefill KV → 스트림 N (장명 스트림)
decode KV → 전용 또는 기본 스트림 (단명 스트림)
수명이 다른 두 유형을 분리하면 GC가 단명 스트림만 효율적으로 회수 가능.
3. TP 워커별 배치 (Per-vLLM Worker)
동기: TP > 1 환경에서 전체 스텝 지연 = max(rank_i I/O latency). FDP로 랭크 간 성능 격리 시 tail latency 감소.
| 워커 | Placement Group |
|---|---|
| Worker 0 | Group 0 |
| Worker 1 | Group 1 |
| Worker 2 | Group 2 |
| Worker 3 | Group 3 |
평가 시 주의사항
- 클린 상태에서 시작하면 WAF 관찰 어려움
- sustained state로 preconditioning 후 측정해야 의미 있는 WAF 수치 확보 가능
- 비교군: CacheLib FDP 사례 (WAF 3.5 → ~1.0) 참고
관련 페이지
- [[raw_block-io_uring-cmd]] — io_uring_cmd + dspec 필드 (FDP 배관)
- [[NVMe-FDP]] — FDP RUH/RG/PH 개념
- [[Plugin-Pipeline]] — LMCache 코드 수정 없이 FDP 백엔드 등록하는 방법
- [[CacheLib-FDP-사례]] — 외부 증거
- [[WAF]] — 개선 목표 KPI