12. Apache Kafka KRaft 모드 장애복구 및 증설 테스트 (Controller 3, Broker 3)
Apache Kafka 3.9.0을 KRaft 모드로 구성한 후, 컨트롤러와 브로커 장애 복구 동작을 테스트하는 과정을 정리했습니다.
3개의 가상 머신을 활용한 실습 환경에서 리더 교체와 동기화 복구 과정을 확인할 수 있습니다
Apache Kafka KRaft 모드 장애복구 및 증설 테스트 (Controller 3, Broker 3)
목차
1. 테스트 환경 구성 및 설정
Apache Kafka를 테스트 하기 위해서 VirtualBox로 가상머신 3개를 생성하고 kafka 를 설치합니다.
이번 테스트에서는 Controller 3개 + Broker 3개 구성으로 고가용성(HA) 환경을 구축하고, 노드 장애 및 복구 상황에서의 동작을 확인합니다.
| VM | 역할 | IP주소 |
| host_56_101 | Controller, Broker | 192.168.56.101 |
| host_56_102 | Controller, Broker | 192.168.56.102 |
| host_56_103 | Controller, Broker | 192.168.56.103 |
각 노드는 KRaft 모드에서 controller와 broker 역할을 동시에 수행합니다.
핵심 server.properties 설정 예시 (node 1)
process.roles=broker,controller
node.id=1
#node.id=2
#node.id=3
controller.quorum.voters=1@192.168.56.101:9093,2@192.168.56.102:9093,3@192.168.56.103:9093
listeners=PLAINTEXT://:9092,CONTROLLER://:9093
advertised.listeners=PLAINTEXT://192.168.56.101:9092,CONTROLLER://192.168.56.101:9093
#advertised.listeners=PLAINTEXT://192.168.56.102:9092,CONTROLLER://192.168.56.102:9093
#advertised.listeners=PLAINTEXT://192.168.56.103:9092,CONTROLLER://192.168.56.103:9093
controller.listener.names=CONTROLLER
log.dirs=/home/kafka/kafka_2.13-3.9.0/data
offsets.topic.replication.factor=3
transaction.state.log.replication.factor=3
transaction.state.log.min.isr=2
2. Kafka 클러스터 실행 및 상태 확인
◆ 스토리지 초기화 및 서버 실행
1. 스토리지 초기화
#/home/kafka/kafka_2.13-3.9.0/data 에 이전 데이터가 있는 경우 삭제 필요
/home/kafka/kafka_2.13-3.9.0/bin/kafka-storage.sh format \
-t $KAFKA_CLUSTER_ID \
-c /home/kafka/kafka_2.13-3.9.0/config/kraft/server.properties
2. 서버 실행
/home/kafka/kafka_2.13-3.9.0/bin/kafka-server-start.sh \
-daemon \
/home/kafka/kafka_2.13-3.9.0/config/kraft/server.properties
3. process 확인
$ps aux | grep kafka
◆ 메타데이터 쿼럼 상태 확인
메타데이터 쿼럼 → Kafka의 중요한 정보를 안전하게 관리하는 컨트롤러 그룹
kafka-metadata-quorum.sh \
--bootstrap-controller 192.168.56.102:9093 describe \
--replication

