본문으로 건너뛰기

비동기 메커니즘 — Future vs eventfd

변경 검증 가이드 (다음 fetch 후):

git log eaa2bfee..HEAD -- lmcache/v1/storage_backend/plugins/rust_raw_block_backend.py
git 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-processMP
요청자vLLMvLLM
수행자 (실제 일하는 코드)LMCacheLMCache
수행 환경vLLM 프로세스 안, vLLM 의 asyncio loop 위LMCache 별도 프로세스, 자체 ThreadPool
결과 받는 사람vLLMvLLM
완료 알림 방식asyncio Futureeventfd

❌ "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) 뿐.