Bugs · 판별 가이드

좀비 job 판별 — 반복되는 오해 3가지

마지막 업데이트 2026-09-17

사건 2026-09-15 작성 2026-09-17 대상 apps/livekit-agent

한 줄 요약

좀비 job 로그에서 고장처럼 보이지만 정상인 신호 1개(20분마다의 quarantined; reconnecting), 규모를 10배 이상 잘못 읽게 하는 수치 1개(경고 712건), 근거 없이 단정하게 되는 결론 1개(CPU 독식)를 구분하면, 좀비의 확정된 해악은 워커 슬롯 점유 하나로 좁혀진다.

오해 1 — “quarantined; reconnecting이 찍혔으니 세션이 고장났다”

오해 20분마다 이 경고가 9번 찍혔다 → 세션이 망가진 채 job만 살아남았다.

실제 OpenAI Realtime 커넥션을 20분마다 재활용하는 정상 동작이다. 정상 수업 job도 20분을 넘기면 똑같이 찍는다.

코드 경로

올바른 판별: 이 로그의 유무가 아니라 이 로그 뒤로 대화 활동이 있는지를 본다. 좀비는 “20분마다 갱신은 계속되는데 발화·전사가 하나도 없는” 상태다.

오해 2 — “경고 712건 = VAD가 CPU를 부른 횟수”

오해 712건이 곧 부하량이고, 최대 161.8s는 한 번의 추론에 걸린 시간이다.

실제 712는 추론 1회가 200ms를 넘겨 경고가 찍힌 횟수이고, 161.8s는 그 시점의 누적 밀림이다.

항목근거
추론 창 1개512샘플 / 16kHz = 32msSilero 표준값 (네이티브 상수)
경고 임계200msinference/vad.py:34
관측 구간16:00:41~18:12:31 = 7,910초CloudWatch 집계
추론 호출 추정약 247,000회7,910 ÷ 0.032
그중 느렸던 것712회 = 0.29%

누적 밀림은 inference/vad.py:359-364에서 창마다 max(0, 누적 + 추론시간 − 창길이)로 더해지고, 따라잡을 때만 줄어든다. 값이 크다는 것은 “오래 밀린 상태가 유지됐다”는 뜻이지 “한 번이 오래 걸렸다”가 아니다.

건수는 생존 시간에 비례한다. 3시간 산 좀비가 40분 산 수업 job보다 건수가 많은 것은 당연하므로, 비교는 반드시 분당 발생률로 정규화한다.

오해 3 — “좀비가 CPU를 독식해서 다른 수업이 죽었다”

오해 좀비가 한 코어를 100% 물고 있었고, 그래서 옆 job이 굶었다.

실제 실측이 이를 지지하지 않는다. 분당 지연 발생률은 좀비 5.4건/분 vs 피해 job 중앙값 51.9건/분으로 피해 job이 10배 더 밀렸고, 17:20까지는 같은 “동시 2개” 조건에서 정상이었다.

확정된 좀비의 기여는 슬롯 1칸을 3시간 점유해 모든 실수업을 ‘두 번째 동시 job’으로 만든 것까지다. 17:32경 임계를 넘긴 별도 요인은 여전히 미확정이며, 확정에는 해당 태스크의 CPU·메모리 그래프가 필요하다.

왜 배정이 계속됐나apps/livekit-agent/agent.py:355-373_ppi_agent_loadactive_jobs / MAX_JOBS_PER_WORKER만 반환한다(기본 2, agent.py:348). CPU 실측은 들어가지 않으므로 포화된 태스크도 load 0.495로 “여유 있음”을 광고한다. 워커 상태는 0.5초마다 재계산·신고된다(vendor/livekit-agents/.../worker.py:804).

반대 방향의 사고도 같은 원인에서 나온다 — 좀비 2개가 한 태스크의 슬롯 2/2를 채우면 load = 0.99 ≥ threshold가 되어 그 워커가 통째로 배정 대상에서 빠진다(2026-09-16 관측, 7시간 신규 job 0건).

함께 보기