장애 대응

Kafka 클러스터에서 발생할 수 있는 장애 상황과 대응 방법을 살펴봅니다.

장애 유형

장애 분류

┌─────────────────────────────────────────────────────────────────┐
│                     Kafka Failure Types                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │              Critical (즉시 대응)                         │   │
│  │  - 전체 클러스터 다운                                      │   │
│  │  - 다수 Broker 장애                                        │   │
│  │  - 데이터 손실 위험                                        │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │              High (1시간 내 대응)                          │   │
│  │  - 단일 Broker 장애                                        │   │
│  │  - 파티션 리더 없음                                        │   │
│  │  - Consumer Group 문제                                     │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │              Medium (당일 대응)                            │   │
│  │  - Under-replicated 파티션                                │   │
│  │  - Consumer Lag 증가                                       │   │
│  │  - 성능 저하                                               │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

장애 진단 절차

초기 진단 체크리스트

# 1. 클러스터 상태 확인
kafka-broker-api-versions.sh --bootstrap-server localhost:9092
 
# 2. 토픽/파티션 상태 확인
kafka-topics.sh --bootstrap-server localhost:9092 --describe
 
# 3. Under-replicated 파티션 확인
kafka-topics.sh --bootstrap-server localhost:9092 \
    --describe --under-replicated-partitions
 
# 4. 오프라인 파티션 확인
kafka-topics.sh --bootstrap-server localhost:9092 \
    --describe --unavailable-partitions
 
# 5. Consumer Group 상태 확인
kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
    --describe --all-groups
 
# 6. 로그 확인
tail -f /var/log/kafka/server.log | grep -E "ERROR|WARN"

진단 흐름도

장애 감지
    │
    ▼
┌─────────────────────────────────────────┐
│ 1. 클러스터 접근 가능?                   │
│    NO → Broker/Network 문제 확인        │
│    YES ↓                                │
└─────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────┐
│ 2. Controller 활성화?                    │
│    NO → Controller 선출 문제            │
│    YES ↓                                │
└─────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────┐
│ 3. 파티션 상태 정상?                     │
│    Offline → Leader 없음               │
│    Under-replicated → 복제 지연         │
│    OK ↓                                 │
└─────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────┐
│ 4. Producer/Consumer 문제?              │
│    YES → 클라이언트 설정/네트워크 확인  │
│    NO → 성능 문제 조사                  │
└─────────────────────────────────────────┘

장애 시나리오별 대응

시나리오 1: Broker 다운

증상

  • 특정 Broker에 연결 불가
  • Under-replicated 파티션 발생
  • 일부 파티션 리더 없음

진단

# Broker 상태 확인
kafka-broker-api-versions.sh --bootstrap-server <broker>:9092
 
# 해당 Broker의 파티션 확인
kafka-topics.sh --bootstrap-server localhost:9092 --describe \
    | grep "Leader: <broker-id>"
 
# 시스템 로그 확인
journalctl -u kafka -f
dmesg | tail

대응

# 1. Broker 재시작 시도
systemctl restart kafka
 
# 2. 재시작 실패 시 로그 분석
cat /var/log/kafka/server.log | grep -E "ERROR|FATAL"
 
# 3. 디스크 공간 확인
df -h /var/kafka-logs
 
# 4. OOM 확인
dmesg | grep -i "out of memory"
 
# 5. Broker 복구 불가 시 - 새 Broker로 교체
# 파티션 재할당 필요

시나리오 2: Controller 장애

증상

  • 토픽/파티션 생성 불가
  • Leader 선출 안됨
  • 클러스터 메타데이터 변경 불가

진단

# Controller 확인
kafka-metadata.sh --snapshot /var/kafka-logs/__cluster_metadata-0/00000000000000000000.log \
    --command "describe --controller"
 
# ZooKeeper 모드에서 Controller 확인
echo dump | nc zookeeper:2181 | grep controller
 
# Controller 로그 확인
grep "controller" /var/log/kafka/server.log

대응

# 1. Controller 재선출 강제
# ZooKeeper 모드
zkCli.sh -server zookeeper:2181
rmr /controller
 
# KRaft 모드
# Controller Quorum이 자동으로 새 Controller 선출
 
# 2. Controller Broker 재시작
systemctl restart kafka
 
