-
[카프카 핵심 가이드] CH7. 신뢰성 있는 데이터 전달Study/카프카 핵심 가이드 2025. 3. 9. 15:44
✅ 주요 내용
- 신뢰성 보장의 의미
- 카프카의 복제 메커니즘과 이것이 시스템의 신뢰성에 어떻게 영향을 미치는지
- 서로 다른 활용 사례에 대해 카프카의 브로커와 토픽들을 어떻게 설정해줘야 하는지
- 서로 다른 신뢰성 상황에서 클라이언트들(프로듀서와 컨슈머)을 어떻게 사용해야 하는지
- 시스템의 신뢰성을 검증하는 방법
브로커는 메시지 저장, 프로듀서는 메시지 전송, 컨슈머는 메시지 수신(오프셋 커밋)에 대한 책임을 가지고 있다.
따라서 각 관점에서 어떤 설정을 통해 신뢰성을 높일 수 있는지 생각하면 된다.
7.1 신뢰성 보장
- 카프카가 제공하는 보장을 알면, 실패 상황에서 시스템이 어떻게 작동하는지 알 수 있음
- 카프카는 무엇을 보장할까?
- 파티션 안의 메시지들 간에 순서를 보장한다.
- 만약 메시지 A 다음에 B가 쓰여졌고, 동일한 프로듀서가 동일한 파티션에 썼을 경우, 카프카는 B의 오프셋이 A보다 큰 것을 보장함
- 컨슈머 역시 A를 읽은 후 B를 읽게 됨
- 클라이언트가 쓴 메시지는 모든 인-싱크 레플리카의 파티션에 쓰여진 뒤에야 '커밋'된 것으로 간주된다. (디스크에 플러시(flush)될 필요까지는 없음)
- 프로듀서는 메시지 전송 후 응답 받는 시점을 정할 수 있음
- ex) 메시지가 완전히 커밋된 후 or 리더에게만 쓰여진 후 or 네트워크로 전송된 후 바로
- 프로듀서는 메시지 전송 후 응답 받는 시점을 정할 수 있음
- 커밋된 메시지들은 최소 1개의 작동 가능한 레플리카가 남아 있는 한 유실되지 않는다.
- 컨슈머는 커밋된 메시지만 읽을 수 있다.
- 파티션 안의 메시지들 간에 순서를 보장한다.
- 설정 매개변수를 조절해 어느 정도의 신뢰성이 필요한지 결정할 수 있음
7.2 복제
- 카프카의 복제 메커니즘은 파티션별로 다수의 레플리카를 유지한다는 특성과 함께 카프카의 신뢰성 보장의 핵심임
- 하나의 메시지를 여러 개의 레플리카에 씀으로써 카프카는 크래시가 나더라도 메시지의 지속성을 유지함
- 주요 특징 - cf) https://fordevelop.tistory.com/248#6.3-%EB%B3%B5%EC%A0%9C
- 카프카 토픽은 파티션으로 이루어지고, 하나의 파티션은 하나의 디스크에 저장됨
- 카프카는 파티션에 저장된 이벤트들의 순서를 보장하며, 파티션은 온라인/오프라인 상태일 수 있음
- 각 파티션은 다수의 레플리카를 가질 수 있고, 그중 하나가 리더가 됨
- 모든 이벤트들은 리더 레플리카에 쓰여지며 (대체로) 리더 레플리카에서 읽혀짐
- 참고) 카프카 프로듀서와 브로커의 rack 설정 시 팔로워 레플리카에서 읽어올 수도 있음
- 다른 레플리카들은 단순히 리더와 동기화를 맞추며 최신 이벤트를 제 시간에 복사해오기만 하면 됨
- 만약 리더가 작동 불가 상태가 되면, 인-싱크 레플리카 중 하나가 새 리더가 됨
Q. 인-싱크 레플리카의 기준은 무엇일까?
- 해당 레플리카가 파티션의 리더 레플리카이거나 아래의 조건을 만족하는 팔로워 레플리카인 경우 인-싱크 상태인 것으로 간주함
- 주키퍼와의 활성 세션이 있다. 즉, 최근 6초 사이(설정에 따라 다름)에 주키퍼로 하트비트를 전송했다.
- 최근 10초 사이(설정에 따라 다름) 리더로부터 메시지를 읽어 왔다.
- 최근 10초 사이에 리더로부터 읽어 온 메시지들이 가장 최근 메시지이다.
- 팔로워가 리더로부터 메시지를 받고 있는 것만으로는 부족함
- 최근 10초 사이 랙(지연)이 없었던 적이 최소 한 번은 있어야 함
- 위 조건을 충족하지 못하는 경우 레플리카는 아웃-오브-싱크 상태로 간주됨 (동기화가 풀린 상태)
- 주키퍼와 다시 연결되어 리더 파티션에 쓰여진 가장 최근 메시지까지를 따라잡으면 다시 인-싱크 레플리카가 됨
7.3 브로커 설정
- 메시지 저장 신뢰성 관련한 브로커의 설정 매개변수 알아보기
- 브로커 단위 혹은 토픽 단위로 설정 가능함
- 토픽 단위 제어를 통해 동일한 카프카 클러스터 내 신뢰성이 필요한 토픽과 아닌 토픽을 같이 저장할 수 있음을 의미함
7.3.1 복제 팩터
- 요약하면,
- 파티션 단위로 얼만큼의 복제본을 만들 것인가
- 브로커 단위 설정: default.replication.factor, 토픽 단위 설정: replication.factor
- 특징
- 복제 팩터 변경 가능함
- 이미 존재하는 토픽에 대해 카프카의 레플리카 재할당 툴을 사용해 레플리카를 추가하거나 삭제할 수 있음
- 복제 팩터가 제공하는 가용성과 하드웨어 사용량 사이에는 트레이드 오프가 존재함
- 복제 팩터가 N이면 N-1개의 브로커가 중단되더라도 토픽의 데이터를 읽거나 쓸 수 있음
- (+) 복제 팩터가 클수록 가용성과 신뢰성이 증가하고 장애가 발생할 가능성은 감소함
- (-) 최소한 N개의 브로커가 필요하고, N개의 복사본을 저장해야 하므로 N배의 디스크 공간이 필요함
- 복제 팩터 변경 가능함
Q. 토픽에 몇 개의 레플리카가 적절할까?
- 아래의 사항들을 고려해야 함
- 가용성
- 레플리카가 하나뿐인 파티션은 정기적으로 브로커를 재시작하기만 해도 사용 불가능해짐
- 레플리카 수가 많을수록 가용성은 늘어남
- 지속성
- 각 레플리카는 파티션 안의 모든 데이터의 복사본
- 만약 파티션에 레플리카가 하나뿐이고 디스크가 사용 불가능하게 될 경우 해당 파티션의 모든 데이터는 유실됨
- 복사본이 많을수록 모든 데이터가 유실될 가능성은 줄어듦
- 처리량
- 레플리카가 추가될 때마다 브로커간 트래픽은 증가함
- 메시지를 모든 레플리카에 써야 하므로 복제 트래픽 증가
- 클러스터의 크기와 용량을 산정할 때 고려해야 함
- 레플리카가 추가될 때마다 브로커간 트래픽은 증가함
- 종단 지연
- 컨슈머가 메시지를 읽으려면 모든 인-싱크 레플리카에 복제되어야 함
- 비용
- 더 많은 레플리카를 가질수록 저장소와 네트워크에 들어가는 비용 역시 증가함
- 가용성
- 추가) 레플리카의 위치 역시 매우 중요
- 같은 파티션의 모든 레플리카들이 같은 랙에 설치되어 있는 브로커들에 저장되었고 랙 스위치가 오작동할 경우, 복제 팩터와는 상관없이 해당 파티션은 사용할 수 없게 됨
- 랙 단위 사고를 방지하기 위해 브로커들을 서로 다른 랙에 배치한 뒤 broker.rack 브로커 설정 매개변수에 랙 이름을 설정하는 것을 권장함
- 랙 이름 설정 시 카프카는 파티션의 레플리카들이 서로 다른 랙에 분산되어 저장되도록 하여 가용성을 높임
- 클라우드 환경에서 운영중일 경우, 가용 영역(availability zone)을 랙과 비슷한 개념으로 사용함
- 참고 - https://fordevelop.tistory.com/257#6.5.2-%ED%8C%8C%ED%8B%B0%EC%85%98-%ED%95%A0%EB%8B%B9
7.3.2 언클린 리더 선출
- 요약하면,
- 언클린 리더 선출이란? --> 아웃-오브-싱크 레플리카를 리더로 선출하는 것
- 즉, 기존 리더 레플리카를 제외한 인-싱크 레플리카가 없는 상황에서 아웃-오브-싱크 레플리카를 리더로 선출할 것인지를 결정함
- 고려사항
- 아웃-오브-싱크 레플리카가 리더가 될 수 있도록 허용할 경우 : 데이터 유실과 일관성 깨짐의 위험성 존재
- 무조건 발생하는 것은 아님. 아래 나올 min.insync.replicas 값을 높게 잡아두면 방지할 수도 있음
- 허용하지 않을 경우 : 원래 리더가 복구되는 것을 기다려야 하므로 가용성 줄어듦
- 아웃-오브-싱크 레플리카가 리더가 될 수 있도록 허용할 경우 : 데이터 유실과 일관성 깨짐의 위험성 존재
- 설정: unclean.leader.election.enable, default: false
- 클러스터 단위에서만 가능
- 클린한 리더 선출이란? --> 인-싱크 레플리카 중 하나를 리더로 선출하는 것
- 파티션의 리더가 더 이상 사용 가능하지 않을 경우 인-싱크 레플리카 중 하나가 파티션의 새 리더가 됨
- 커밋된 데이터에 아무런 유실이 없음을 보장한다는 점에서 이러한 리더 선출을 '클린'하다고 부름
- 커밋된 데이터 정의 자체가 모든 인-싱크 레플리카에 존재하는 데이터이기 때문
Q. 작동 불능에 빠진 리더 레플리카 외에 인-싱크 레플리카가 없다면 어떻게 해야할까?
- 발생 케이스 2가지 (리더 제외한 나머지가 모두 아웃-오브-싱크 레플리카가 되는 경우)
- 팔로워 레플리카가 모두 작동 불가능할 때
- 이 경우 프로듀서는 리더에 쓰기 작업을 계속할 것이고 모든 메시지는 커밋되고 응답이 간다. (리더가 유일한 인-싱크 레플리카이기 때문)
- 이후 리더 레플리카를 사용할 수 없게 되었고, 이 상황에서 아웃-오브-싱크 레플리카 중 하나가 먼저 시작 되면, 파티션의 유일한 사용 가능한 레플리카는 아웃-오브-싱크 레플리카가 된다.
- 팔로워 레플리카의 복제 작업이 뒤쳐졌을 때
- 네트워크 문제가 발생해 팔로워 레플리카들의 복제 작업이 뒤쳐질 수 있다.
- 복제 작업은 계속 수행되지만, 더이상 인-싱크 상태는 아님
- 리더 레플리카는 유일한 인-싱크 레플리카로서 계속해서 메시지를 받는다.
- 이후 리더 레플리카를 사용할 수 없게 되면, 리더가 될 수 있는 레플리카는 아웃-오브-싱크 레플리카밖에 없다.
- 네트워크 문제가 발생해 팔로워 레플리카들의 복제 작업이 뒤쳐질 수 있다.
- 팔로워 레플리카가 모두 작동 불가능할 때
- 결정 2가지
- 리더 레플리카가 복구될 때까지 기다리기
- unclean.leader.election.enable=false로 설정했을 때 적용되는 방식
- 리더가 복구될 때까지 해당 파티션은 오프라인 상태가 된다.
- 아웃-오브-싱크 레플리카를 리더로 선정하기
- unclean.leader.election.enable=true로 설정했을 때 적용되는 방식
- 아래 2가지 문제를 감수해야 한다.
- 메시지 유실
- 해당 레플리카가 동기화를 못한 사이 예전 리더에 쓰여졌던 모든 메시지들은 유실됨
- 컨슈머 입장에서 메시지 일관성 깨짐
- 동일한 오프셋에 대해 새 리더에 쓰여진 메시지와 예전 리더에 쓰여진 메시지가 다를 수 있음 (위의 메시지 유실 때문에)
- 일부 컨슈머들은 새 리더에 쓰여진 메시지를 읽게 되고, 일부는 예전 리더에 쓰여진 메시지를 읽었을 수 있고, 일부는 뒤섞인 채로 읽게 될 수 있음
- 메시지 유실
- 리더 레플리카가 복구될 때까지 기다리기
7.3.3 최소 인-싱크 레플리카
- 요약하면,
- 최소 인-싱크 레플리카 수를 충족하는 파티션에만 쓰기가 가능함
- 충족하지 못하는 경우 쓰기는 할 수 없고 읽기만 가능함
- 언클린 리더 선출 시 발생할 수 있는 메시지 유실, 일관성 깨지는 것 방지하기 위함
- 설정: min.insync.replicas, default: 1
- 최소 인-싱크 레플리카의 수를 충족하는 파티션에만 메시지 쓰기가 가능하게 하는 것
- 충족하지 못하는 경우 쓰기는 할 수 없고 읽기만 가능함
예시)
- 토픽에 레플리카 3개 존재, min.insync.replicas=2 설정
- 프로듀서들은 3개의 레플리카 중 최소 2개가 인-싱크 상태인 파티션에만 쓸 수 있다.
- 만약 3개 중 2개의 레플리카가 아웃-오브-싱크가 되면, 해당 파티션은 더 이상 쓰기 요청을 받을 수 없다.
- 프로듀서는 NotEnoughReplicasException 수신
- 대신 컨슈머는 계속해서 파티션에 존재하는 데이터를 읽을 수는 있다. (해당 레플리카는 읽기 전용이 됨)
- 이를 통해 언클린 리더 선출이 발생했을 때 메시지 유실 및 일관성 깨지는 것을 방지할 수 있다.
- 읽기 전용 상태에서 회복하려면, 최소 인-싱크 레플리카 수를 충족할 때까지 기다려야 한다.
7.3.4 레플리카를 인-싱크 상태로 유지하기
- 레플리카가 out-of-sync 상태가 될 수 있는 두 가지 이유
- 주키퍼와의 연결이 끊어졌을 때
- 리더 업데이트 내역을 따라가는 데 실패해서 복제 렉이 발생했을 때
- 카프카는 위 두 조건에 대한 카프카 클러스터의 민감도를 조절할 수 있는 브로커 설정 제공
- zookeeper.session.timeout.ms
- 카프카 브로커가 주키퍼로 하트비트를 전송을 멈출 수 있는 최대 시간
- 해당 간격 안에만 하트비트를 보내면 주키퍼는 브로커가 죽었다고 판단하지 않음
- 카프카 버전 2.5.0부터 default 값 6초 -> 18초로 증가
- 네트워크 지연의 변동폭이 큰 클라우드 환경에 설치된 카프카 클러스터의 안정성 증대시키기 위함
- GC나 네트워크 상황과 같은 무작위적인 변동에 영향을 받지 않을 만큼 높게, 하지만 실제로 작동이 멈춘 브로커가 적시에 탐지될 수 있을 만큼 충분히 낮게 설정되어야 함
- 카프카 브로커가 주키퍼로 하트비트를 전송을 멈출 수 있는 최대 시간
- replica.lag.time.max.ms
- 팔로워 레플리카가 리더로부터 데이터를 읽어오지 못하거나, 리더에 쓰여진 최신 메시지를 따라잡지 못해도 인-싱크 상태로 유지될 수 있는 최대 시간
- 카프카 버전 2.5.0부터 default 10초 -> 30초로 조정
- 클러스터의 회복 탄력성을 증대시키고 불필요한 변동을 피하기 위함
- 해당 값은 컨슈머의 최대 지연에도 영향을 줌
- 즉, 메시지가 모든 레플리카에 도착해서 컨슈머가 이 메시지를 읽을 수 있게 되는 데 최대 30초가 걸릴 수 있음
- 컨슈머는 커밋된 메시지만 읽을 수 있기 때문 (커밋 기준 = 모든 인-싱크 레플리카에 메시지가 쓰여졌을 때)
- zookeeper.session.timeout.ms
7.3.5 디스크에 저장하기
- 카프카는 세그먼트를 교체할 때(기본값: 1GB)와 재시작 직전에만 메시지를 디스크로 플러시함
- 그 외의 경우 리눅스의 페이지 캐시 기능에 의존함(페이지 캐시 공간이 다 찼을 경우에만 메시지를 플러시 하는 것)
- 브로커가 디스크에 더 자주 메시지를 저장하도록 설정하는 것도 가능함
- flush.messages : 디스크에 저장되지 않은 최대 메시지 수
- flush.ms : 얼마나 자주 디스크에 메시지를 저장하는지
7.4 신뢰성 있는 시스템에서 프로듀서 사용하기
- 카프카 브로커에 사용 가능한 가장 높은 신뢰성 설정을 적용하더라도, 프로듀서 역시 신뢰성이 있도록 설정해주지 않으면 시스템 전체로서는 여전히 데이터가 유실될 수 있음
신뢰성 있는 프로듀서 설정
- 신뢰성 요구 조건에 맞는 올바른 acks 설정 사용
- 설정과 코드 모두에서 올바른 에러 처리
프로듀서의 데이터 유실 상황
- 프로듀서의 acks=1 설정
- 브로커 설정
- 토픽별로 3개의 레플리카를 가지도록 설정, 언클린 리더 선출 off
- 이렇게 되면 카프카 클러스터에 커밋된 메시지는 유실되지 않음
- 프로듀서 설정
- 메시지를 보낼 때 acks=1 설정
- 상황
- 프로듀서에서 메시지를 전송해서 리더에는 쓰여졌지만, 아직 인-싱크 레플리카에 반영되지 않은 상태
- 리더가 프로듀서에게 성공 응답을 보낸 직후 리더에 크래시가 나서 데이터가 인-싱크 레플리카로 복제되지 못함
- 다른 레플리카들은 여전히 인-싱크 상태로 간주되기 때문에, 그중 하나가 리더가 됨
- 메시지가 레플리카에 쓰여지지 않은 만큼 해당 메시지는 유실됨
- 프로듀서 입장에서는 메시지가 유실된 것
- 브로커 설정
- 프로듀서의 올바르지 않은 에러 처리
- 브로커 설정
- 토픽별로 3개의 레플리카를 가지도록 설정, 언클린 리더 선출 off
- 프로듀서 설정
- 메시지를 보낼 때 acks=all 설정
- 상황
- 카프카에 메시지를 쓰려고 하는데, 대상 파티션의 리더 브로커가 크래시가 나서 새 리더는 아직 선출중인 상태
- 카프카는 "Leader not Available" 응답 보냄
- 프로듀서가 올바르게 에러를 처리하지 않고 쓰기가 성공할 때까지 재시도 하지 않을 경우, 메시지가 유실될 수 있음
- 브로커 설정
7.4.1 응답 보내기
- 프로듀서는 세 가지 응답(acknowledgement) 모드 중 하나를 선택할 수 있음
- https://fordevelop.tistory.com/238#3.4.2-acks
7.4.2 프로듀서 재시도 설정하기
- 프로듀서의 에러 처리는 두 부분으로 나누어짐
- 프로듀서가 자동으로 처리해주는 에러
- 개발자들이 처리해야 하는 에러
- 프로듀서는 재시도 가능한 에러에 대해 자동으로 처리할 수 있음
- Q. 재시도 가능한 에러인지 어떻게 판별할까?
- 브로커의 응답 코드 사용
- 프로듀서가 브로커에 메시지를 전송하면 브로커는 성공 or 에러 코드를 리턴함
- 에러 코드는 두 부류로 나뉘어짐
- 전송을 재시도하면 해결될 수 있는 것 ex) LEADER_NOT_AVAILABLE
- 전송을 재시도해도 해결될 수 없는 것 ex) INVALID_CONFIG
- Q. 재시도 가능한 에러인지 어떻게 판별할까?
- 메시지가 유실되지 않는 것이 목표일 경우, 가장 좋은 방법은 재시도 가능한 에러가 발생했을 때 프로듀서가 계속해서 메시지 전송을 재시도하도록 설정하는 것
- 권장
- 재시도 수를 기본 설정값(MAX_INT, 사실상 무한)
- 메시지 전송을 포기할 때까지 대기할 수 있는 시간을 지정하는 delivery.timeout.ms 설정값을 최대로 잡음
- 즉, 프로듀서가 이 시간 간격 내에 메시지 전송을 계속해서 재시도 하도록 함
- 권장
- 주의) 메시지 전송 재시도로 인해 결과적으로 메시지가 중복 저장될 수 있음
- 각 메시지가 '최소 한 번' 저장되도록 보장하지만, '정확히 한 번'은 보장하지 않음
- enable.idempotence=true 설정하여 프로듀서가 추가적인 정보를 레코드에 포함할 수 있도록 하고, 이를 활용해 브로커가 재시도로 인해 중복된 메시지를 건너뛸 수 있도록 할 수 있음
7.4.3 추가적인 에러 처리
- 프로듀서가 재시도 불가능한 에러에 대해서는 수동 에러 처리가 필요함
- 예시)
- 메시지 크기에 관련되었거나 인가 관련 에러와 같이 재시도 불가능한 브로커 에러
- 메시지가 브로커에 전송되기 전에 발생한 에러 (ex. 직렬화 에러)
- 프로듀서가 모든 재전송 시도를 소진했거나, 재시도 과정에서 프로듀서가 사용하는 가용 메모리가 메시지로 가득 차서 발생하는 에러
- 타임아웃
- 예시)
- 어플리케이션의 조건에 따라 적절한 방식을 선택해야 함
7.5 신뢰성 있는 시스템에서 컨슈머 사용하기
- 컨슈머가 해야 할 일은 어느 메시지까지 읽었는지 추적하는 것. 이는 메시지를 읽는 도중에 누락되지 않게 하기 위해서 필수적임
- 이를 위해 컨슈머는 메시지의 오프셋을 커밋함
- 이를 통해 해당 컨슈머나 다른 컨슈머가 재시작한 뒤에도 어디서부터 작업을 계속해야 할지 알 수 있음
- 컨슈머가 메시지를 누락할 수 있는 경우는 메시지를 읽기는 했지만 아직 처리가 완료되지 않은 이벤트들의 오프셋을 커밋하는 경우
- 오프셋이 언제 어떻게 커밋되는지에 대해 신경써야 함
7.5.1 신뢰성 있는 처리를 위해 중요한 컨슈머 설정
- group.id
- 동일한 group.id를 갖는 컨슈머들은 동일한 컨슈머 그룹에 속함
- 참고) 카프카 컨슈머 > 컨슈머와 컨슈머 그룹
- auto.offset.reset
- 커밋된 오프셋이 없을 때(컨슈머가 처음 시작한 경우)나 컨슈머가 브로커에 없는 오프셋을 요청할 때 컨슈머가 어떻게 해야 할지 결정함 (latest, earliest, none)
- 참고) https://fordevelop.tistory.com/242#4.5.10-auto.offset.reset
- enable.auto.commit
- 일정한 시간에 맞춰 컨슈머가 자동으로 오프셋을 커밋하게 할 것인지 or 코드에서 직접 오프셋을 커밋할 것인지 결정함
- 특징
- 잘못된 오프셋을 커밋하는 사태를 방지해줌
- 메시지 중복 처리 발생 가능함
- 어플리케이션 백그라운드에서 메시지 처리를 수행하기 위해 다른 스레드에 레코드를 넘기는 것과 같이 복잡한 처리를 해야 할 경우, 자동 커밋보다는 직접 오프셋을 커밋해주는 것이 적절함. 자동 커밋 기능이 컨슈머가 읽어오기는 했지만 아직 처리하지 않은 오프셋을 커밋할 수도 있기 때문
- 참고) 카프카 컨슈머 > 자동 커밋
- auto.commit.interval.ms
- 오프셋을 자동 커밋할 경우, 커밋되는 주기 설정함 (default: 5초)
- 더 자주 커밋할수록 오버헤드는 늘어나지만, 컨슈머가 멈췄을 때 발생할 수 있는 중복의 수는 줄어듦
추가) 빈번한 리밸런싱
- 데이터 처리의 신뢰성과 직접적으로 연관된 것은 아니지만, 컨슈머가 리밸런스 수행을 위해 자주 멈추면 신뢰성이 있다고 하기 어려움
- 불필요한 리밸런싱과 리밸런싱이 발생했을 때의 멈춤을 최소화하는 방안도 고려해야 함
- 불필요한 리밸런싱 최소화 : 카프카 컨슈머 > 정적 그룹 멤버십
- 리밸런싱이 발생했을 때의 멈춤 최소화 : 카프카 컨슈머 > 협력적 리밸런스
7.5.2 컨슈머에서 명시적으로 오프셋 커밋하기
고려해야 할 중요 사항
- 커밋 빈도는 성능과 중복 개수 사이의 트레이드오프다
- 커밋 작업은 상당한 성능 오버헤드를 수반함
- 커밋 주기는 성능과 중복 발생의 요구 조건 사이에서 균형을 맞춰야 함
- 정확한 시점에 정확한 오프셋을 커밋하자
- 처리가 완료된 메시지의 오프셋을 커밋해야 함 (읽기는 했지만 처리되지 않은 메시지의 오프셋 커밋 시 메시지 누락 발생)
- 컨슈머는 재시도를 해야 할수도 있다
- poll()을 호출하고 레코드를 처리하는 도중 예외가 발생해 일부 레코드는 처리가 완료되지 않아 나중에 처리되어야 할 수 있음
- 방식
- 동기 방식 재시도
- 재시도 가능한 에러가 발생했을 경우 마지막으로 처리에 성공한 레코드의 오프셋을 커밋함
- 나중에 처리해야 할 레코드들을 버퍼에 저장하고, 컨슈머의 pause() 메서드를 호출해 추가적인 poll() 호출이 데이터를 리턴하지 않도록 한 뒤, 레코드 처리를 계속함
- 비동기 방식 재시도
- dead-letter-queue 방식
- 별도의 재시도 토픽에 메시지를 발행한 뒤 기존 메시지 처리는 계속 진행함
- 동기 방식 재시도
- 컨슈머가 상태를 유지해야 할 수도 있다
- poll() 메서드 호출 간에 상태를 유지해야 할 수도 있음
- 예시)
- 이동평균 계산을 위해 카프카에서 새 메시지를 폴링해 올 때마다 평균값을 업데이트 해줘야 함
- 컨슈머가 재시작되면, 중복된 메시지에 의한 이동평균값을 복구시켜야 함
- 예시)
- poll() 메서드 호출 간에 상태를 유지해야 할 수도 있음
'Study > 카프카 핵심 가이드' 카테고리의 다른 글
[카프카] 카프카는 어떻게 고성능을 유지할까? (0) 2025.03.24 [카프카 핵심 가이드] CH6. 카프카 내부 메커니즘 - 물리적 저장소 (0) 2025.03.08 [카프카 핵심 가이드] CH6. 카프카 내부 메커니즘 (0) 2025.02.19 [카프카 핵심 가이드] CH4. 카프카 컨슈머: 카프카에서 데이터 읽기 (2) (1) 2025.02.13 [카프카 핵심 가이드] CH4. 카프카 컨슈머: 카프카에서 데이터 읽기 (1) (0) 2025.02.11