코드 저장소.

카프카의 복구 과정을 측정 - ISR 테스트 본문

포폴/일정관리 프로젝트 vol.02

카프카의 복구 과정을 측정 - ISR 테스트

slown 2026. 5. 2. 10:51

 

1.테스트 개요

2.환경 구성 및 통제 변수

3. 장애 시나리오 설계

4. 지표 측정 및 결과

5.결론 및 고

6.소감

 

1. 테스트 개요

 

1-1. 본 테스트의 목적 및 배경

 

분산 메시징 시스템인 Apache Kafka 운영 시, 특정 브로커의 하드웨어 결함이나 네트워크 장애는 불가피하게 발생한다. 본 테스트는 이러한 장애 상황에서도 시스템이 사전에 정의된 신뢰성 설정을 바탕으로 데이터 유실 없이(Zero Data Loss) 서비스를 지속할 수 있는지 검증하는 데 목적이 있다.

 

1-2. 가용성 및 신뢰성 관점에서의 테스트 범위 정의

  • 가용성(Availability): 브로커 장애 감지 후 새로운 리더 파티션이 선출되어 클라이언트 요청을 다시 처리하기까지의 가동 중단 시간(Downtime)을 측정한다.
  • 신뢰성(Reliability): 복제본 간의 동기화 상태(ISR)를 관리하고, 장애 발생 시에도 프로듀서가 보낸 메시지가 중복이나 누락 없이 저장되는지 확인한다.

 

2.환경 구성 및 통제 변수

 

2-1. 인프라 아키텍처

 

 

테스트의 신뢰성을 위해 기존의 인프라 서버에서 실제 운영 환경에 준하는 고가용성 클러스터를 구성하였다.

  • Cluster Mode: Kafka KRaft Mode
  • Nodes: 3개의 브로커 노드가 Controller와 Broker 역할을 겸임하도록 구성
    • controller.quorum.voters: [1@kafka-1:9093, 2@kafka-2:9093, 3@kafka-3:9093]
  • Topic Metadata:
    • num.partitions: 3
    • offsets.topic.replication.factor: 3

테스트 시작 전 토픽의 정상 상태 (Partition: 3, Replica: 3, ISR: [1,2,3])

 

2-2. 핵심 파라미터 설정 

 

이미지 내 실제 설정값을 기반으로 한 데이터 보존 및 복구 정책은 다음과 같다.

분류 파라미터 설정값 엔지니어링 의도

용성
min.insync.replicas 2 최소 2대 이상의 ISR이 유지되어야 쓰기가 가능하도록 설정하여 데이터 안정성 확보
신뢰성 offsets.commit.required.acks -1 (all) 모든 복제본에 메시지가 복제되었음을 확인한 후 승인 (Zero Data Loss)
복구 controller.uorum.election.timeout.ms 1000 리더 장애 시 1초 내외의 빠른 선출을 유도하여 가동 중단 시간 최소화
복구 controlled.shutdown.enable true 의도된 종료 시 리더 권한을 안전하게 이관하여 복구 속도 향상

 

2-3. 관찰 및 모니터링 도구

 

실시간 지표 변화를 정밀하게 추적하기 위해 타임스탬프(date +"%H:%M:%S.%3N") 출력을 포함한 모니터링 스크립트를 백그라운드에서 구동하여 초/밀리초 단위의 가용성을 관찰합니다.

 

 

3. 장애 시나리오 설계 (Test Scenarios)

클라이언트가 카프카 클러스터에 지속적으로 메시지를 발행/소비하는 '런타임 상태'에서 아래 장애들을 유발하여 클러스터의 거동을 비교합니다.

  • 시나리오 A: SIGKILL을 이용한 비정상 강제 종료 (kill -9 프로세스 크래시)
  • 시나리오 B: iptables를 이용한 네트워크 고립 (좀비 브로커 상태 유발)
  • 시나리오 C: Graceful Shutdown을 통한 정상 종료 (docker stop 제어된 종료)

 

4. 지표 측정 및 결과 (Measurement & Results)

4-1. 시나리오 A (비정상 강제 종료) 결과 분석

 

런타임 상태에서 docker kill kafka-3 명령을 통해 강제 종료(SIGKILL)를 수행했습니다.

 

 

TRIGGER_KILL 발생 시점과 클라이언트가 장애를 감지하고 새로운 리더로 선출되는 타임라인 분석

  • 장애 감지 및 리더 선출: 타임스탬프 측정 결과, Broker 3번이 죽은 직후 클라이언트 측 로그에 커넥션 단절 에러가 감지되었습니다. 클러스터는 즉시 3번 브로커를 ISR에서 제외하여 Isr: 1,2 상태로 축소시켰고, 파티션 리더를 Leader: 1로 빠르게 재선출했습니다. 이 과정에서 min.insync.replicas=2 조건을 충족하고 있었기 때문에 프로듀서의 데이터 전송은 누락 없이 계속 유지되었습니다.
  • 복구 프로세스(Recovery): 다운되었던 브로커를 재기동(docker start)하자, 로그상에서 리커버리 스레드가 구동되며 정합성 검증이 실행되었습니다. 리더와의 오프셋 동기화가 완료된 후 다시 안정적으로 ISR에 편입되었습니다. 
  • 리더를 선출을 하고 복구를 하기까지의 로그를 보면 02:40:20 감지 → 02:40:28 리더 선출 완료, 약 8초 소요가 되는 것을 알 수 있습니다.

 

4-2. 시나리오 B (네트워크 고립 - 좀비 브로커) 결과 분석

