KRaft 동적 쿼럼 재구성(KIP-853) — 클러스터를 멈추지 않고 컨트롤러를 넣고 빼기
Kafka Streams suppress() 및 KRaft 동적 쿼럼 재구성 공식 문서 종합 (웹 리서치, 2026) — Apache Kafka Javadoc(Suppressed) + Confluent 개발자 튜토리얼 + KIP-853 KIP-853: KRaft Controller Membership Changes
이 모듈을 다 읽으면
- KIP-853 이전에는 컨트롤러 쿼럼 멤버 변경이 왜 어려웠는지 설명할 수 있다
- 동시에 한 번에 하나의 변경만 허용하는 안전장치의 이유를 설명할 수 있다
kafka-learn-30에서 다룬 ZooKeeper 제거와 KRaft 컨트롤러 쿼럼을 전제로, Kafka 3.9(KIP-853)부터 가능해진, 클러스터를 재시작하지 않고도 컨트롤러 쿼럼 멤버를 추가·제거할 수 있는 동적 재구성 기능을 정리한다.
add-controller/remove-controller — 살아있는 클러스터에 컨트롤러 넣고 빼기
KIP-853은 KRaft 컨트롤러 쿼럼 멤버십을 동적으로 만든다 — kafka-metadata-quorum.sh 도구(또는 대응하는 AdminClient API)로 이미 따라잡은(caught-up) 상태의 컨트롤러를 add-controller로 추가하거나, remove-controller로 기존 컨트롤러를 제거할 수 있다. 쿼럼을 확장하려면 먼저 kafka-storage.sh로 새 컨트롤러를 프로비저닝해 기동한 뒤, kafka-metadata-quorum.sh describe --replication으로 새 컨트롤러가 복제를 잘 따라잡고 있는지 모니터링하는 절차를 거친다.
핵심 포인트
- kafka-metadata-quorum.sh add-controller/remove-controller(또는 AdminClient API)로 살아있는 클러스터의 컨트롤러 쿼럼 멤버를 동적으로 추가/제거 가능
- 확장 시 절차: kafka-storage.sh로 새 컨트롤러 프로비저닝·기동 → describe --replication으로 복제 추격 상태 모니터링 → add-controller
안전장치 — 한 번에 한 건씩만 변경 허용
활성 컨트롤러(active controller)는 AddRaftVoter/RemoveRaftVoter/UpdateRaftVoter 같은 런타임 투표자 변경 요청을 처리할 때, 한 번에 딱 하나의 컨트롤러 추가 또는 제거만 허용하도록 강제한다 — 여러 개의 쿼럼 변경이 동시에 진행 중이면 비동기적인 메타데이터 로그 복제 과정에서 서로 다른(분리된) 다수결 집합이 생겨날 위험이 있고, 이는 스플릿 브레인으로 이어질 수 있기 때문이다. 즉 이 '한 번에 하나씩'이라는 제약은 성능 최적화가 아니라 쿼럼 안전성을 지키기 위한 근본적인 설계 결정이다.
핵심 포인트
- 활성 컨트롤러는 컨트롤러 추가/제거를 한 번에 하나씩만 처리하도록 강제
- 이유: 여러 변경이 동시에 진행되면 비동기 메타데이터 로그 복제 중 서로 다른 다수결 집합이 생겨 스플릿 브레인 위험 — 성능이 아닌 안전성을 위한 설계
3.9 시점의 제약 — 정적 쿼럼을 동적으로 전환하는 건 아직 불가
Kafka 3.9 기준 KIP-853의 한계는, 기존에 정적(static)으로 구성된 메타데이터 쿼럼을 동적 쿼럼으로 전환하는 기능은 아직 지원되지 않는다는 점이다(추후 지원 예정으로 명시됨) — 즉 이 동적 재구성 기능을 쓰려면 처음부터 동적 쿼럼으로 클러스터를 구성해야 한다는 실무적 제약이 있다. 또한 KIP-996(pre-vote)이 아직 구현되지 않은 시점에는, 제거할 컨트롤러를 remove-controller 실행 전에 먼저 종료해두는 것이 권장된다.
핵심 포인트
- 3.9 시점 한계: 기존 정적 쿼럼을 동적 쿼럼으로 전환하는 기능은 아직 미지원(추후 지원 예정) — 처음부터 동적 쿼럼으로 구성해야 함
- KIP-996(pre-vote) 구현 전까지는 remove-controller 실행 전 제거 대상 컨트롤러를 먼저 종료하는 것이 권장됨