| 항목 | 설명 |
| NodeId | 컨트롤러 노드의 ID (2, 1, 3) |
| DirectoryId | 컨트롤러 로그가 저장된 디렉터리 식별자 (UUID 또는 디렉터리 ID) |
| LogEndOffset | 해당 컨트롤러가 저장한 메타데이터 로그의 최종 오프셋 (마지막으로 기록된 위치) |
| Lag | 리더 컨트롤러와의 데이터 지연 정도 (0이면 정상적으로 동기화됨) |
| LastFetchTimestamp | 해당 컨트롤러가 마지막으로 메타데이터를 가져온 타임스탬프 (밀리초) |
| LastCaughtUpTimestamp | 해당 컨트롤러가 마지막으로 동기화된 타임스탬프 (밀리초) |
| Status | 현재 컨트롤러의 상태 (Leader 또는 Follower) |
- Leader Controller는 NodeId 2이며, Follower Controller는 NodeID 1,3 입니다.
- Status = Leader → 현재 이 컨트롤러가 클러스터의 메타데이터를 관리하는 역할을 수행 중입니다.
- Status = Follower → 리더가 장애가 발생하면 새로운 리더 컨트롤러로 승격될 가능성이 있습니다.
- 모든 컨트롤러(NodeId 1, NodeId 3)가 리더(NodeId 2)와 완전히 동기화(Lag=0) 되어 있습니다.
- 리더 컨트롤러(NodeId 2)가 장애가 발생하면, NodeId 1 또는 NodeId 3이 새로운 리더로 선출될 가능성이 높습니다.
◆ 컨트롤러 리더 및 클러스터 상태 조회
- 명령어는 클러스터 전체의 컨트롤러 리더 선출 상태와, 장애 발생 시 얼마나 많은 팔로워가 지연되고 있는지를 확인하는 용도로 사용됩니다.
kafka-metadata-quorum.sh \
--bootstrap-controller 192.168.56.102:9093 \
describe --status
| 항목 | 설명 |
| ClusterId | 현재 Kafka 클러스터의 고유 식별자 |
| LeaderId | 현재 리더 컨트롤러 노드 ID |
| LeaderEpoch | 현재 리더 컨트롤러가 선출된 횟수 |
| HighWatermark | 커밋된 메타데이터의 오프셋 |
| MaxFollowerLag | 팔로워 컨트롤러 중 가장 높은 지연(Lag) 값 |
| Voters | 컨트롤러 투표권을 가진 노드 목록 |
| Observers | 투표권 없이 상태만 모니터링하는 노드 목록 |

- 현재 리더 컨트롤러는 NodeId 2 , 192.168.56.102:9093 가 현재 클러스터의 리더 컨트롤러입니다.
- LeaderEpoch = 57, 리더 컨트롤러가 57번 선출되었으며, 이 값이 자주 증가하면 컨트롤러 장애나 네트워크 문제가 발생했을 가능성이 있습니다
- MaxFollowerLag = 0, 모든 팔로워 컨트롤러가 리더 컨트롤러와 완전히 동기화됨을 의미합니다. 만약 0이 아니라면, 팔로워 컨트롤러가 리더와 데이터 동기화가 지연되고 있는 상태입니다.
3. 테스트용 토픽 생성 및 메시지 송수신
◆ 토픽 생성
- Kafka에서는 데이터를 주제(Topic)별로 관리하며, 하나의 토픽은 여러 개의 파티션(Partition)으로 나뉘어 데이터를 저장할 수 있습니다.
- 토픽 생성 명령어는 Kafka 클러스터 내의 어떤 브로커에서 실행해도 문제없이 적용됩니다.
- partitions=3: 3개의 파티션으로 데이터 분산 저장
- replication-factor=2: 최소 2개 브로커에 복제하여 하나가 다운되더라도 데이터 손실 방지
1. 토픽 생성
kafka-topics.sh \
--create --topic test-topic \
--bootstrap-server 192.168.56.102:9092 \
--partitions 3 --replication-factor 3
2. 토픽 목록 조회
kafka-topics.sh \
--list \
--bootstrap-server 192.168.56.102:9092
3. 토픽 상세 정보
kafka-topics.sh \
--describe \
--topic test-topic \
--bootstrap-server 192.168.56.102:9092
4. 토픽 제거(참고)
kafka-topics.sh \
--delete \
--topic test-topic \
--bootstrap-server 192.168.56.102:9092
- test-topic 토픽은 3개의 파티션(PartitionCount: 3)으로 구성되었으며,
- 각 파티션은 3개의 복제본 (Replication Factor: 3) 을 가집니다.

- 토픽 설명 참고

◆ 메시지 송수신
1. Producer 생성
kafka-console-producer.sh \
--topic test-topic\
--bootstrap-server 192.168.56.102:9092,192.168.56.103:9092
2. Consumer 생성
kafka-console-consumer.sh \
--topic test-topic \
--from-beginning \
--bootstrap-server 192.168.56.102:9092,192.168.56.103:9092

