고승범 님의 "실전 카프카 개발부터 운영까지" 책을 정리한 포스팅 입니다.
1. 카프카 리플리케이션
동작
예제) 토픽 생성
더보기
/opt/bitnami/kafka/bin/kafka-topics.sh --create --topic topic_chat \
--bootstrap-server localhost:9092 \
--replication-factor 2 \
--partitions 2
예제) 토픽 메시지 생성
더보기
/opt/bitnami/kafka/bin/kafka-console-producer.sh --topic topic_chat \
--bootstrap-server localhost:9092
예제) 토픽 조회
더보기
/opt/bitnami/kafka/bin/kafka-topics.sh --topic topic_chat --describe \
--bootstrap-server localhost:9092
Topic: topic_chat TopicId: Xyz123... PartitionCount: 2 ReplicationFactor: 2 Configs:
Topic: topic_chat Partition: 0 Leader: 1 Replicas: 1,2 Isr: 1,2
Topic: topic_chat Partition: 1 Leader: 2 Replicas: 2,1 Isr: 2,1
항목 | 값 설명 |
Partition | 파티션 번호 (0, 1) |
Leader | 해당 파티션의 쓰기 및 읽기 담당 브로커 |
Replicas | 해당 파티션의 모든 복제본을 가진 브로커 목록 |
ISR |
현재 동기화(in-sync) 상태인 복제본 브로커 목록 (복제 성공 중인 것들)
|
예제) 토픽 메시지 세그먼트 조회
더보기
/opt/bitnami/kafka/bin/kafka-dump-log.sh --print-data-log \
--files /bitnami/kafka/data/topic_chat-0/00000000000000000000.log
Dumping file: /bitnami/kafka/data/topic_chat-0/00000000000000000000.log
offset: 0 position: 0 CreateTime: 1715408001000 key: user123 payload: Hello!
offset: 1 position: 132 CreateTime: 1715408002100 key: user456 payload: How are you?
offset: 2 position: 278 CreateTime: 1715408003200 key: user123 payload: I'm good.
구성
역할 | 설명 |
리더 (Leader) |
프로듀서/컨슈머의 읽기/쓰기 작업을 담당
- 복제된 파티션들 중 하나가 리더로 선출됨 |
팔로워 (Follower) |
리더의 데이터를 동기화 함
- 리더에 문제가 발생하면, 팔로워 중 하나가 리더로 승격됨 |
예시) 리더/팔로워 확인하기
더보기
'토픽 조회'를 통해 확인 가능
Topic: topic_chat TopicId: 3mn7GidkQhKY2IkBpN0T2Q PartitionCount: 2 ReplicationFactor: 2 Configs:
Topic: topic_chat Partition: 0 Leader: 0 Replicas: 1,0 Isr: 0,1
Topic: topic_chat Partition: 1 Leader: 0 Replicas: 0,1 Isr: 0,1
복제 유지
항목 | 설명 |
ISR (In-Sync Replica) | 리더와 데이터를 동일하게 복제하고 있는 팔로워들의 집합 |
리더 역할 | ISR 내 모든 팔로워가 메시지를 수신할 때까지 기다리고 감시 |
팔로워 조건 | 지속적으로 리더로부터 메시지를 잘 복제해야 ISR에 남을 수 있음 |
ISR 제외 | 일정 시간 이상 지연되면 자동으로 ISR에서 제거됨 |
커밋
항목 | 설명 |
커밋 |
ISR 내 모든 팔로워가 해당 메시지를 수신 완료 시, 리더는 내부적으로 "커밋됨" 상태로 표시
|
하이워터마크 |
마지막으로 커밋된 메시지의 offset
- 컨슈머는 이 위치까지 읽을 수 있음 |
예시) 하이워터마크 위치 확인
더보기
cat /bitnami/kafka/data/replication-offset-checkpoint
# partition id / high watermark id
topic_chat 0 2
topic_chat 1 0
리더와 팔로워의 단계별 리플리케이션 동작
- 리더의 감시 작업은 많은 통신을 요구하므로 빠른 성능을 내기 어렵게 함
- 카프카는 감시 작업에 드는 통신을 최소화할 수 있도록 설계되었음
복제 흐름
- 리더: 메시지 수신
- 팔로워: 메시지 요청 (+오프셋 정보)
- 리더: 메시지 응답 (+하이워터마크)
- 팔로워: 메시지 수신
- 하이워터마크 갱신 (리더의 하이워터마크 >= 내 하이워터마크)
- 리더: 모든 팔로워들의 수신 완료 확인
- 모든 팔로워들의 메시지 오프셋 확인
- 모든 팔로워가 최신 오프셋 도달 ✅ → 메시지 커밋
- 모든 팔로워가 최신 오프셋 도달 ❌ → 메시지 커밋 보류 (팔로워가 리더를 따라잡도록 계속 메시지 요청 유도)
- ➡️ 팔로워가 끊임없이 복제를 시도하면서, 리더와 데이터 일관성을 맞추게 됨
- 리더: 커밋
➡️ ACK 없이 효율적으로 정합성 확보 가능
예시
더보기
* 리더: 메시지 발행 받기 (message1)
* 팔로워1 메시지 consume 요청
1. 팔로워1: 메시지 요청 (message1 + 팔로워 메시지 오프셋)
2. 리더: 메시지 응답 (message1 + 리더 하이워터마크)
3. 팔로워1: 메시지 수신 (message1)
- 하이워터마크 갱신
* 팔로워2 메시지 요청
1. 팔로워2: 메시지 요청 (message1)
2. 리더: 메시지 응답 (message1 + 자신의 하이워터마크)
3. 팔로워2: 메시지 수신 (message1)
- 하이워터마크 갱신
* 리더: 모든 팔로워들의 복제 완료 확인
- 커밋
- 하이워터마크 갱신
리더 에포크
- 리더가 바뀔 때마다 1씩 증가하는 버전 번호 (32비트 정수)
항목 | 설명 |
목적 |
데이터 정합성 유지 (리더 변경 전후의 상태 불일치 탐지 역할)
|
관리 주체 | 컨트롤러 (리더 선출 및 에포크 관리) |
전파 방법 |
리더 변경 시, 리플리케이션 프로토콜을 통해 팔로워에게 자동 전달됨
|
메시지 손실 가능성 | 팔로워가 리더로 승격될 때, 커밋되지 않은 최신 메시지는 손실 될 수 있음 |
복구 과정에서 역할 |
하이워터마크 신뢰 불가 시(리더 변경 등), 에포크 + 오프셋 비교로 동기화 정확성 판단
|
복구 과정 (요약) |
1. 팔로워가 리더에게 현재 에포크와 마지막 오프셋 요청
2. 리더는 에포크/오프셋 일치 여부 확인 3. 불일치 시, 리더가 일치하는 지점부터 데이터 재전송 (fetch) 4. 동기화 완료 후 하이워터마크 갱신 |
2. 컨트롤러
- Kafka 클러스터 내에서 리더 선출과 브로커 상태 관리를 담당하는 브로커
역할
항목 | 설명 |
리더 선출 | ISR 내 팔로워 중 하나를 새로운 리더로 지정함 |
브로커 실패 감지 | 특정 브로커가 응답 없을 경우, 장애로 인식 |
메타정보 기록 | 새로운 리더 정보를 ZooKeeper 또는 KRaft에 기록 |
정보 전파 | 모든 브로커에게 변경 사항(리더 변경 등)을 전파함 |
리더 부재 시 영향
- 리더가 없으면 쓰기 작업이 불가, 전체 작업 실패
- ➡️ 리더 선출을 빠르게 수행해야 함
항목 | 내용 |
브로커 정상 종료 과정 |
1. 관리자가 브로커 종료 명령어 실행 (SIG_TERM)
2. 브로커가 컨트롤러에게 종료 알림 3. 컨트롤러가 새 리더 선출 4. 리더 정보를 주키퍼에 기록 5. 모든 브로커에게 리더 변경 사항 전파 6. 종료 요청 브로커에 정상 종료 응답 7. 디스크에 저장 후 정상 종료 |
브로커 비정상 종료 과정 |
1. 브로커 다운 발생 (SIG_TERM 같은 신호 없이 죽음)
2. 컨트롤러가 감지 (헬스 체크 중 실패) 3. 새 리더 즉시 선출 4. 리더 정보를 주키퍼에 기록 5. 모든 브로커에게 리더 변경 사항 전파 ⚠️ 파티션 다운타임 발생 ⚠️ 클라이언트 장애 발생 (재시도 매커니즘을 통해 복구 진행) |
3. 로그 세그먼트
로그 세그먼트
- 토픽 메시지를 파일 단위로 분할 저장 (로그 파일 하나 = 세그먼트 파일)
- 메시지가 인입될 때마다 파일에 append됨
- key, value, offset, size 등을 함께 기록
세그먼트 롤링
- 세그먼트 파일이 너무 커지면 새로운 세그먼트 파일이 생성됨
- retention.ms: 로그 세그먼트 파일 최대 보관 시간
- retention.bytes: 로그 세그먼트 파일 최대 크기
롤링 정책
구분 | 삭제 (Delete) |
컴팩션 (Compaction)
|
설정 값 | log.cleanup.policy=delete |
log.cleanup.policy=compact
|
동작 방식 | 오래된 로그 세그먼트 파일을 삭제 |
최신 데이터만 남기고 압축
|
삭제 대상 | 최신 파일은 남기고, 과거 파일부터 삭제 |
중복된 key에 대해 가장 최신 value만 보관
|
주요 설정 옵션 | 없음 (단순 삭제) |
- log.cleaner.min.compaction.lag.ms (최소 대기 시간)
- log.cleaner.max.compaction.lag.ms (최대 대기 시간) |
사용 목적 | 오래된 데이터 자체가 필요 없을 때 사용 |
같은 key의 최신 상태만 유지하고 싶을 때 사용
|
대표 사용 예시 | 일반 메시지 토픽 데이터 관리 |
내부 토픽 관리 (__consumer_offsets)
|
특이사항 | 디스크 공간 확보 목적이 큼 |
과거 데이터가 중요하지 않을 경우에 적합
|
__consumer_offsets 토픽
- 내부 특수 토픽
- 각 컨슈머 그룹의 오프셋 커밋 정보 저장
- key-value 형태 (key: 컨슈머 그룹 - 토픽, value: 오프셋 번호)
- 컨슈머가 죽었다가 살아나도 이어서 소비할 수 있음
'Kafka' 카테고리의 다른 글
[Kafka] 9. Kafka Streams (0) | 2025.05.12 |
---|---|
[실전 카프카 개발부터 운영까지] 6. 컨슈머의 내부 동작 원리와 구현 (0) | 2025.05.08 |
[실전 카프카 개발부터 운영까지] 5. 프로듀서의 내부 동작 원리와 구현 (0) | 2025.05.07 |
[실전 카프카 개발부터 운영까지] 3. 카프카 기본 개념과 구조 (0) | 2025.05.03 |
[실전 카프카 개발부터 운영까지] 1. 카프카 개요 (0) | 2025.05.02 |