비동기 메커니즘 — Future vs eventfd
변경 검증 가이드 (다음 fetch 후):
git log eaa2bfee..HEAD -- lmcache/v1/storage_backend/plugins/rust_raw_block_backend.pygit log eaa2bfee..HEAD -- private/docs/notes/raw_block_line.md위에 커밋이 잡히면 (1)
loop주입 시그니처가 사라졌거나run_coroutine_threadsafe가 다른 기전으로 바뀌었는지, (2) eventfd 가 3 개에서 다른 개수로 변했는지 확인. 전자면 "asyncio loop 외부에서 받음" 섹션, 후자면 "eventfd 3 개 분리" 섹션 다시 써야 함.
비동기가 왜 필요한가
KV 캐시 디스크 쓰기에 50ms 걸리면 그동안 vLLM 은 다른 일을 해야 함. 즉:
"이 작업 시작해줘. 끝나면 알려줘. 난 그동안 다른 거 할게."
문제는 "끝나면 어떻게 알릴 거냐".
두 가지 답 = 두 모드
Non-MP 모드 — asyncio Future (진동벨)
손님(vLLM) ──[주문]──> 점원(asyncio loop)
│
├─> 주방에 일 던지기
│
└─> 진동벨(Future) 손님한테 줌
손님: 자리에서 다른 일 하다가 진동벨 울리면 가지러 감
- 점원(asyncio loop) 한 명이 모든 주문을 처리
- 진동벨(Future) 로 "끝나면 결과 줄게" 약속
- 단점: 점원이 같은 가게(같은 프로세스) 안에 있어야 진동벨 작동
MP 모드 — eventfd (도어벨)
손님(vLLM 프로세스) ──[ZMQ]──► 택배기사(LMCache 서버 프로세스)
│
├─> 자기 창고(ThreadPool) 에 일 던지기
│
└─> 도어벨(eventfd) 누르기
손님: 도어벨 울리면 받음
- 별도 건물(별도 프로세스) 에 LMCache 서버
- 진동벨은 같은 가게에서만 작동하니까 OS 차원의 도어벨 =
eventfd사용 - 작업 완료 → 커널이 도어벨 울림 → 손님 깨어남
누가 일을 하는가 (중요!)
두 모드 모두 일을 하는 주체는 LMCache. vLLM 은 요청자.
| 항목 | In-process | MP |
|---|---|---|
| 요청자 | vLLM | vLLM |
| 수행자 (실제 일하는 코드) | LMCache | LMCache |
| 수행 환경 | vLLM 프로세스 안, vLLM 의 asyncio loop 위 | LMCache 별도 프로세스, 자체 ThreadPool |
| 결과 받는 사람 | vLLM | vLLM |
| 완료 알림 방식 | asyncio Future | eventfd |
❌ "vLLM 의 async loop 에서 vLLM 이 자기 순서 올 때 캐시 일을 함" ✅ "vLLM 의 async loop 에 LMCache 가 자기 코루틴을 던져 넣고, LMCache 의 코드가 그 loop 위에서 실행됨"
비유: "내 책상을 너한테 빌려줄게. 네가 거기서 일해."
"asyncio loop 외부에서 받음" 의 의미
raw_block_line.md:57 의 표현:
RustRawBlockBackend(legacy) ... asyncio.run_coroutine_threadsafe 로 Core 호출 ... (MP 와 같은 eventfd 비동기 계약 없음 — asyncio loop 외부에서 받음)
= "loop 를 자기가 안 만들고 외부에서 주입받는다"
근거 코드: lmcache/v1/storage_backend/plugins/rust_raw_block_backend.py:90
def __init__(self, ..., loop: Optional[asyncio.AbstractEventLoop] = None, ...):
# 호스트(vLLM) 가 이미 돌리고 있는 자기 loop 를 넘겨줌
같은 파일 377-380:
fut = asyncio.run_coroutine_threadsafe(
self._submit_put_one(...), # ← LMCache 메서드
loop, # ← vLLM 이 빌려준 loop
)
run_coroutine_threadsafe = "내가 있는 스레드와 다른 스레드에서 돌고 있는 asyncio loop 에 코루틴을 제출".
eventfd 3 개 분리 (MP)
근거: private/docs/notes/raw_block_line.md:65
eventfd 3 개 분리 (store / lookup / load)
커널에 신호 통로 3 개를 따로 만들어:
store_efd(fd=7 같은 정수)lookup_efd(fd=8)load_efd(fd=9)
각각 다른 일이 끝났을 때 다른 통로로 알림. 한 통로면 "어떤 일이 끝났지?" 다시 확인해야 하니까.
한 줄 정리
두 모드 모두 LMCache 가 일을 한다. 차이는 어디서 그 일이 도느냐 (vLLM loop 빌려서 vs 별도 프로세스) 와 완료를 어떻게 알리느냐 (Future vs eventfd) 뿐.