# 3. Controller 격리 및 교체 (심각한 경우)

시나리오 3: 오프라인 파티션

증상

  • Producer 전송 실패
  • Consumer 소비 불가
  • “Leader not available” 오류

진단

# 오프라인 파티션 확인
kafka-topics.sh --bootstrap-server localhost:9092 \
    --describe --unavailable-partitions
 
# 파티션 상세 정보
kafka-topics.sh --bootstrap-server localhost:9092 \
    --describe --topic <topic>
 
# ISR 상태 확인
# Replicas: 1,2,3  ISR: (비어있음) → 모든 Replica 다운

대응

# 1. Replica Broker 상태 확인 및 복구
 
# 2. Unclean Leader Election (데이터 손실 감수)
kafka-configs.sh --bootstrap-server localhost:9092 \
    --alter --entity-type topics --entity-name <topic> \
    --add-config unclean.leader.election.enable=true
 
# 3. 수동 Leader 선출 (KRaft 모드)
kafka-leader-election.sh --bootstrap-server localhost:9092 \
    --topic <topic> --partition <partition> \
    --election-type unclean
 
# 4. 설정 복원
kafka-configs.sh --bootstrap-server localhost:9092 \
    --alter --entity-type topics --entity-name <topic> \
    --delete-config unclean.leader.election.enable

시나리오 4: Under-replicated 파티션

증상

  • ISR 크기 < Replication Factor
  • 복제 지연 알림

진단

# Under-replicated 파티션 목록
kafka-topics.sh --bootstrap-server localhost:9092 \
    --describe --under-replicated-partitions
 
# 네트워크 지연 확인
ping <broker-host>
 
# Broker 간 복제 상태
kafka-replica-verification.sh --broker-list localhost:9092 \
    --topic-white-list <topic>

대응

# 1. 네트워크 문제 확인 및 해결
 
# 2. Follower Broker 리소스 확인
# CPU, Memory, Disk I/O
 
# 3. 복제 스로틀 확인
kafka-configs.sh --bootstrap-server localhost:9092 \
    --describe --entity-type brokers --entity-name <broker-id>
 
# 4. 복제 스로틀 조정
kafka-configs.sh --bootstrap-server localhost:9092 \
    --alter --entity-type brokers --entity-name <broker-id> \
    --add-config follower.replication.throttled.rate=100000000
 
# 5. 복제 완료 후 스로틀 제거

시나리오 5: Consumer Lag 급증

증상

  • Consumer Lag 지속 증가
  • 처리 지연
  • 데이터 처리 적체

진단

# Consumer Lag 확인
kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
    --describe --group <group-id>
 
# Consumer 메트릭 확인
# - records-consumed-rate
# - fetch-latency-avg
# - rebalance-rate-per-hour

대응

# 1. Consumer 인스턴스 증가
# 파티션 수 이하로 Consumer 추가
 
# 2. Consumer 설정 최적화
# max.poll.records 조정
# fetch.min.bytes, fetch.max.wait.ms 조정
 
# 3. 처리 로직 최적화
# 배치 처리, 비동기 처리
 
# 4. 긴급 시 - 오래된 메시지 건너뛰기
kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
    --group <group-id> --reset-offsets --to-latest \
    --topic <topic> --execute
 
# 5. 파티션 수 증가 (장기적)
kafka-topics.sh --bootstrap-server localhost:9092 \
    --alter --topic <topic> --partitions <new-count>

시나리오 6: 디스크 공간 부족

증상

  • Broker 시작 실패
  • 메시지 저장 실패
  • “No space left on device” 오류

진단

# 디스크 사용량 확인
df -h /var/kafka-logs
 
