[Kafka 운영 ⑨] 장애 대응 런북 — 증상별 진단·조치 의사결정 트리
컨슈머 랙 급증, URP, 오프라인 파티션, 컨트롤러 부재, 디스크 풀, ISR 플래핑, 요청 지연까지 — Kafka 장애를 증상별로 탐지·진단·조치하는 운영 런북. 시리즈 1~8편을 하나로 묶는 의사결정 트리와 JMX 메트릭·CLI 치트시트.
새벽 3시에 페이저가 울립니다. "프로듀서 지연 알림"이라는 한 줄짜리 메시지뿐, 무엇이 잘못됐는지는 알려주지 않습니다. 브로커가 죽었나? 디스크가 찼나? 컨트롤러가 사라졌나? 이럴 때 필요한 건 영웅적인 감(感)이 아니라, 증상 하나에서 출발해 원인까지 좁혀 들어가는 런북입니다. 이 글은 지금까지의 Kafka 운영 시리즈(1~8편)에서 다룬 진단 기법들을 하나의 의사결정 트리로 묶어, 장애 상황에서 그대로 따라갈 수 있는 운영 매뉴얼로 정리합니다.
이 글에서 배우는 것
- 증상 → 분기 → 조치로 이어지는 마스터 의사결정 트리
- 컨슈머 랙 급증, URP, 오프라인 파티션, 컨트롤러 부재 등 7대 증상별 탐지·진단·조치 절차
- 각 증상에 직결되는 JMX 메트릭과 정상 임계값
- 장애 현장에서 바로 쓰는 CLI 치트시트(
kafka-topics.sh,kafka-consumer-groups.sh,kafka-log-dirs.sh,kafka-reassign-partitions.sh)- 1~8편의 진단 기법을 언제 꺼내 쓸지 연결하는 지도
1. 런북을 쓰는 법 — 증상에서 출발하라
장애 대응에서 가장 흔한 실수는 원인을 먼저 추측하는 것입니다. "아마 GC 때문일 거야"라고 단정하고 GC 로그부터 뒤지다가, 실제로는 디스크가 가득 찬 상황을 놓칩니다. 좋은 런북은 반대로 갑니다. 관측 가능한 증상(메트릭·알림)에서 출발해, 분기 조건을 따라 원인을 좁히고, 검증된 조치로 끝냅니다.
이 글의 모든 절은 동일한 3단 구조를 따릅니다.
| 단계 | 질문 | 도구 |
|---|---|---|
| 탐지 (Detect) | 무엇이 잘못됐다고 알려주는가? | JMX 메트릭, 알림 규칙 |
| 진단 (Diagnose) | 가능한 원인 중 어느 것인가? | CLI, 로그, 분기 조건 |
| 조치 (Remediate) | 안전하게 무엇을 할 것인가? | 재시작·재할당·설정 변경 |
그리고 모든 조치에 앞서 세 가지를 기록하세요. (1) 증상이 시작된 시각, (2) 최근 배포·설정 변경 이력, (3) 영향받은 토픽·파티션·컨슈머 그룹. 이 세 줄이 사후 분석(postmortem)의 절반입니다.
2. 마스터 의사결정 트리
페이저가 울렸을 때 가장 먼저 펼칠 그림입니다. 가장 치명적인 증상(데이터 가용성에 직접 영향)을 위쪽에 두고, 영향 범위가 좁은 순서로 분기합니다.
분기 순서가 곧 우선순위입니다. 오프라인 파티션과 컨트롤러 부재는 클러스터 전체의 가용성을 위협하므로 먼저 확인합니다. 컨슈머 랙은 심각하지만 보통 데이터 손실 없이 회복 가능하므로 마지막에 둡니다. 단, 여러 증상이 동시에 나타나면 보통 상류 원인 하나(예: 브로커 다운)가 URP·ISR·랙을 연쇄로 일으킨 것이니, 트리 위쪽의 원인부터 해소하세요.
3. 증상: 컨슈머 랙 급증
다운스트림이 데이터를 제때 받지 못한다는 가장 직접적인 신호입니다. (자세한 컨슈머 내부 동작은 1·2편, 랙 모니터링 심화는 6편 참조.)
탐지
| 메트릭 | 위치 | 의미 |
|---|---|---|
records-lag-max | 컨슈머 클라이언트 JMX (consumer-fetch-manager-metrics) | 컨슈머가 가장 뒤처진 파티션의 랙(레코드 수) |
records-consumed-rate | 컨슈머 클라이언트 JMX | 초당 소비 레코드 수 — 0에 수렴하면 정지 |
그룹 LAG 합계 | kafka-consumer-groups.sh --describe | 그룹 전체 랙. 외부 익스포터(Burrow 등)로 추세 관측 |
알림 기준은 절대값보다 추세가 낫습니다. "랙이 N분간 단조 증가" 또는 "소비율이 0인데 프로듀스율은 양수"가 좋은 조건입니다.
진단
# 그룹 상태와 파티션별 랙 한눈에 보기
kafka-consumer-groups.sh --bootstrap-server broker:9092 \
--group payment-consumer --describe출력의 분기 포인트:
| 관측 | 가능한 원인 | 다음 행동 |
|---|---|---|
CONSUMER-ID가 비어 있음 | 컨슈머가 떨어져 나감(크래시·배포) | 컨슈머 프로세스/로그 확인 |
STATE = PreparingRebalance가 지속 | 리밸런스 폭풍, 세션 타임아웃 | max.poll.interval.ms·처리 시간 점검 |
| 특정 파티션만 랙이 큼 | 핫 파티션 / 키 편향 / 느린 핸들러 | 파티셔닝·처리 로직 점검 |
| 모든 파티션 랙이 균일하게 증가 | 처리량 부족 / 다운스트림 정체 | 컨슈머 스케일아웃 |
조치
- 리밸런스 폭풍:
max.poll.records를 낮추거나 처리 로직을 빠르게 해max.poll.interval.ms내에 폴 주기를 지키도록 한다. 협력적 리밸런싱(cooperative-sticky)으로 전환해 stop-the-world를 줄인다. - 처리량 부족: 파티션 수 한도 내에서 컨슈머 인스턴스를 늘린다(컨슈머 수는 파티션 수를 넘으면 유휴가 됨).
- 핫 파티션: 키 설계를 재검토하거나 파티션 수를 늘려 재분배(기존 데이터 순서 보장에 미치는 영향 유의).
- 다운스트림 정체: DB·외부 API 등 싱크의 병목을 먼저 해소한다. 컨슈머만 늘리면 싱크 부하만 키운다.
4. 증상: Under-Replicated Partitions (URP)
리더는 살아 있지만 일부 복제본이 ISR(In-Sync Replica)에서 빠진 상태입니다. 즉시 데이터 손실은 아니지만, 내결함성이 줄어든 위험 구간입니다.
탐지
| 메트릭 | 정상값 | 경고 |
|---|---|---|
kafka.server:type=ReplicaManager,name=UnderReplicatedPartitions | 0 | > 0이 수 분간 지속되면 조사 |
# 어떤 파티션이 URP인지 직접 확인
kafka-topics.sh --bootstrap-server broker:9092 \
--describe --under-replicated-partitions진단
URP의 원인은 대개 셋 중 하나입니다.
- 브로커 다운:
kafka-broker-api-versions.sh --bootstrap-server ...로 살아 있는 브로커를 확인하거나, 컨트롤러 로그에서BrokerChange를 본다. 죽은 브로커가 가진 복제본 전부가 URP로 잡힌다. - 느린 팔로워: 팔로워가
replica.lag.time.max.ms(기본 30s) 내에 리더를 따라잡지 못해 ISR에서 빠진다. 디스크 I/O 포화·긴 GC가 흔한 원인(8편과 동일 진단). - 네트워크: 브로커 간 패킷 손실·대역폭 부족.
RequestQueueTimeMs·복제 트래픽 메트릭으로 확인.
조치
| 원인 | 조치 |
|---|---|
| 브로커 다운 | 브로커를 복구·재시작한다. 복귀하면 팔로워가 자동으로 따라잡아 ISR에 재합류 → URP 0으로 수렴 |
| 영구 소실 브로커 | kafka-reassign-partitions.sh로 복제본을 살아 있는 브로커로 재할당 |
| 느린 팔로워 | 디스크·GC 문제 해소(§8). 일시적이면 자동 회복 |
| 리더 편중 | 복구 후 kafka-leader-election.sh --election-type preferred로 선호 리더 재배치 |
브로커를 롤링 재시작할 때는 한 번에 하나씩, 그리고 직전 브로커의 URP가 0으로 돌아온 뒤 다음으로 넘어가세요. 동시에 두 대를 내리면
min.insync.replicas를 깨뜨려 쓰기가 막힐 수 있습니다.
5. 증상: 오프라인 파티션
가장 심각한 증상입니다. 해당 파티션에 리더가 없어 프로듀스도 컨슘도 불가능합니다. 데이터 가용성에 직접 영향이 가므로 트리 최상단에서 확인합니다. (언클린 리더 선출과 ISR 의미는 5편 참조.)
탐지
| 메트릭 | 정상값 | 경고 |
|---|---|---|
kafka.controller:type=KafkaController,name=OfflinePartitionsCount | 0 | > 0이면 즉시 대응(페이지) |
진단
오프라인 파티션은 보통 다음 조합에서 발생합니다.
- ISR에 남은 복제본이 없음 + 언클린 리더 선출 비활성(
unclean.leader.election.enable=false, 운영 권장 기본값). ISR이 비면 Kafka는 손상 위험이 있는 비동기 복제본을 리더로 올리지 않고 파티션을 오프라인으로 둡니다 — 가용성보다 일관성을 택한 결과입니다.
# 리더가 -1(없음)인 파티션 찾기
kafka-topics.sh --bootstrap-server broker:9092 \
--describe --topic orders | grep "Leader: -1"원인을 좁히려면 직전에 여러 브로커가 동시에 내려갔는지(전원·랙·스토리지 장애)를 본다. RF=3에서 ISR이 한 곳으로 줄어든 상태에서 그 브로커마저 죽으면 ISR이 비고 파티션이 오프라인이 됩니다.
조치
데이터 손실을 감수하고 가용성을 회복해야 한다면, 영향 토픽에 한해 언클린 리더 선출을 한시적으로 켭니다.
# 특정 토픽에 한해 언클린 리더 선출 허용 (가용성 우선, 데이터 손실 가능)
kafka-configs.sh --bootstrap-server broker:9092 --alter \
--entity-type topics --entity-name orders \
--add-config unclean.leader.election.enable=true
# 복구 후 반드시 원복할 것언클린 리더 선출은 마지막 수단입니다. ISR 밖의 복제본을 리더로 올리므로 일부 메시지가 영구 손실될 수 있습니다. 켰다면 회복 직후 반드시
false로 되돌리고, 손실 가능 구간을 사후 분석에 기록하세요.
6. 증상: 액티브 컨트롤러 부재(또는 중복)
컨트롤러는 파티션 리더십·ISR·토픽 메타데이터를 관장합니다. 컨트롤러가 없으면 리더 선출·재할당 같은 메타데이터 변경이 멈춥니다.
탐지
ActiveControllerCount는 클러스터 전체 합이 정확히 1이어야 합니다. 각 브로커가 0 또는 1을 보고하며, 모두 합쳐 1이면 정상입니다.
| 합계 | 의미 | 심각도 |
|---|---|---|
1 | 정상 — 단일 컨트롤러 | OK |
0 | 컨트롤러 없음 — 메타데이터 변경 마비 | 치명 |
2+ | 스플릿 브레인 — 컨트롤러 중복 | 치명 |
# 브로커별 ActiveControllerCount 합 확인 (JMX → Prometheus 권장)
# 합이 1이 아니면 즉시 페이지진단
- KRaft 모드(컨트롤러 쿼럼): 컨트롤러는 별도 쿼럼(
controller.quorum.voters)에서 선출됩니다. 합이 0이면 쿼럼이 과반(majority)을 잃은 것 — 컨트롤러 노드 과반이 살아 있는지 확인합니다.kafka-metadata-quorum.sh로 리더·복제 상태를 점검합니다.
# KRaft: 메타데이터 쿼럼 상태 확인
kafka-metadata-quorum.sh --bootstrap-controller controller:9093 describe --status
kafka-metadata-quorum.sh --bootstrap-controller controller:9093 describe --replication- ZooKeeper 모드(레거시): 컨트롤러는 ZK의
/controller노드 선점으로 정해집니다. 합이 0이면 ZK 세션 만료·연결 단절이, 2+이면 (드물게) 좀비 컨트롤러나 네트워크 분할이 의심됩니다. ZK 앙상블의 과반 가용성과 ZK↔브로커 연결을 확인합니다.
조치
| 상황 | 조치 |
|---|---|
| KRaft 쿼럼 과반 소실 | 컨트롤러 노드를 복구해 과반을 회복한다. 데이터 디렉터리 손상 시 메타데이터 복원 절차 수행 |
| ZK 세션 문제 | ZK 앙상블 안정화(과반 노드 확인), zookeeper.session.timeout.ms 점검 |
| 컨트롤러 중복(2+) | 네트워크 분할을 해소한다. 통상 분할 해소 시 한쪽이 자진 사임. 강제로 컨트롤러를 옮기려면 현재 컨트롤러 브로커를 재시작해 페일오버 유도 |
정상적인 컨트롤러 페일오버(예: 컨트롤러 브로커 1대 재시작)는 합을 일시적으로 0으로 떨어뜨렸다가 곧 1로 회복합니다. 알림은 "1이 아닌 상태가 수십 초 이상 지속"일 때만 울리도록 디바운스하세요.
7. 증상: 디스크 풀 / 로그 디렉터리 오프라인
브로커가 데이터를 쓸 곳이 없으면 해당 로그 디렉터리를 오프라인 처리하고, 그 디렉터리의 모든 복제본이 URP→오프라인으로 번질 수 있습니다. (스토리지·리텐션 설계는 7편에서 상세히 다뤘으니 함께 보세요.)
탐지
| 신호 | 위치 |
|---|---|
kafka.log:type=LogManager,name=OfflineLogDirectoryCount | > 0이면 디스크/마운트 문제 |
| 디스크 사용률 95%+ | 노드 익스포터(node_exporter) disk_used_percent |
브로커 로그의 No space left on device, Error while writing to checkpoint file | 브로커 server.log |
진단
# 브로커별/로그 디렉터리별 사용량과 파티션 크기 확인
kafka-log-dirs.sh --bootstrap-server broker:9092 \
--describe --broker-list 1,2,3 | python3 -m json.tool | less분기 포인트:
- 단순 용량 초과: 특정 토픽이 리텐션 설정보다 빠르게 적재.
retention.ms/retention.bytes가 적절한지, 갑작스러운 트래픽 급증이 있었는지 확인. - 로그 디렉터리 오프라인(마운트/디스크 장애):
OfflineLogDirectoryCount > 0. 디스크 자체 장애. 해당 브로커가 보유한 복제본이 위험.
조치
| 원인 | 즉시 조치 | 근본 조치 |
|---|---|---|
| 리텐션 과다 | 영향 토픽 retention.ms/retention.bytes를 한시적으로 줄여 세그먼트 삭제 유도 | 토픽별 리텐션 정책 재설계(7편) |
| 트래픽 급증 | 디스크 증설 또는 일부 파티션을 여유 브로커로 재할당 | 용량 계획·알림 임계값 조정 |
| 디스크 장애 | 오프라인 디렉터리 브로커를 점검·교체. 복제본은 다른 브로커에 이미 존재(RF≥2) | JBOD 디스크 교체 절차 정비 |
# 한시적으로 리텐션을 줄여 디스크 압박 완화 (주의: 데이터 조기 삭제)
kafka-configs.sh --bootstrap-server broker:9092 --alter \
--entity-type topics --entity-name verbose-logs \
--add-config retention.ms=3600000디스크는 80%에서 알림, 90%에서 행동이 안전선입니다. 100%에 닿으면 브로커가 쓰기 불능에 빠지고, 복구 중에도 컴팩션·세그먼트 삭제에 추가 공간이 필요해 회복이 더 어려워집니다.
8. 증상: ISR 수축/플래핑
복제본이 ISR에 들어왔다 나갔다를 반복(flapping)하면, 그 자체로는 가용성을 깨지 않더라도 URP·오프라인 파티션의 전조입니다.
탐지
| 메트릭 | 의미 | 경고 |
|---|---|---|
kafka.server:type=ReplicaManager,name=IsrShrinksPerSec | 초당 ISR 축소 횟수 | 지속적으로 0보다 큼 |
kafka.server:type=ReplicaManager,name=IsrExpandsPerSec | 초당 ISR 확장 횟수 | shrink와 함께 반복되면 플래핑 |
수축과 확장이 번갈아 반복되면 복제본이 replica.lag.time.max.ms(기본 30,000ms) 경계에서 아슬아슬하게 줄타기하고 있다는 뜻입니다.
진단
- GC 일시정지: 풀 GC가
replica.lag.time.max.ms를 넘기면 팔로워가 잠깐 ISR에서 빠졌다 회복. GC 로그에서 stop-the-world 시간 확인. - 디스크 I/O 포화: 팔로워가 리더의 데이터를 디스크에 쓰는 속도가 못 따라감.
iostat -x의%util·await로 확인. - 네트워크 지터: 복제 트래픽이 일시적으로 막힘.
조치
- GC: 힙·G1 파라미터 조정, 브로커당 파티션·세그먼트 수가 과도하지 않은지 점검.
- 디스크: 더 빠른 스토리지로 이전하거나 부하 분산(파티션 재할당), 페이지 캐시 여유 확보.
- 경계값 조정은 신중히:
replica.lag.time.max.ms를 무작정 늘리면 진짜로 뒤처진 복제본까지 ISR에 남아 일관성 보장이 약해집니다. 근본 원인(GC·디스크)을 먼저 해결하세요.
9. 증상: 요청 지연 상승
브로커는 살아 있고 복제도 건강한데 프로듀스/페치 응답이 느려집니다. 대개 브로커 내부 스레드 풀 포화가 원인입니다.
탐지
| 메트릭 | 정상값 | 경고 |
|---|---|---|
kafka.server:type=KafkaRequestHandlerPool,name=RequestHandlerAvgIdlePercent | > 0.3 (30%+ 유휴) | < 0.2면 I/O 스레드 포화 |
kafka.network:type=SocketServer,name=NetworkProcessorAvgIdlePercent | > 0.3 | < 0.2면 네트워크 스레드 포화 |
kafka.network:type=RequestMetrics,name=TotalTimeMs,request=Produce (p99) | 안정적 baseline | p99 급등 |
...,request=FetchConsumer (p99) | 안정적 baseline | p99 급등 |
RequestHandlerAvgIdlePercent는 0~1 범위로, 유휴 비율입니다. 0에 가까울수록 I/O 핸들러 스레드가 쉴 틈 없이 일하는 포화 상태입니다.
진단
TotalTimeMs는 단계별로 쪼개 볼 수 있습니다. 어느 구간에서 시간이 새는지가 원인을 가립니다.
| 세부 메트릭 | 늘어나면 의심 |
|---|---|
RequestQueueTimeMs | I/O 핸들러 스레드 부족 → num.io.threads 점검 |
LocalTimeMs | 디스크·페이지 캐시 병목(읽기/쓰기 지연) |
RemoteTimeMs | 복제 대기 — acks=all에서 느린 팔로워(§4·§8) |
ResponseQueueTimeMs / ResponseSendTimeMs | 네트워크 스레드 부족·클라이언트 수신 지연 |
조치
| 원인 | 조치 |
|---|---|
| I/O 스레드 포화 | num.io.threads 상향(보통 디스크 수에 맞춤), 처리량 분산 |
| 네트워크 스레드 포화 | num.network.threads 상향 |
| 복제 대기(RemoteTime) | 느린 팔로워 원인 해소(§8), acks 정책 재검토 |
| 디스크 병목(LocalTime) | 스토리지 업그레이드, 핫 파티션 재분배 |
| 단순 과부하 | 파티션·브로커 확장, 클라이언트 배치(linger.ms·batch.size) 튜닝 |
스레드 수를 늘리기 전에 유휴율과 큐 시간을 함께 보세요. 핸들러 유휴율이 충분한데 p99만 높다면 문제는 스레드가 아니라 디스크나 복제(RemoteTime)일 가능성이 큽니다.
10. 꼭 봐야 할 JMX 메트릭 한눈에 보기
알림 규칙으로 등록해 두면, 위 트리의 분기 질문 대부분을 자동으로 답하게 만들 수 있습니다.
| 메트릭 | MBean (요약) | 정상 임계값 | 무엇을 경고하나 | 관련 절 |
|---|---|---|---|---|
| OfflinePartitionsCount | KafkaController | = 0 | 리더 없는 파티션, 읽기/쓰기 중단 | §5 |
| ActiveControllerCount | KafkaController | 클러스터 합 = 1 | 컨트롤러 부재(0)·중복(2+) | §6 |
| UnderReplicatedPartitions | ReplicaManager | = 0 | 복제 내결함성 저하 | §4 |
| OfflineLogDirectoryCount | LogManager | = 0 | 디스크/마운트 장애 | §7 |
| IsrShrinksPerSec | ReplicaManager | 평상시 0 | 느린 팔로워·GC·디스크 | §8 |
| IsrExpandsPerSec | ReplicaManager | 평상시 0 | (shrink와 함께) 플래핑 | §8 |
| RequestHandlerAvgIdlePercent | KafkaRequestHandlerPool | > 0.3 | I/O 스레드 포화 | §9 |
| NetworkProcessorAvgIdlePercent | SocketServer | > 0.3 | 네트워크 스레드 포화 | §9 |
| TotalTimeMs (Produce/Fetch p99) | RequestMetrics | 안정 baseline | 요청 지연 | §9 |
| records-lag-max | 컨슈머 클라이언트 | 추세 평탄 | 컨슈머 랙 | §3 |
| BytesInPerSec / BytesOutPerSec | BrokerTopicMetrics | baseline 대비 | 트래픽 급변(용량) | §7 |
절대 임계값은 클러스터마다 다릅니다. **카운터형(Offline·URP·Controller)은 정확한 값(0 또는 1)**으로, 비율·게이지형(IdlePercent·p99·lag)은 baseline 대비 편차로 알림을 거는 것이 오탐을 줄입니다.
11. CLI 치트시트
장애 현장에서 가장 자주 꺼내는 명령들입니다. --bootstrap-server(브로커)와 --bootstrap-controller(KRaft 컨트롤러)를 혼동하지 마세요.
# ── 토픽/복제 상태 ──────────────────────────────
# URP 파티션만 출력
kafka-topics.sh --bootstrap-server broker:9092 --describe --under-replicated-partitions
# ISR이 최소치 미만인 파티션
kafka-topics.sh --bootstrap-server broker:9092 --describe --under-min-isr-partitions
# 리더가 없는(오프라인) 파티션
kafka-topics.sh --bootstrap-server broker:9092 --describe --unavailable-partitions
# ── 컨슈머 그룹/랙 ──────────────────────────────
kafka-consumer-groups.sh --bootstrap-server broker:9092 --list
kafka-consumer-groups.sh --bootstrap-server broker:9092 --group payment-consumer --describe
# ── 디스크/로그 디렉터리 ────────────────────────
kafka-log-dirs.sh --bootstrap-server broker:9092 --describe --broker-list 1,2,3
# ── 파티션 재할당 (브로커 소실/편중 시) ─────────
# 1) 재할당 계획 생성
kafka-reassign-partitions.sh --bootstrap-server broker:9092 \
--topics-to-move-json-file topics.json --broker-list "1,2,3" --generate
# 2) 실행
kafka-reassign-partitions.sh --bootstrap-server broker:9092 \
--reassignment-json-file reassignment.json --execute --throttle 50000000
# 3) 진행 상황 확인
kafka-reassign-partitions.sh --bootstrap-server broker:9092 \
--reassignment-json-file reassignment.json --verify
# ── 선호 리더 재배치 (브로커 복귀 후 리더 균형 회복) ──
kafka-leader-election.sh --bootstrap-server broker:9092 --election-type preferred --all-topic-partitions
# ── 컨트롤러/메타데이터 쿼럼 (KRaft) ────────────
kafka-metadata-quorum.sh --bootstrap-controller controller:9093 describe --status
kafka-metadata-quorum.sh --bootstrap-controller controller:9093 describe --replication
# ── 동적 설정 변경 (리텐션/언클린 선출 등) ───────
kafka-configs.sh --bootstrap-server broker:9092 --entity-type topics --entity-name orders --describe재할당 시
--throttle로 복제 대역폭을 제한하세요. 스로틀 없이 대량 재할당을 돌리면 복제 트래픽이 정상 프로듀스/페치를 밀어내 §9 요청 지연을 스스로 유발합니다.
12. 시리즈 지도 — 어느 편을 언제 펴나
이 런북은 진입점입니다. 증상으로 원인을 좁힌 뒤, 깊은 진단·튜닝은 해당 편으로 들어가세요.
| 증상 / 주제 | 이 글의 절 | 깊이 들어갈 편 |
|---|---|---|
| 컨슈머 동작 원리·오프셋 | §3 | 1·2편 (컨슈머/오프셋 관리) |
| 컨슈머 랙 모니터링 심화 | §3 | 6편 (랙 모니터링·알림) |
| ISR·언클린 리더 선출 의미 | §5·§8 | 5편 (복제·ISR·내구성) |
| 디스크·리텐션·스토리지 | §7 | 7편 (스토리지 운영) |
| 브로커/네트워크 튜닝 | §4·§9 | (브로커 튜닝 편) |
마치며
- 장애 대응은 추측이 아니라 증상에서 출발합니다. §2의 마스터 트리를 페이저 옆에 붙여 두세요.
- 분기 순서가 곧 우선순위입니다. 오프라인 파티션 → 컨트롤러 → 디스크 → URP → ISR → 지연 → 랙 순으로 가용성 영향이 큰 것부터 확인합니다.
- 여러 증상이 동시에 보이면 보통 상류 원인 하나(브로커 다운 등)의 연쇄입니다. 트리 위쪽부터 끄세요.
- 카운터형 메트릭(Offline·URP·Controller)은 정확한 값으로, 비율·게이지형은 baseline 대비 편차로 알림을 겁니다.
- 언클린 리더 선출과 스로틀 없는 재할당은 양날의 검입니다. 회복 후 원복과 사후 분석 기록을 잊지 마세요.
- 좋은 런북은 한 번 쓰고 끝나지 않습니다. 장애 한 건마다 트리·임계값·치트시트를 갱신해 다음 새벽 3시를 조금 더 편하게 만드세요.
참고 자료
- Apache Kafka. "Monitoring" — https://kafka.apache.org/documentation/#monitoring
- Apache Kafka. "Operations" — https://kafka.apache.org/documentation/#operations
- Apache Kafka. "Post-Deployment / Datacenters & Geo-Replication" — https://kafka.apache.org/documentation/#datacenters
- Apache Kafka. "KRaft Metadata Quorum" — https://kafka.apache.org/documentation/#kraft
— Data Dynamics 엔지니어링 팀