📌 Raft 알고리즘 이해하기 – Kafka KRaft를 중심으로
Kafka 4.x부터 ZooKeeper가 사라지고 KRaft(Kafka + Raft) 모드가 기본이 되었습니다.
Raft는 분산 시스템에서 합의(consensus)를 이루기 위한 대표적인 알고리즘인데, 리더 선출과 로그 복제를 안정적으로 관리합니다.
이번 글에서는 Raft와 관련해 자주 헷갈리는 개념들을 질문/답변 형식으로 정리했습니다.
❓ 브로커가 3개일 때, 리더가 죽으면 투표가 불가능한 것 아닌가?
아닙니다.
- 3개 브로커일 때 과반수(Quorum)는 2.
- 리더 1대가 죽더라도 2대가 남으면 서로 투표해서 새로운 리더를 뽑을 수 있습니다.
- 다만 2대가 모두 죽고 1대만 남으면 Quorum(2)을 만족하지 못하므로 선거가 불가능합니다.
✅ 정리: 3개 중 1대 장애까지는 정상 동작, 2대 장애 시는 클러스터가 멈춥니다.
❓ 2대가 동시에 자기 자신에게 투표하면 어떻게 되나?
- Raft에서 Candidate는 항상 자기 자신에게 1표를 줍니다.
- 만약 2대가 동시에 Candidate가 되면 → 각자 자기 자신에게만 투표 → 표가 갈려서 과반수 확보 실패.
- 이런 상황을 split vote(투표 분열)이라고 부릅니다.
❓ Split Vote는 어떻게 해결되나?
Raft가 split vote를 푸는 표준 메커니즘
- 랜덤화된 선거 타임아웃 (Randomized Election Timeout)
- 각 노드는 서로 다른 범위의 timeout+jitter를 가짐.
- 첫 라운드에서 동시 타임아웃이 나와도, 다음 라운드에선 거의 항상 한 노드가 먼저 timeout → 먼저 Candidate → 먼저 득표 요청 → 다른 노드가 아직 표를 안 썼다면 그쪽 표까지 받아 과반 확보.
- => 확률적으로 반복될수록 동시성은 깨지고 결국 한 쪽이 승리.
- 한 Term당 1표 규칙 + Term 증가로 재시도
- 각 노드는 Term당 오직 1표만 줌.
- 과반 실패(=split vote) 상태로 또 timeout이 나면 Term을 올리고 다시 선거.
- 새 Term가 시작될 때 투표권이 리셋되므로 재시도의 진행 보장.
- 로그 최신성 규칙 (Up-to-date Log Rule)
- 유권자(다른 노드)는 자기보다 로그가 덜 최신인 후보에게 표를 거부.
- 자연스럽게 가장 최신 로그를 가진 후보에게 표가 쏠려 표 분산을 줄임.
- 리더가 되면 가장 진보된 상태가 리더가 되도록 설계.
- 하트비트(Heartbeat)가 타이머 리셋
- 어떤 후보가 과반을 모아 리더가 되면 즉시 하트비트를 보냄.
- 받는 노드들은 선거 타이머가 리셋되어 추가 분열 없이 질서 회복.
- Pre-Vote 확장(실무에서 매우 유용)
- 정식 선거(=Term 증가) 전에 “나 뽑아줄 거 있어?” 하고 **사전 확인(PreVote)**을 함.
- 과반이 사전 동의하지 않으면 Term을 올리지도 않고 조용히 대기 → 불필요한 충돌/용수철 현상 감소.
- 네트워크 분할(분리된 소수파)이 클러스터를 흔드는 것을 크게 줄임.
- CheckQuorum/Leader Stickiness(확장 옵션)
- 리더가 과반의 응답을 일정 시간 못 받으면 스스로 리더를 포기(step down)해, 잘못된 리더 지속을 방지.
- 반대로 정상 시엔 리더의 하트비트가 계속 타임아웃을 리셋해 불필요한 재선거를 억제.
- 영속화된 votedFor/term
- 각 노드는 term과 votedFor를 디스크에 기록.
- 재시작/장애 후에도 투표 일관성이 유지되어 선거 뒤틀림을 막음.
작은 타임라인 예시 (3노드 B, C가 남음)
- A(리더) 장애 → B, C는 follower.
- (라운드1) B와 C가 거의 동시에 timeout → 둘 다 Candidate → 각자 1표 확보 → 서로는 이미 표를 사용해서 과반 실패.
- (라운드2) 시간 흐름 + 랜덤 타임아웃으로 B가 먼저 timeout → Candidate 전환 → C에게 득표 요청 → C는 아직 이번 Term에 표를 안 줬으므로 B에게 표를 줌 → B 과반(2/3) 달성 → 리더 당선 → 하트비트 발송 → C 타이머 리셋 → 안정화.
✅ 정리: split vote는 일시적으로 생기지만, 랜덤 타임아웃 + Term 재시작 + 최신성 규칙 덕분에 결국 한쪽이 과반을 확보해 리더가 뽑히게 됩니다.
❓ 짝수 노드 구성이 더 안전하지 않나?
직관적으로는 맞아 보이지만, 실제로는 홀수 노드 구성이 더 효율적입니다.
| 노드 수 | Quorum허용 | 가능한 장애 수 |
| 3 | 2 | 1 |
| 4 | 3 | 1 |
| 5 | 3 | 2 |
- 3대와 4대는 허용 장애 수가 동일(1대)입니다.
- 즉, 4대를 운영해도 안정성은 늘지 않고 리소스만 낭비됩니다.
- 반면 5대로 늘리면 2대 장애까지 견딜 수 있어 안정성이 확실히 강화됩니다.
✅ 정리: 그래서 Kafka, ZooKeeper, Etcd 같은 분산 합의 시스템은 항상 홀수 개(3, 5, 7 …) 노드를 권장합니다.
❓ 후보자(Candidate) 선출은 리더가 죽었을 때만 일어나나?
아닙니다. 리더가 죽지 않아도 선거가 벌어질 수 있습니다.
- 리더의 하트비트(Heartbeat)를 Election Timeout 동안 받지 못한 경우
- 네트워크 지연, 패킷 손실, follower가 느려서 타이머가 만료된 경우
- 운영자가 리더 브로커를 강제로 재시작했을 때
✅ 정리: 후보자 선출은 “리더 장애”뿐 아니라 하트비트를 일정 시간 못 받는 상황 전체에서 일어납니다.
그래서 Election Timeout > Heartbeat Interval × 몇 배 이상으로 설정하는 것이 안정성을 높이는 핵심입니다.
📌 결론
Raft는 단순히 “리더가 죽으면 새 리더를 뽑는 알고리즘”이 아니라,
- Quorum 기반의 합의
- split vote를 피하기 위한 랜덤화된 선거
- 홀수 노드 구성을 통한 효율적인 장애 허용
- 하트비트로 안정성 확보
등의 메커니즘을 통해 분산 시스템을 안정적으로 운영할 수 있게 합니다.
Kafka 4.x의 KRaft 모드도 이 원리를 그대로 활용하므로, 운영자는 노드 개수, 타임아웃 설정, 네트워크 안정성 등을 잘 고려해야 합니다.
'Kafka' 카테고리의 다른 글
| Kafka Consumer Group (0) | 2025.09.29 |
|---|---|
| Event Driven Architecture란? (0) | 2022.06.30 |
댓글