# 토픽별 사용량
du -sh /var/kafka-logs/* | sort -rh | head -20
 
# 가장 큰 토픽 확인
kafka-log-dirs.sh --bootstrap-server localhost:9092 \
    --describe --broker-list <broker-id>

대응

# 1. 즉시 - 불필요한 토픽 삭제
kafka-topics.sh --bootstrap-server localhost:9092 \
    --delete --topic <unused-topic>
 
# 2. Retention 정책 조정
kafka-configs.sh --bootstrap-server localhost:9092 \
    --alter --entity-type topics --entity-name <topic> \
    --add-config retention.ms=86400000  # 1일로 축소
 
# 3. 세그먼트 강제 삭제 (긴급)
kafka-delete-records.sh --bootstrap-server localhost:9092 \
    --offset-json-file offsets.json
 
# 4. 디스크 추가/교체 (장기적)
 
# 5. 로그 디렉토리 추가
# server.properties: log.dirs=/disk1/kafka-logs,/disk2/kafka-logs

긴급 복구 절차

클러스터 전체 다운 복구

# 1. ZooKeeper 상태 확인 (ZK 모드)
echo stat | nc zookeeper:2181
 
# 2. Broker 순차 시작
# Controller eligible Broker 먼저
systemctl start kafka-controller-1
sleep 30
systemctl start kafka-broker-1
sleep 30
systemctl start kafka-broker-2
 
# 3. 클러스터 상태 확인
kafka-broker-api-versions.sh --bootstrap-server localhost:9092
 
# 4. 토픽 상태 확인
kafka-topics.sh --bootstrap-server localhost:9092 --describe
 
# 5. Producer/Consumer 복구

데이터 복구

# 1. 마지막 정상 Offset 확인
kafka-run-class.sh kafka.tools.DumpLogSegments \
    --files /var/kafka-logs/<topic>-<partition>/00000000000000000000.log \
    --print-data-log
 
# 2. Consumer Offset 확인
kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
    --describe --group <group-id>
 
# 3. 특정 Offset으로 리셋 (필요시)
kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
    --group <group-id> --reset-offsets --to-offset <offset> \
    --topic <topic>:<partition> --execute

장애 예방

헬스체크 구현

#!/bin/bash
# kafka-health-check.sh
 
BOOTSTRAP_SERVER="localhost:9092"
 
# Broker 연결 확인
if ! kafka-broker-api-versions.sh --bootstrap-server $BOOTSTRAP_SERVER > /dev/null 2>&1; then
    echo "CRITICAL: Cannot connect to Kafka"
    exit 2
fi
 
# Under-replicated 파티션 확인
URP=$(kafka-topics.sh --bootstrap-server $BOOTSTRAP_SERVER \
    --describe --under-replicated-partitions 2>/dev/null | wc -l)
 
if [ "$URP" -gt 0 ]; then
    echo "WARNING: $URP under-replicated partitions"
    exit 1
fi
 
# 오프라인 파티션 확인
OFFLINE=$(kafka-topics.sh --bootstrap-server $BOOTSTRAP_SERVER \
    --describe --unavailable-partitions 2>/dev/null | wc -l)
 
if [ "$OFFLINE" -gt 0 ]; then
    echo "CRITICAL: $OFFLINE offline partitions"
    exit 2
fi
 
echo "OK: Kafka cluster is healthy"
exit 0

Runbook 템플릿

incident:
  name: "Kafka Broker Down"
  severity: High
  on_call: "platform-team"
 
detection:
  - "Broker health check failed"
  - "Prometheus alert: KafkaBrokerDown"
 
immediate_actions:
  - "Acknowledge alert"
  - "Check Broker status: systemctl status kafka"
  - "Check system resources: top, df -h, dmesg"
 
investigation:
  - "Review Broker logs: /var/log/kafka/server.log"
  - "Check recent changes: git log, deployment history"
  - "Verify network connectivity"
 
resolution:
  - "Restart Broker if safe"
  - "Scale out if needed"
  - "Perform partition reassignment if necessary"
 
post_incident:
  - "Document root cause"
  - "Update monitoring/alerting"
  - "Conduct post-mortem if needed"

Best Practices

1. 사전 준비

✓ 정기 백업 및 복구 테스트
✓ Runbook 문서화 및 갱신
✓ 장애 시뮬레이션 훈련
✓ 롤백 계획 수립

2. 장애 대응 원칙

1. 침착하게 상황 파악
2. 영향 범위 확인
3. 에스컬레이션 여부 결정
4. 임시 조치 후 근본 해결
5. 사후 분석 및 재발 방지

3. 커뮤니케이션

- 장애 발생 즉시 이해관계자 알림
- 정기적 상황 업데이트
- 복구 완료 공지
- 사후 분석 결과 공유

관련 문서