Replication Factor 설정

Replication Factor는 Kafka의 고가용성과 데이터 내구성을 결정하는 핵심 설정입니다.

Replication 개념

기본 구조

┌─────────────────────────────────────────────────────────────────┐
│                  Replication Factor = 3                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Topic: orders, Partition 0                                     │
│                                                                 │
│  Broker 1         Broker 2         Broker 3                     │
│  ┌─────────┐     ┌─────────┐     ┌─────────┐                   │
│  │ Leader  │────>│Follower │     │Follower │                   │
│  │ (P0)    │     │ (P0)    │<────│ (P0)    │                   │
│  └─────────┘     └─────────┘     └─────────┘                   │
│       │               ↑               ↑                         │
│       └───────────────┴───────────────┘                         │
│              복제 (Replication)                                  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Replication Factor의 의미

RF의미허용 장애
1복제 없음0개 Broker
21개 복제본1개 Broker
32개 복제본2개 Broker
NN-1개 복제본N-1개 Broker

Replication Factor 설정

Topic 생성 시

# RF=3으로 토픽 생성
kafka-topics.sh --create \
    --topic my-topic \
    --bootstrap-server localhost:9092 \
    --partitions 6 \
    --replication-factor 3

Broker 기본값

# server.properties
# 자동 생성 토픽의 기본 RF
default.replication.factor = 3

기존 토픽 RF 변경

# 1. 재할당 계획 생성
cat > reassignment.json << EOF
{
  "version": 1,
  "partitions": [
    {"topic": "my-topic", "partition": 0, "replicas": [1, 2, 3]},
    {"topic": "my-topic", "partition": 1, "replicas": [2, 3, 1]},
    {"topic": "my-topic", "partition": 2, "replicas": [3, 1, 2]}
  ]
}
EOF
 
# 2. 재할당 실행
kafka-reassign-partitions.sh --execute \
    --bootstrap-server localhost:9092 \
    --reassignment-json-file reassignment.json
 
# 3. 진행 상황 확인
kafka-reassign-partitions.sh --verify \
    --bootstrap-server localhost:9092 \
    --reassignment-json-file reassignment.json

RF와 관련 설정

min.insync.replicas

# acks=all 사용 시 최소 동기화 Replica 수
min.insync.replicas = 2

RF와 min.insync.replicas 조합

RF = 3, min.insync.replicas = 2

정상 상태:
┌────────┐  ┌────────┐  ┌────────┐
│ Leader │  │Follower│  │Follower│
│ (ISR)  │  │ (ISR)  │  │ (ISR)  │
└────────┘  └────────┘  └────────┘
ISR = 3, 쓰기 가능 ✓

1개 Broker 장애:
┌────────┐  ┌────────┐  ┌────────┐
│ Leader │  │Follower│  │  DOWN  │
│ (ISR)  │  │ (ISR)  │  │        │
└────────┘  └────────┘  └────────┘
ISR = 2, 쓰기 가능 ✓ (min.insync.replicas = 2)

2개 Broker 장애:
┌────────┐  ┌────────┐  ┌────────┐
│ Leader │  │  DOWN  │  │  DOWN  │
│ (ISR)  │  │        │  │        │
└────────┘  └────────┘  └────────┘
ISR = 1, 쓰기 불가 ✗ (acks=all 시)

Producer acks 설정

// RF와 함께 고려해야 하는 설정
props.put("acks", "all");  // 모든 ISR에 쓰기 확인

RF 결정 가이드

권장 값

환경RFmin.insync.replicas설명
개발11단일 노드
테스트21기본 복제
프로덕션32표준 권장
크리티컬53높은 내구성

고려 사항

RF 선택 시 고려사항:

1. 가용성 요구사항
   - 허용 가능한 동시 장애 Broker 수
   - 복구 시간 목표 (RTO)

2. 데이터 내구성
   - 데이터 손실 허용 범위
   - 규정 준수 요구사항

3. 리소스
   - 저장 공간: 원본 × RF
   - 네트워크: 복제 트래픽
   - Broker 수: RF ≤ Broker 수

4. 성능
   - 쓰기 레이턴시 (acks=all 시)
   - 복제 지연

저장 공간 계산

일일 데이터: 100GB
Retention: 7일
RF: 3

필요 공간:
= 일일 데이터 × Retention × RF
= 100GB × 7 × 3
= 2.1TB

Broker당 (3 Broker):
= 2.1TB / 3
= 700GB

Rack Awareness

개념

┌─────────────────────────────────────────────────────────────────┐
│                    Rack-Aware Replication                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Rack A               Rack B               Rack C               │
│  ┌─────────────┐     ┌─────────────┐     ┌─────────────┐       │
│  │  Broker 1   │     │  Broker 2   │     │  Broker 3   │       │
│  │  ┌───────┐  │     │  ┌───────┐  │     │  ┌───────┐  │       │
│  │  │Leader │  │     │  │Replica│  │     │  │Replica│  │       │
│  │  │ P0    │  │     │  │ P0    │  │     │  │ P0    │  │       │
│  │  └───────┘  │     │  └───────┘  │     │  └───────┘  │       │
│  └─────────────┘     └─────────────┘     └─────────────┘       │
│                                                                 │
│  Rack 전체 장애에도 데이터 가용                                   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

설정

# server.properties
broker.rack = rack-a
 
# 또는 /rack-a 같은 계층 구조
broker.rack = /dc1/rack-a

복제 배치 확인

# 토픽의 Replica 배치 확인
kafka-topics.sh --describe \
    --topic my-topic \
    --bootstrap-server localhost:9092
 
# 출력 예시:
# Topic: my-topic  Partition: 0  Leader: 1  Replicas: 1,2,3  Isr: 1,2,3

Unclean Leader Election

설정

# 기본값: false (권장)
unclean.leader.election.enable = false

동작 비교

ISR이 비어있을 때:

unclean.leader.election.enable = false:
┌─────────────────────────────────────────┐
│ 모든 ISR Broker 장애                     │
│ → 파티션 사용 불가 (가용성 ↓)             │
│ → 데이터 손실 없음 (내구성 ↑)             │
└─────────────────────────────────────────┘

unclean.leader.election.enable = true:
┌─────────────────────────────────────────┐
│ 모든 ISR Broker 장애                     │
│ → Out-of-sync Replica가 Leader 됨       │
│ → 파티션 사용 가능 (가용성 ↑)             │
│ → 일부 데이터 손실 가능 (내구성 ↓)        │
└─────────────────────────────────────────┘

모니터링

주요 메트릭

Under Replicated Partitions:
kafka.server:type=ReplicaManager,name=UnderReplicatedPartitions
→ 0이어야 정상

Offline Partitions:
kafka.controller:type=KafkaController,name=OfflinePartitionsCount
→ 0이어야 정상

ISR Shrink/Expand Rate:
kafka.server:type=ReplicaManager,name=IsrShrinksPerSec
kafka.server:type=ReplicaManager,name=IsrExpandsPerSec

명령행 확인

# Under Replicated 파티션 확인
kafka-topics.sh --describe \
    --bootstrap-server localhost:9092 \
    --under-replicated-partitions
 
# Offline 파티션 확인
kafka-topics.sh --describe \
    --bootstrap-server localhost:9092 \
    --unavailable-partitions

관련 문서