티스토리 뷰
728x90
한눈에 보는 요약
전통적으로 Apache Kafka는 ZooKeeper를 통해 메타데이터(브로커·토픽·파티션 정보) 저장, 컨트롤러 선출, 동적 설정 변경을 처리했습니다. 그러나 ZooKeeper가 가진 운영 복잡성·확장 한계를 해결하고자 2019년 제안된 KIP-500이 ‘Kafka Raft’(KRaft) 모드를 도입해 ZooKeeper 의존을 제거했습니다. KRaft는 Raft 합의 알고리즘으로 브로커 내부에 메타데이터 전용 컨트롤러 쿼럼을 구성해 단일 스택 배포·빠른 리더 선출·메타데이터 처리량 향상을 제공합니다. Kafka 3.5+에서는 신규 클러스터의 기본 옵션으로 자리 잡았고, Amazon MSK·Confluent Platform 등 주요 배포판이 KRaft를 공식 지원합니다. 아래에서는 ① ZooKeeper의 기존 역할 ② KRaft 등장 배경 ③ 아키텍처·장점 ④ 설정 및 마이그레이션 절차를 심층적으로 살펴봅니다.
1. ZooKeeper가 카프카에서 맡았던 역할
1-1. 메타데이터 저장소
- 토픽·파티션 매핑, ACL, 동적 설정이 ZooKeeper znode 트리에 저장돼 브로커가 부팅 시 로드합니다.
1-2. 컨트롤러 선출
- 다수 브로커 중 Kafka Controller 1대를 ZooKeeper EPHEMERAL ZNode를 이용해 선출·감시합니다. 장애 발생 시 재선출엔 수 초가 걸렸습니다.
1-3. 클러스터 코디네이션
- 브로커 가용성 체크, ISR(In-Sync Replica) 정보 관리, 토픽 생성·삭제 이벤트 전파 등을 담당했습니다. 이처럼 데이터 경로(브로커)와 제어 경로(ZooKeeper) 가 분리돼 운영 복잡도가 컸습니다.
2. KRaft 모드 등장 배경
2-1. 확장성과 지연 한계
- 수 만 파티션 규모에서 ZooKeeper znode 갯수·워치 이벤트가 폭증해 메타데이터 처리 병목이 나타났습니다.
2-2. 운영 복잡성
- Kafka + ZooKeeper 두 스택을 따로 배포·모니터링·백업해야 하는 부담이 지속적으로 보고됐습니다.
2-3. KIP-500 비전
- “브로커 내부 로그로 메타데이터를 관리하자”는 KIP-500이 2019년 제안되며 Raft 합의를 변형한 KRaft 프로토콜이 설계되었습니다.
3. KRaft 아키텍처와 동작 방식
3-1. 컨트롤러 쿼럼
- 최소 3노드(홀수)로 구성된 전용 컨트롤러가 Raft Leader 선출·메타데이터 커밋을 담당합니다.
- 브로커는 process.roles=broker(데이터 전용) 또는 broker,controller(개발용)로 역할을 분리 설정합니다.
3-2. Raft 로그
- 메타데이터 변경 사항이 전용 __cluster_metadata 로그로 기록·복제돼 ZooKeeper znode 대신 사용됩니다.
3-3. 빠른 failover
- 컨트롤러 장애 시 다수결 Raft Vote 로 수 백 ms 내 새 리더가 선출돼 파티션 리더 선출 지연이 대폭 줄어듭니다.
4. ZooKeeper 대비 KRaft의 장점
영역 ZooKeeper 기반 KRaft 기반
| 배포 복잡도 | 두 스택 관리 | 단일 스택 배포·업그레이드 |
| 메타데이터 처리량 | znode 워치 병목 | Raft 로그 스트림, 파티션 수 한계↑ |
| 리더 선출 시간 | 수 초 | 수 백 ms 이내 (strimzi.io) |
| 노드 수 | 브로커 N + ZooKeeper 3 | 브로커 N + 컨트롤러 3(공유 가능) → 인프라↓ |
| 동적 설정 | ZooKeeper 트리에 작성 | 컨트롤러 API로 로그 커밋 |
5. KRaft 설정 방법
5-1. 단일 노드(테스트)
# server.properties
process.roles=broker,controller
node.id=1
controller.quorum.voters=1@localhost:9093
listeners=PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
- controller.listener.names=CONTROLLER 추가 후 부팅하면 ZooKeeper 없이 곧바로 작동합니다.
5-2. 프로덕션 3-컨트롤러 + N-브로커
- 컨트롤러 전용 노드 3대에 process.roles=controller 설정, 각 node.id 1-3 할당.
- 브로커 노드는 process.roles=broker, controller.quorum.voters=1@ctrl1:9093,2@ctrl2:9093,3@ctrl3:9093 지정.
- 클라이언트는 평소와 동일하게 bootstrap.servers 로 브로커 포트(9092)를 사용합니다.
5-3. ZooKeeper → KRaft 마이그레이션(KIP-866)
- Kafka 3.6+의 KRaft Migrator 도구로 “더블 라이트”(두 메타데이터 로그 동시 기록) 단계를 거쳐 무중단 전환이 가능합니다.
- 완료 후 ZooKeeper를 제거하고 kraft 모드로 재시작합니다.
6. 운영 시 고려 사항
- 하드웨어 – 컨트롤러 노드는 디스크 신뢰성·네트워크 레이턴시가 중요하며, Confluent는 브로커와 동일 스펙 또는 더 빠른 CPU/SSD를 권장합니다.
- 모니터링 – kraftController:* JMX 지표(LeaderElectionRate, MetadataLogEndOffset 등)를 별도로 수집해야 합니다.
- 버전 호환성 – 3.5~3.6은 기능 일부가 Preview이며, 3.7부터 MSK·Confluent에서 GA(Generally Available) 로 지원됩니다.
728x90
'개발 인프라 > 카프카' 카테고리의 다른 글
| 카프카 프로듀서, 메시지 전송 보장 레벨(acks) (1) | 2025.05.23 |
|---|---|
| 카프카 메시지 직렬화, 무엇을 선택해야 할까 (0) | 2025.05.23 |
| 카프카 토픽과 파티션, 왜 중요할까? (1) | 2025.05.21 |
| 카프카 컨슈머(Consumer)와 컨슈머 그룹 파헤치기 (1) | 2025.05.16 |
| 카프카 프로듀서(Producer) 란? (2) | 2025.05.16 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 자바
- 언리얼엔진
- springai
- 코프링
- Heap Area
- 언리얼엔진5
- 일급 객체
- unreal engjin
- generated_body()
- RESTfull
- ai통합
- First-class citizen
- Subagent
- 카프카 개념
- cqrs
- method Area
- 스브링부트
- MCP
- AI 에이전트
- model context protocol
- 타입 안전성
- Java
- 코틀린
- redis
- JAVA 프로그래밍
- Claude Agent SDK
- 디자인패턴
- JVM
- vite
- Stack Area
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 | 29 | 30 | 31 |
글 보관함
