| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
- 타입스크립트
- 실천방법
- ECMAScript
- Javascript
- 자기계발
- 카프카설계
- 자바스크립트
- frontend
- 백엔드개발
- 이벤트드리븐
- 의존성주입
- enum
- EKS네트워크
- TCP/IP
- Flux
- vue store
- MSA
- springboot
- webpack
- 카프카실무
- TypeScript
- GC
- AWSVPC
- DI
- 인생꿀팁
- 추천
- 고동시성
- Vue+Typescript
- HTTP란
- kafka
- Today
- Total
끄적끄적
Kafka Leader/Follower/ISR — Broker 1대가 죽었을 때 30초 장애를 겪고 배운 것들 (실무 설정값 포함) 본문
Kafka Leader/Follower/ISR — Broker 1대가 죽었을 때 30초 장애를 겪고 배운 것들 (실무 설정값 포함)
mashko 2026. 2. 26. 21:14Kafka Leader & Follower
파티션 리더/팔로워 동작 원리 · ISR · Preferred Leader · 실무 장애 시나리오 완전 정리
📋 목차
- 들어가며 — Broker 1대가 죽었을 때 벌어진 일
- Leader와 Follower — 역할 분담의 핵심
- ISR(In-Sync Replica) — 가장 중요한 개념
- Leader Election — 리더는 어떻게 선출되나
- Preferred Leader Rebalancing — 실무에서 왜 중요한가
- acks 설정과 ISR의 관계 — 유실 vs 성능 트레이드오프
- 실무 장애 시나리오와 대응법
- 운영 핵심 설정값 총정리
들어가며 — Broker 1대가 죽었을 때 벌어진 일
Kafka 클러스터를 운영하던 중 Broker 1대에 디스크 장애가 났습니다. 순간적으로 Producer가 메시지를 보내지 못하는 현상이 발생했고, Consumer Lag이 급격히 쌓이기 시작했어요. 장애 시간은 약 30초. 짧은 것 같지만 실시간 주문 데이터가 흐르는 파이프라인에서 30초는 꽤 치명적이었습니다.
나중에 확인해보니 죽은 Broker에 파티션 리더가 몰려있었고, 팔로워들이 리더를 이어받는 과정에서 그 시간이 소요된 것이었습니다. 리더와 팔로워 개념, 그리고 ISR을 제대로 이해하고 있었다면 처음부터 리더가 특정 Broker에 몰리지 않도록 설계했을 겁니다.
① 리더와 팔로워가 정확히 어떤 역할을 하는지
② ISR이 뭔지, ISR에서 빠지면 무슨 일이 생기는지
③ acks=all이 왜 ISR과 연결되는지
④ Preferred Leader Rebalancing을 왜 주기적으로 해야 하는지
Leader와 Follower — 역할 분담의 핵심
Kafka에서 각 파티션은 Replication Factor 수만큼 여러 Broker에 복제됩니다. 이 중 단 1개만 Leader, 나머지는 모두 Follower입니다.
👑 LEADER
FOLLOWER
FOLLOWER
Kafka 2.4+: Rack-aware 설정으로 가까운 Follower에서 읽기 가능 (Consumer Fetch from Follower)
| 역할 | Leader | Follower |
|---|---|---|
| 쓰기(Producer) | 전담 처리 | 직접 받지 않음 |
| 읽기(Consumer) | 전담 처리 (기본) | Kafka 2.4+ 설정 시 가능 |
| 복제 | Follower에게 전달 | Leader에서 Pull |
| 장애 시 | Follower 중 1개가 승격 | Leader 승격 대기 |
| 개수 | 파티션당 1개 | Replication Factor - 1개 |
Follower는 Leader에게 데이터를 Push 받는 게 아니라 Pull 방식으로 가져갑니다.
Follower가 주기적으로 Leader에게 Fetch 요청을 보내 최신 데이터를 동기화하는 구조예요.
이 동기화가 얼마나 잘 따라가고 있는지를 나타내는 것이 바로 ISR입니다.
ISR(In-Sync Replica) — 가장 중요한 개념
ISR은 In-Sync Replica의 약자로, 리더와 거의 동일한 수준으로 복제가 동기화된 Replica들의 집합입니다. 리더는 항상 ISR에 포함되고, 팔로워는 동기화 상태에 따라 ISR에 들어가거나 나갑니다.
acks=all 설정 시 ISR 전체가 메시지를 받아야 Producer에게 ack를 보냅니다.
ISR이 1개(리더만)로 줄어든 상태에서 리더까지 죽으면 → ISR 밖의 팔로워가 리더로 승격 → 미복제 메시지 유실!
이것이 unclean.leader.election.enable 설정이 중요한 이유입니다.
# ISR 판단 기준 — 이 시간 내 동기화 못 하면 ISR 제외
replica.lag.time.max.ms=30000 # 기본 30초, 운영 환경 10초 권장
# 최소 ISR 수 — ISR이 이 수보다 적으면 Producer 쓰기 거부
min.insync.replicas=2 # Replication Factor 3일 때 2 권장
# Unclean Leader Election — ISR 밖의 팔로워를 리더로 허용할지
unclean.leader.election.enable=false # 운영 환경 반드시 false!
# true로 하면: 가용성 ↑, 데이터 유실 위험 ↑
# false로 하면: 데이터 무결성 ↑, 리더 없는 파티션 발생 가능
Replication Factor가 N이면 min.insync.replicas = N/2 + 1 설정을 권장합니다.
RF=3 → min.insync.replicas=2 : Broker 1대 장애 허용
RF=5 → min.insync.replicas=3 : Broker 2대 장애 허용
Leader Election — 리더는 어떻게 선출되나
리더 장애 감지 — Controller Broker가 감지
Kafka 클러스터에는 Controller라는 특별한 Broker가 존재합니다 (Kafka 3.0+ KRaft 모드에서는 별도 Controller 프로세스). Controller는 ZooKeeper(또는 KRaft)를 통해 각 Broker의 상태를 모니터링하고 리더 장애를 감지합니다.
ISR 중 새 리더 선출
Controller는 해당 파티션의 ISR 목록에서 첫 번째 Broker를 새 리더로 선출합니다. ISR 순서는 Preferred Leader(최초 리더)가 가장 앞에 옵니다. unclean.leader.election.enable=false이면 ISR이 비어있을 경우 파티션이 리더 없이 오프라인 상태가 됩니다.
새 리더 등록 및 Producer/Consumer 재연결
새 리더 정보가 Kafka 메타데이터에 업데이트되면, Producer와 Consumer는 자동으로 새 리더를 발견하고 재연결합니다. 이 과정이 실무에서 체감하는 "30초 장애"의 정체였습니다. session.timeout.ms와 connections.max.idle.ms 튜닝으로 단축 가능합니다.
Preferred Leader Rebalancing — 왜 주기적으로 해야 하나
Topic을 생성할 때 Kafka는 파티션 리더를 각 Broker에 균등하게 분산시킵니다. 이 최초 할당된 리더를 Preferred Leader라고 합니다. 문제는 운영 중 Broker 재시작이나 장애가 반복되면 리더가 점점 특정 Broker에 몰리기 시작한다는 것입니다.
auto.leader.rebalance.enable=true (기본값) 로 설정하면 Kafka가 주기적으로 Preferred Leader로 리밸런싱합니다.
수동으로 즉시 실행하려면: kafka-leader-election.sh --type preferred
현재 리더 분포 확인: kafka-topics.sh --describe --topic 토픽명
# 파티션 리더 분포 현황 확인
kafka-topics.sh \
--bootstrap-server kafka1:9092 \
--describe \
--topic order-events
# 출력 예시
# Topic: order-events Partition: 0 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3
# Topic: order-events Partition: 1 Leader: 1 Replicas: 2,3,1 Isr: 1,2,3 ← Preferred는 2인데 1이 리더!
# Preferred Leader로 즉시 리밸런싱
kafka-leader-election.sh \
--bootstrap-server kafka1:9092 \
--election-type PREFERRED \
--all-topic-partitions
acks 설정과 ISR의 관계 — 유실 vs 성능 트레이드오프
| acks 설정 | 동작 방식 | 성능 | 메시지 유실 위험 | 적합한 상황 |
|---|---|---|---|---|
acks=0 |
ack 없이 바로 다음 전송 | 최고 | 매우 높음 | 로그 수집, 유실 허용 데이터 |
acks=1 |
Leader만 받으면 ack | 보통 | 중간 | 일반 이벤트, 적당한 내구성 |
acks=all (-1) |
ISR 전체가 받아야 ack | 낮음 | 최소화 | 결제, 주문 등 중요 데이터 |
① Producer가 메시지 전송 → Leader가 수신
② Follower들이 Leader로부터 Pull → 복제
③ ISR 중 최소 2개(Leader 포함)가 복제 완료를 확인
④ Leader가 Producer에게 ack 전송
⑤ 이 시점부터 메시지는 안전하게 저장됨
결론: Broker 1대가 죽어도 나머지 2대 중 1대에 데이터가 있으므로 유실 없음!
실무 장애 시나리오와 대응법
시나리오 1 — ISR이 1개로 줄었는데 리더가 죽음
unclean.leader.election.enable=true 이면: ISR 밖 Follower가 리더 승격 → 미복제 메시지 유실!
unclean.leader.election.enable=false 이면: 파티션 리더 없음 → Producer/Consumer 완전 중단!
1) replica.lag.time.max.ms를 낮게 설정 → ISR 이탈 빠르게 감지하고 알림
2) min.insync.replicas=2 → ISR이 1개가 되는 순간 Producer 쓰기 거부로 조기 인지
3) Broker 리소스(CPU/Disk I/O) 여유 충분히 확보 → Follower 지연 방지
시나리오 2 — 리더 쏠림으로 특정 Broker 과부하
✅ 예방: auto.leader.rebalance.enable=true + leader.imbalance.check.interval.seconds=300 설정으로 5분마다 자동 리밸런싱
시나리오 3 — Follower가 계속 ISR에서 탈락
1) 해당 Broker 디스크 I/O 확인 (디스크 포화 → 복제 지연)
2) GC 로그 확인 (긴 GC Pause → 복제 스레드 멈춤)
3) 네트워크 bandwidth 확인 (대역폭 부족 → 복제 지연)
4) replica.lag.time.max.ms 값이 너무 낮게 설정된 건 아닌지 확인
운영 핵심 설정값 총정리
### Replication 관련
default.replication.factor=3 # Topic 기본 복제 계수
min.insync.replicas=2 # 최소 ISR 수 (acks=all 시 적용)
unclean.leader.election.enable=false # 데이터 무결성 우선
### ISR 판단
replica.lag.time.max.ms=10000 # 10초 내 동기화 안 하면 ISR 제외
replica.fetch.min.bytes=1
replica.fetch.wait.max.ms=500
### Leader 리밸런싱
auto.leader.rebalance.enable=true
leader.imbalance.check.interval.seconds=300 # 5분마다 리밸런싱 체크
leader.imbalance.per.broker.percentage=10 # 10% 이상 불균형 시 리밸런싱
### Controller (KRaft 모드)
process.roles=broker,controller # 소규모 클러스터: 겸용
# 대규모: broker / controller 역할 분리 권장
spring.kafka.producer:
acks: all # ISR 전체 확인
retries: 3 # 실패 시 재시도
properties:
enable.idempotence: true # 중복 방지
max.in.flight.requests.per.connection: 5
delivery.timeout.ms: 120000 # 2분 내 최종 전달 보장
request.timeout.ms: 30000 # 리더 응답 대기 30초
retry.backoff.ms: 1000 # 재시도 간격 1초
⚡ "리더가 죽어도 서비스가 살아있는 것이 Kafka의 가치입니다"
Leader/Follower/ISR 이 3가지만 제대로 이해하면
Kafka 운영의 90%는 해결됩니다.
장애 때 당황하지 않으려면 평소에 ISR 모니터링과 리더 분포 확인을 습관화하세요 💪
비슷한 장애 경험 있으시면 댓글로 공유해 주세요!
'Back-end' 카테고리의 다른 글
| Kafka 순서 보장 실무 완전 정복 — 파티션 키 설계부터 재시도 순서 역전 해결까지 (트러블슈팅 포함) (1) | 2026.02.26 |
|---|
