5. 브로커와 리플리케이션: 데이터 유실을 막는 핵심 원리

리플리케이션(Replication)의 역할과 구조

리플리케이션(복제)은 카프카가 고가용성(High Availability)과 데이터 내구성(Durability)을 보장하는 핵심 메커니즘입니다. 하나의 파티션을 여러 브로커에 복제해 둠으로써, 특정 브로커에 장애가 발생하더라도 데이터 유실 없이 서비스를 지속할 수 있습니다.

ISR (In-Sync Replicas): 리더의 자격을 갖춘 정예 그룹

ISR은 "동기화된 복제본 그룹"을 의미하며, 리더의 데이터를 거의 실시간으로 복제하여 뒤처지지 않은 상태를 유지하고 있는 리더와 팔로워들의 집합입니다. ISR은 카프카의 데이터 무결성을 이해하는 데 가장 중요한 개념입니다.

파티션 0의 복제 상태

브로커 1 (리더, ISR)
Offset 3: Msg D
Offset 2: Msg C
Offset 1: Msg B
브로커 2 (팔로워, ISR)
Offset 3: Msg D
Offset 2: Msg C
Offset 1: Msg B
브로커 3 (팔로워, Out-of-Sync)
Offset 1: Msg B
Offset 0: Msg A

브로커 1과 2는 리더와 데이터가 동기화되어 ISR에 속해있지만, 브로커 3은 네트워크 문제 등으로 복제가 지연되어 ISR에서 제외되었습니다.

ISR 퇴출: "너, 2군으로 내려가!"

"ISR에서 쫓겨난다"는 말은 브로커가 종료되거나 파티션이 삭제되는 물리적인 행위를 의미하는 것이 아닙니다. 이는 "리더를 대체할 자격이 없다"고 판단하여 논리적으로 그룹에서 제외하는 '자격 박탈'에 가깝습니다.

마치 스포츠 팀에서 1군 엔트리(ISR)에 있던 선수가 부상으로 2군(Out-of-Sync)으로 내려가는 것과 같습니다. 선수가 팀에서 방출되는 것이 아니라, 잠시 경기에 뛸 수 없는 상태가 되는 것입니다.

  1. 문제 발생: 팔로워 브로커에 과부하가 걸려 리더의 데이터를 제때 복제하지 못하고 뒤처지기 시작합니다.
  2. 자격 박탈: 컨트롤러는 해당 팔로워를 ISR 명단에서 조용히 제거합니다.
  3. 그 후: 해당 팔로워는 종료되지 않고 계속해서 리더의 데이터를 따라잡으려고 노력합니다. 다만, acks=all 설정 시 이 팔로워는 더 이상 기다림의 대상이 되지 않습니다.
  4. 복귀: 팔로워가 다시 리더의 최신 데이터까지 모두 복제하는 데 성공하면, 컨트롤러는 해당 팔로워를 다시 ISR 명단에 포함시킵니다.
acks=all의 진짜 의미
프로듀서의 acks=all 설정은 "리더와 모든 팔로워에게 복제가 완료되면 성공 응답을 받겠다"는 의미가 아닙니다. 정확히는 "리더와 ISR에 포함된 모든 팔로워에게 복제가 완료되면 성공 응답을 받겠다"는 의미입니다.

만약 위 그림의 상태에서 프로듀서가 acks=all로 메시지를 보낸다면, 리더인 브로커 1과 ISR 멤버인 브로커 2에만 복제가 완료되면 즉시 성공(Ack) 응답을 받습니다. 뒤처져 있는 브로커 3까지 기다리지 않음으로써, 특정 팔로워의 장애가 전체 시스템의 성능을 저하시키는 것을 방지합니다.

리더 선출(Leader Election): 장애 극복 시나리오

만약 리더 브로커에 장애가 발생하면, 카프카 클러스터의 컨트롤러는 즉시 새로운 리더를 선출하여 서비스 중단을 최소화해야 합니다. 이때 어떤 팔로워를 새로운 리더로 선택할 것인지가 데이터의 유실 여부를 결정합니다.

1. 깨끗한 선출 (Clean Leader Election) - 기본값