iptables를 통해 특정 브로커의 9092 포트 통신을 차단하여 프로세스는 살아있으나 네트워크 응답만 불능인 상태를 검증했습니다.

 

 

  • 결과: 클러스터는 즉시 장애를 인지하지 못하고 하트비트 세션 타임아웃 지연 시간 동안 대기 현상(Stall)이 발생했습니다. 이후 타임아웃 임계치를 넘긴 시점에 해당 브로커를 ISR에서 격리하고 나서야 정상적인 메시징 플로우가 복구되었습니다. 비정상 프로세스 종료보다 네트워크 고립 상태가 시스템 가용성에 더 일시적인 지연 리스크를 줄 수 있음을 확인했습니다.

4-3. 시나리오 C (Graceful Shutdown) 결과 분석

docker stop kafka-3 명령어를 통해 제어된 종료 메커니즘을 수행했습니다.

 

 

Graceful Shutdown (TRIGGER_STOP) 시 클라이언트 측 에러 없이 유연하게 리더 이관이 처리되는 과정

  • 리더 사전 이관: 로그 플로우 상에서 TRIGGER_STOP 신호가 인입되자, 브로커 내부적으로 Controlled shutdown active 절차가 수행되었습니다. 자신이 가지고 있던 리더 권한을 프로세스가 완전히 죽기 전에 다른 복제본 브로커들에게 안전하게 이관(Leader 이관 완료)했습니다.
  • 가용성 확인: 타임스탬프를 확인해 보면 클라이언트 측에 단 한 줄의 타임아웃이나 NotLeaderForPartitionException 에러도 발생하지 않고 완벽하게 무중단(Zero Downtime)으로 메시지가 연속 처리되는 것을 실실적으로 증명했습니다.

5. 결론 및 고찰

5-1. 테스트 결과에 기반한 시스템 가용성 평가

 

본 테스트를 통해 엔지니어링 의도로 설정했던 acks=all, min.insync.replicas=2, controlled.shutdown.enable=true 파라미터들이 런타임 장애 상황에서 어떻게 가용성과 신뢰성을 상호보완하며 방어하는지 눈으로 직접 확인했습니다. 정상 종료(Controlled Shutdown) 시에는 완벽한 무중단 서비스를 보장하고, 비정상 종료 시에도 최소 임계치 내에서 데이터 정합성을 철저히 지켜냄을 입증했습니다.

5-2. 운영 환경에서의 리스크 요인 및 대응 방안 (치명적 임계치 테스트)

만약 3대의 클러스터 환경에서 브로커 장애가 연속으로 발생하여 min.insync.replicas=2 임계치가 무너지면(즉, 브로커 2대가 다운되는 상황) 시스템은 데이터 신뢰성을 지키기 위해 쓰기 요청을 전면 거부합니다.

 

 

브로커 2대 다운으로 복제본 수가 부족해지자 프로듀서에서 NotEnoughReplicasException을 발생시키며 쓰기를 거부하는 모습

  1. 지표 모니터링의 필수성: min.insync 조건이 깨지는 순간 클라이언트는 메시지를 발행할 수 없으므로, 프로덕션 환경에서는 ISR 이탈을 감지하는 UnderReplicatedPartitions 지표에 가상 얼럿(Alerting)을 필수적으로 연동해야 합니다.
  2. 리커버리 디스크 비용 인지: 강제 종료 상황 후 재기동 시에는 세그먼트 정합성 검증 작업으로 인해 디스크 I/O 리소스 소모 및 복구 지연 시간이 발생할 수 있으므로, 제어 가능한 인프라 점검 시에는 무조건 Graceful Shutdown 마인드셋을 가져가야 안전합니다.

 

6.소감

이번 ISR 장애 테스트는 단순히 카프카의 이론적인 동작을 확인하는 것을 넘어, "운영 환경에서 시스템의 가용성과 신뢰성을 어떻게 정량적으로 증명할 것인가"에 대한 깊은 고민을 해결해 준 뜻깊은 과정이었습니다.

 

처음에는 장애 발생 시 막연하게 "복구가 잘 되겠지"라고 생각했으나, 실제 비정상 종료와 Graceful Shutdown 상황을 초/밀리초 단위의 타임스탬프 로그로 실측해 보면서 파라미터 한 줄이 인프라 거동에 미치는 나비효과를 눈으로 직접 목격할 수 있었습니다. 특히, 가용성을 위해 안정성을 타협하거나 반대로 신뢰성을 위해 가용성을 제어하는 등의 무수한 '트레이드 오프(Trade-off)'를 파라미터 설정을 통해 조율하는 과정에서 분산 시스템 아키텍처를 바라보는 시야가 한층 넓어졌습니다.

 

더불어, 단순히 정상 작동하는 해피 케이스만 확인하는 것에 그치지 않고 브로커를 2대 이상 다운시켜 시스템의 임계치를 고의로 붕괴시키는 한계 테스트를 진행했던 것이 가장 기억에 남습니다. 에러 로그(NotEnoughReplicasException)를 직접 확인하고 시스템이 스스로 데이터를 방어하는 모습을 보며, 백엔드 개발자로서 "실패를 고려한 설계"가 왜 그토록 중요한지 뼈저리게 깨달았습니다.

예기치 못한 장애 상황 속에서도 비즈니스 로직과 데이터가 안전하게 보호될 수 있도록 시스템을 검증하고 다듬는 과정에서 큰 카타르시스를 느꼈습니다. 앞으로도 복사 붙여넣기 식의 구현에 안주하지 않고, 내가 짠 코드와 인프라의 거동을 철저하게 모니터링하고 집요하게 실측하여 증명하는 '기본기 있고 단단한 개발자'가 되겠다는 확신을 얻은 값진 실험이었습니다.