4. 노드 장애시 클러스터 동작 확인
◆ 노드 종료 (host_56_101)
kafka-server-stop.sh

◆ 상태 확인
- 노드 1을 종료 후 현재 Kafka 클러스터의 메타데이터 컨트롤러 상태 와 토픽의 정보 등을 확인할 수 있습니다.
- NodeId = 2 가 리더(Leader)로 선출되었으며 , Node 1 (Follower) 은 비정상 상태( LogEndOffset = -1)임을 확인할 수 있습니다.
- Broker 1(Replicas: 3,1,2 중 1번)이 ISR 목록에 없음 → 즉, Broker 1이 리더와 동기화되지 못하고 있습니다.

5. 노드 복구 및 ISR 정상화 확인
Kafka는 장애가 발생한 노드가 다시 실행되면, ISR (In-Sync Replicas) 목록에 복구된 브로커를 다시 추가하게 됩니다.
비정상 상태( LogEndOffset = -1, Lag=6193)이었던 Node 1 (Follower) 도 정상 상태임을 확인할 수 있씁니다.
복구된 브로커는 기존 데이터를 다시 동기화하고 클러스터의 일부로 정상 동작하게 됩니다.

6. 무정지 노드 추가 테스트
3대의 Kafka 클러스터를 구성한 후 운영상태에서 Broker 노드를 추가로 연결해 보겠습니다.
브로커 추가 대상 노드는 host_56_104입니다.
| host_56_104 | Controller, Broker | 192.168.56.104 |
process.roles=broker
node.id=4
controller.quorum.voters=1@192.168.56.101:9093,2@192.168.56.102:9093,3@192.168.56.103:9093
listeners=PLAINTEXT://:9092
inter.broker.listener.name=PLAINTEXT
advertised.listeners=PLAINTEXT://192.168.56.104:9092
controller.listener.names=CONTROLLER
listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
log.dirs=/home/kafka/kafka_2.13-3.9.0/data
num.partitions=3
offsets.topic.replication.factor=3
transaction.state.log.replication.factor=3
transaction.state.log.min.isr=2
log.retention.hours=168
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000
offsets.topic.replication.factor나 transaction.state.log.replication.factor 값은 브로커 수 이상으로 설정할 수 없습니다.
최소 브로커 수 이상이 유지되어야 오류 없이 동작합니다.
1. 스토리지 초기화
#/home/kafka/kafka_2.13-3.9.0/data 에 이전 데이터가 있는 경우 삭제 필요
kafka-storage.sh format \
-t $KAFKA_CLUSTER_ID \
-c /home/kafka/kafka_2.13-3.9.0/config/kraft/server.properties
2. 서버 실행
kafka-server-start.sh \
-daemon \
/home/kafka/kafka_2.13-3.9.0/config/kraft/server.properties
3. process 확인
$ps aux | grep kafka
추가된 브로커가 클러스터에 정상 합류했는지 확인하려면 다음 명령을 실행합니다:
kafka-metadata-quorum.sh \
--bootstrap-controller 192.168.56.102:9093 \
describe --replication
NodeId 4 가 Observer상태로 추가 된 것을 확인 할 수 있습니다.

Kafka 3.9.0의 KRaft 모드 클러스터 구성에서 장애복구 과정을 실습해 보았습니다.
Controller 3개, Broker 3개의 안정적인 구조를 통해 리더 교체와 데이터 동기화가 자동으로 처리됨을 확인했습니다.
관련 글 링크
[VirtualBox]5.호스트 전용 네트워크에서 인터넷 연결 방법 (NAT설정)
11. Kafka 3.9 노드 구성별 server.properties 예시: KRaft 모드
4. Kafka 클러스터 다중 파티션 구성 이해: 고가용성과 장애복구
5. Kafka 리더 장애 발생 시 Failover를 위한 Producer와 Consumer 설정