home
신뢰성 있는 데이터 전달
신뢰성 보장
- 아파치 카프카가 보장하는 것
- 파티션 안의 메시지들 간에 순서를 보장
- 메시지는 모든 인-싱크 레플리카 파티션에 쓰여진 뒤에야 커밋된 것으로 간주
- 레플리카가 남아있는 이상 유실되지 않음
- 컨슈머는 커밋된 메시지만 읽을 수 있음
복제
- 복제는 신뢰성 보장의 핵심 -> 메시지의 지속성 유지
- 인싱크 레플리카 수가 줄어들면 파티션의 실질적인 복제 팩터가 줄어듦 -> 중단시간이 길어지거나 데이터 유실 가능성 높아짐
브로커 설정
- 복제 팩터
replication.factor
,default.replication.factor
- 복제 팩터가 클수록 가용성 신뢰성이 늘어난다.
- 그만큼 디스크 공간이 필요하다.
- 가용성, 지속성, 처리량, 종단 지연, 비용을 고려해야한다.
- 언클린 리더 선출
unclean.leader.election.enable
, 기본값false
- 아웃오브싱크 레플리카가 리더가 되야할 때 문제점
- 만약 새리더가 될 수 없다고 하면 마지막 인싱크 레플리카가 복구될 때 까지 기다려야함
- 만약 될 수 있다고 하면 동기화 전 메시지 유실, 일관성 깨진다.
- 트레이드오프 고려
- 최소 인-싱크 레플리카
min.insync.replicas
- 값에 따라서 더이상 요청을 받을 수 없다.
- 레플리카를 인-싱크 상태로 유지하기
zookeeper.session.timeout.ms
: 브로커가 주키퍼로 하트비트 전송을 멈출 수 있는 최대 시간replica.lag.time.max.ms
: 아웃오브 싱크 상태 시간 제한 -> 컨슈머 최대 지연 시간에 지장을 준다.
신뢰성 있는 시스템에서 프로듀서 사용하기
- 신뢰성 요구 조건에 맞는 acks 설정, 에러 처리가 중요
- 응답 보내기
- acks 0: 프로듀서가 네트워크로 메시지를 전송한 시점에서 성공
- acks 1: 리더가 메시지를 받아서 파티션 데이터 파일에 쓴 직후 응답 or 에러
- acks all: 리더가 모든 인-싱크 레플리카가 메시지를 받아갈 때 까지 기다렸다가 응답 or 에러
- 프로듀서 재시도 설정
- 에러코드는 두가지 -> 전송을 재시도하면 해결될 수 있는 것과 아닌 것
- 메시지 유실되지 않는 것이 목표 -> 재시도 가능한 에러면 계속 재시도
- 그러나 메시지 중복 위험이 있다.
- 추가적인 에러 처리
- 에러가 발생했지만 재전송이 불가능한 메시지들을 어떻게 처리할 것인가?
- 폐기, 에러 로깅, 메시지 전송 중단 등등.. 고려
신뢰성 있는 시스템에서 컨슈머 사용하기
- 오프셋 커밋이 중요하다. -> 중단되었다가 재시작해도 어디서부터 작업을 이어나갈지 알아야 하기 때문
- 신뢰성 있는 처리를 위해 중요한 컨슈머 설정
group.id
: 고유해야함auto.offset.reset
: 커밋된 오프셋이 없을 때나 컨슈머가 브로커에 없는 오프셋을 요청할 때 동작earliest
: 파티션 맨 앞부터latest
: 파티션 맨 뒤부터
enable.auto.commit
: 알아서 커밋? 코드에서 직접 커밋?auto.commit.interva.ms
: 자동 밋 주기, 자주 커밋할 수록 오버헤드
- 컨슈머에서 명시적으로 오프셋 커밋하기
- 오프셋 직접 커밋 수행시 정확성과 성능에 미치는 영향 고려 필요
- 메시지 처리 먼저, 오프셋 커밋은 나중에
- 커밋 빈도는 성능과 크래시 발생시 중복 개수 사이의 트레이드 오프이다
- 정확한 시점에 정확한 오프셋을 커밋하자
- 리밸런스는 발생한다. 적절히 처리
- 컨슈머는 재시도를 해야할 수도 있다.
- ex) 레코드를 저장하려는데 DB가 사용이 불가능할 때
- 앞 레코드가 실패하면 뒤 레코드를 커밋하면 안된다
- DLQ 등으로 해결
- 컨슈머가 상태를 유지해야 할 수도 있다.