컨트롤러는 새로운 리더를 반드시 ISR에 속해 있던 팔로워 중에서만 선택합니다. ISR 멤버들은 리더와 데이터가 완벽히 동기화되어 있음이 보장되므로, 이들 중 누가 새로운 리더가 되더라도 데이터는 절대 유실되지 않습니다.

리더 장애 발생 및 깨끗한 선출

브로커 1 (리더) 장애!
컨트롤러가 감지
브로커 2 (ISR 멤버)

컨트롤러는 ISR에 있던 브로커 2를 새로운 리더로 임명합니다. 데이터 유실이 없습니다.

2. 더러운 선출 (Unclean Leader Election) - 위험한 옵션

만약 리더와 ISR 멤버들이 동시에 장애를 겪어 ISR이 비어버리는 최악의 상황이 발생하면 어떻게 될까요? 이때 unclean.leader.election.enable=true 옵션이 설정되어 있다면, 컨트롤러는 ISR에 없던, 즉 데이터가 뒤처진 팔로워라도 억지로 리더로 임명합니다.

실무 트러블슈팅: acks=all인데 데이터가 유실되는 이유

문제 상황: 데이터 무결성을 위해 acks=all 설정을 사용했음에도 불구하고, 드물게 데이터가 유실되는 현상이 발생했습니다.

원인 분석: unclean.leader.election.enable 옵션이 true로 설정되어 있었을 가능성이 매우 높습니다. 리더와 ISR 멤버가 모두 다운되는 상황에서, 최신 데이터를 가지고 있지 않던 팔로워가 새로운 리더로 선출되었습니다. 이로 인해 이전 리더만 가지고 있던 최신 메시지들이 영원히 유실된 것입니다.

결론: 가용성(Availability) vs 일관성(Consistency)의 트레이드오프

따라서, 데이터 정합성이 조금이라도 중요한 서비스라면 이 옵션은 반드시 false로 유지해야 합니다.

Read Repair가 필요 없는 이유: 카프카의 일관성 모델

카프카의 데이터 일관성 모델을 이해할 때, Cassandra의 대표적인 기능인 'Read Repair(읽기 시점 복구)'와 비교하면 그 차이점이 명확해집니다. 결론부터 말하면, 카프카는 Read Repair를 사용하지 않으며, 사용할 필요도 없도록 설계되었습니다.

철학의 차이: Read Repair vs. Kafka

Read Repair (e.g., Cassandra) Kafka의 리더-팔로워 모델
핵심 철학 "일단 쓰고, 읽을 때 고친다" (사후 처리) "쓸 때부터 완벽하게 보장한다" (사전 예방)
동작 방식 데이터를 읽을 때 여러 복제본을 비교하여 불일치를 감지하고, 백그라운드에서 데이터를 복구합니다. 모든 쓰기는 리더를 통해 이루어지며, ISR 그룹 전체에 복제가 완료되어야만 성공으로 간주합니다.
읽기(Read) 성능 여러 복제본을 확인해야 하므로 상대적으로 복잡하고 느릴 수 있습니다. 항상 일관성이 보장된 리더로부터만 읽으므로, 매우 단순하고 빠릅니다.

카프카는 쓰기 시점(Write-time)에 데이터 일관성을 강력하게 보장함으로써, 읽기 시점(Read-time)의 복잡성을 완전히 제거한 모델입니다.

주요 복제 관련 파라미터

파라미터 설명 기본값
replication.factor 토픽 생성 시 파티션 당 복제본의 수. (토픽 레벨 설정) 1
min.insync.replicas acks=all로 전송된 메시지를 처리하기 위해 필요한 최소 ISR 멤버 수. 이 값보다 ISR 멤버 수가 적으면 프로듀서는 에러를 반환합니다. replication.factor가 3일 때 2로 설정하는 것이 일반적입니다. 1
replica.lag.time.max.ms 팔로워가 리더로부터 데이터를 가져가지 못했을 때, ISR에서 제외되기까지 대기하는 최대 시간. 10000 (10초)
unclean.leader.election.enable ISR에 리더 후보가 없을 때, 동기화되지 않은 복제본을 리더로 선출할지 여부. false