1976 words
10 minutes
[kafka]08. 신뢰성있는 카프카
Overview
신뢰성에 관한 것이라면, 카프카와 함께 통합되는 시스템이 카프카 그 자체만큼 중요하다.
여기서는 카프카의 맥락에서 시스템의 신뢰성을 보장하는 방법에 대해 다룬다.
- 카프카의 복제 매커니즘이 신뢰성에 미치는 영향
- 신뢰성과 관련한 브로커 및 토픽 설정
- 시나리오에 따른 클라이언트 사용법
- 시스템의 신뢰성을 검증하는 방법
01. 카프카가 보장하는 것(신뢰성 보장)
- 파티션 내부 메시지의 순서 보장
- 클라이언트가 쓴 메시지는 모든 in sync replica에 파티션에 쓰여야만 커밋된 것으로 간주
- 커밋된 메시지는 최소 1개의 작동가능한 레플리카가 남아있는한 유실되지 않는다.
- 컨슈머는 커밋된 메시지만 읽을 수 있다.
02. 복제의 영향
- 파티션은 메시지의 물리적인 분할 단위이다. 보통 브로커에 분산 저장되며 각각 독립적인 offset을 가지기에 순서가 보장되는 특성이 있다.
- 레플리카는 파티션의 리더 레플리카거나 혹은 특정 조건을 만족하는 팔로워일 경우 인 싱크 레플리카로 본다.
- 리더 레플리카가 작동불능 상대가 될 경우 인 싱크 레플리카 중 하나가 리더가 된다.
- 파티션은 다수의 레플리카를 가질 수 있으며 그 중 하나가 리더 레플리카이다.
03. 브로커 설정
Concept
- replication.factor : 파티션의 복제본 수
- unclean.leader.election.enable : ISR 외의 레플리카가 리더가 될 수 있는지 여부
- min.insync.replicas in sync replica의 최소 수. 이 수보다 적은 수의 레플리카가 있을 경우 커밋이 실패한다.
replacation factor
- 클라우드 환경에서 카프카를 운용할 경우 availablity zone을 랙과 비슷한 개념으로 사용하는 것이 보통이다.
unclean.leader.election.enable
-
leader가 다운되었을 때 ISR 내의 레플리카 중 하나가 리더가 되는데, 이때 ISR 외의 레플리카가 리더가 되는 것을 허용할지 여부를 결정하는 설정
-
leader가 clean하다는 것은 리더가 될 레플리카가 ISR 내에 있는 것을 의미
-
기본값은 false
unclean.leader.election.enable=false
데이터 정합성 측면
- 정합성은 기본적으로 일관성의 문제
- ISR 내의 레플리카만 리더가 될 수 있어 데이터 손실 없음
- 모든 컨슈머는 동일한 데이터를 보게 됨
가용성 측면
- 모든 ISR이 다운되면 파티션 전체가 사용 불가능
- 서비스 중단 시간(downtime) 발생 가능성 높음
- 복구를 위해 ISR 중 하나가 다시 복구 될 때까지 대기 필요
unclean.leader.election.enable=true
데이터 정합성 측면
- 데이터 손실 발생 가능
- 이전 리더가 가진 커밋된 메시지들이 유실될 수 있음
- 일시적으로 다른 컨슈머들이 서로 다른 데이터를 볼 수 있음
가용성 측면
- 높은 가용성 보장
- ISR 외의 레플리카도 리더가 될 수 있어 서비스 중단 최소화
- 빠른 복구 가능
min.insync.replicas
- 커밋된 데이터를 2개 이상의 레플리카에 쓸 경우 min.insync.replicas 를 보다 높게 잡아줄 필요가 있다.
04 Producer 설정
Concept
- acks : acknowledgments. 프로듀서가 메시지응답을 성공으로 판정한는 기준에 대한 설정. 안정성과 성능간 트레이드오프와 관련
- delivery.timeout.ms : 프로듀서는 이 시간 간격안에 있는 한 메시지 전송을 재시도 한다.
- 전송 실패한 메시지를 계속 재시도하는 것은 메시지가 중복될 위험을 내포한다.
acks
retries
잘못된 메시지의 처리방식
- 요구사항에 따라 에러를 어떤식으로 처리할 지가 달라진다.
- 메시지 재전송이 에러 핸들러가 하는 일의 전부라면, 프로듀서의 재전송기능을 쓰는 편이 더 낫다.
04. Consumer 설정
NOTE커밋된 메시지와 커밋된 오프셋의 차이 커밋된 메시지는 모든 인 싱크 레플리카에 쓰여져 컨슈머가 읽을 수 있는 메시지를 의미 커밋된 오프셋은 컨슈머가 메시지를 받아서 처리완료한 지점을 의미
Concept
- offset commit : 컨슈머가 특정 파티션의 offset까지의 메시지를 안전하게 처리할 수 있다고 보장할 수 있는 지점을 카프카에 기록하는 작업. 이는 단순히 처리완료 신호가 아니라 복구가 가능한 지점을 표기하는것에 가까움. 특정 offset을 commit했다는 것은 offset이전의 모든 메시지도 처리되었음을 의미
- group.id : 기본적으로 같은 그룹id를 갖는 두 개의 컨슈머가 같은 토픽을 구독할 경우, 각각의 컨슈머에는 해당 토픽 전체의 서로 다른 서브셋만 할당되기 때문에 각각은 서로 다른 부분의 메시지를 읽게된다.
- auto.offset.reset : 컨슈머가 브로커에 없는 오프셋을 요청할 때 컨슈머가 처음부터 읽을지(데이터 유실 최소화), 가장 최신의 메시지부터 읽을지(중복처리 최소화와 메시지 누락의 트레이드오프)를 결정하는 설정
- enable.auto. : 일정한 시간에 맞춰 컨슈머가 오프셋을 커밋하게 할 것인가 코드에서 오프셋을 커밋하게 할 것인가?
- auto.commit.interval.ms : 오토커밋의 주기. 더 자주 커밋할수록 오버헤드 역시 늘어나지만 컨슈머가 정지했을 경우의 중복의 수는 줄어든다.
Consumer 명시적 offset commit
NOTE재시도 가능한 에러를 컨슈머가 처리하는 두 가지 방식
- 마지막으로 처리한 오프셋을 커밋. 나중에 처리할 레코드들을 버퍼에 저장. 컨슈머의 pause() 메서드를 사용해 레코드를 버퍼에 저장하고, 커밋된 오프셋 이후에 처리할 레코드들을 처리한다.
- 별도의 토픽에 쓴 후 재처리. 별도의 컨슈머 그룹을 사용해서 재시도 토픽에 저장된 레코드 처리
Concept
- dead letter queue : 재처리가 불가능한 메시지를 보관하는 큐
Wrap-up
Key Takeaway
- 신뢰성에 관한 것이라면, 카프카와 함께 통합되는 시스템이 카프카 그 자체만큼 중요하다.
- 신뢰성 있는 시스템 구축에 있어서의 트레이드오프는 메시지 저장의 신뢰성과 그 외의 가용성, 높은 처리량 , 낮은 레이턴시 등의 요구사항들과의 균형을 맞추는 것이다.
- 복제팩터가 N일 경우 N-1개의 레플리카가 다운되어도 파티션은 계속 작동하며 토픽의 데이터를 읽고 쓸 수 있다. 따라서 복제팩터가 클 수록 가용성과 신뢰성은 늘어나고 장애가 발생할 가능성은 줄어든다.
- Consumer의 커밋 빈도는 성능과 크래시 발생시 중복 개수 사이의 트레이드 오프 이다.
- 어플리케이션을 설계할 때 컨슈머에서 리밸런싱이 발생할 것이라는 것을 염두해 두어야 한다. 이것은 보통 파티션이 해제되기 전 오프셋을 커밋하고 새로운 파티션이 할당되었을 때 어플리케이션이 보유하고 있던 상태를 삭제하는 작업을 포함한다.
[kafka]08. 신뢰성있는 카프카
https://yjinheon.netlify.app/posts/02de/kafka/de-kafka-08_kafka_reliability/