Kafka 컨슈머 랙 급증 장애 복구 플레이북: 40분 안에 원인 좁히는 운영 절차
💡 Key Takeaways
- 랙 증가는 처리량 부족, 파티션 불균형, 외부 의존성 지연 중 어디에서 병목이 생겼는지 먼저 분리해야 빠르게 대응할 수 있습니다.
- 장애 중에는 재처리 정확성보다 서비스 영향 축소를 우선하고, 소비 재개 전략을 명확히 나눠야 복구 시간이 줄어듭니다.
- 복구 후에는 컨슈머 설정값보다 배포 단위, 알림 임계치, 재시도 정책을 함께 손봐야 같은 장애를 반복하지 않습니다.
Kafka 컨슈머 랙 급증 장애 복구 플레이북
온콜을 하다 보면 가장 당황스러운 순간이 "평소 2천 미만이던 랙이 20만을 넘어갔다"는 알림을 새벽에 받는 때입니다. 이때 많은 팀이 컨슈머 인스턴스 수를 먼저 늘리지만, 실제로는 처리량이 아니라 특정 파티션 편중이나 외부 API 지연이 원인인 경우가 더 많습니다. 지난 분기 우리 팀도 주문 이벤트 파이프라인에서 같은 일을 겪었고, 초반 10분을 잘못 써서 증상을 더 키웠습니다. 파티션 48개 중 3개에만 지연이 몰려 있었는데 전체 스케일아웃을 먼저 하면서 리밸런싱이 연속 발생했고, 오히려 정상 파티션 처리량까지 떨어졌습니다. 그래서 지금은 장애 초기에 보는 지표를 고정했습니다. 첫째, 토픽 전체 랙이 아니라 파티션별 분포를 본다. 둘째, 컨슈머 처리율(records/sec)과 폴링 간격을 같이 본다. 셋째, 다운스트림 의존성(PG, Redis, 외부 API) p95 지연을 같은 시간축으로 겹쳐 본다. 이 세 가지를 5분 안에 확인하면 "확장 문제인지, 병목 문제인지"를 거의 구분할 수 있습니다.
원인 분류가 끝나면 복구 모드를 두 단계로 나눕니다. 1단계는 서비스 영향 최소화, 2단계는 정합성 회복입니다. 예를 들어 결제 완료 알림처럼 지연 허용 범위가 짧은 이벤트는 우선순위를 높이고, 통계 집계 이벤트는 일시적으로 소비 속도를 낮춰도 됩니다. 우리 팀은 컨슈머 그룹을 기능별로 나눠 두었기 때문에, 장애 시에는 영향이 큰 그룹만 max.poll.records와 워커 풀을 조정해 단기 처리량을 끌어올립니다. 반대로 외부 API 429가 원인이면 재시도 간격을 늘리고 서킷 브레이커를 먼저 여는 편이 안전합니다. 여기서 중요한 건 "모든 실패를 즉시 재시도"하지 않는 것입니다. 장애 당시 재시도 폭주가 랙을 더 키우는 경우가 잦기 때문입니다. 실제로 우리는 재시도 큐 적재량이 4배로 늘던 구간에서, 지수 백오프 상한을 8초에서 45초로 올리고 동시 처리 수를 30% 줄여 12분 만에 증가 곡선을 꺾었습니다. 복구는 빨리 하는 것도 중요하지만, 회복 도중 2차 장애를 만들지 않는 것이 더 중요합니다.
현장에서는 "언제 컨슈머를 리스타트할지"도 자주 논쟁이 됩니다. 경험상 리스타트는 원인 파악 전 기본 액션이 아니라, 폴링 스레드 교착이나 메모리 누수 징후가 명확할 때만 선택해야 합니다. 무작정 재시작하면 그룹 리밸런싱이 늘어나 짧은 시간에는 더 나빠질 수 있습니다. 저는 리스타트 여부를 세 가지로 판단합니다. 첫째, CPU는 낮은데 처리율만 급락했는가. 둘째, 동일 배포 버전에서만 랙이 증가했는가. 셋째, 특정 인스턴스 로그에 커밋 지연/타임아웃이 반복되는가. 세 조건 중 둘 이상이면 순차 재시작(한 번에 1대)으로 들어갑니다. 동시에 오프셋 커밋 전략도 점검합니다. 자동 커밋에만 의존한 서비스는 장애 중 중복 처리와 유실 공포가 커서 의사결정이 늦어집니다. 그래서 최소한 핵심 토픽은 수동 커밋 기준을 문서화해 두는 편이 좋습니다. 우리 팀은 "외부 부작용 호출 성공 후 커밋" 원칙을 명시해, 복구 중에도 롤백 포인트를 명확히 잡았습니다. 이 한 줄 원칙이 있으면 장애 회의에서 논쟁 시간이 눈에 띄게 줄어듭니다.
복구가 끝난 뒤에는 그래프가 정상으로 돌아왔다고 바로 종료하지 말고 운영 체크리스트를 남겨야 합니다. 저는 항상 네 가지를 기록합니다. 장애 탐지 시각과 실제 증상 시작 시각의 차이, 랙 증가를 가장 먼저 설명한 지표 하나, 복구에 효과 없었던 액션, 다음 배포 전에 반드시 바꿀 설정값입니다. 이 기록이 있어야 다음 온콜이 같은 함정에 빠지지 않습니다. 특히 알림 임계치와 런북 문구는 반드시 손봐야 합니다. "랙 5만 초과" 같은 단일 임계치는 트래픽 시즌성에 취약하므로, 최근 30분 평균 대비 증가율과 지속 시간 조건을 함께 두는 게 안전합니다. 마지막으로 리허설을 권합니다. 월 1회라도 스테이징에서 의도적으로 컨슈머 지연을 만들고, 온콜이 동일 절차로 대응해 시간을 재보면 문서의 빈 구멍이 바로 드러납니다. 장애는 피하기 어렵지만, 대응 속도와 판단 품질은 반복 훈련으로 확실히 개선할 수 있습니다.