언젠가 면접에서 카프카 사용시 메시지가 유실될 수 있을까? 만약 유실될 수 있다면 언제 유실될 수 있을까? 라는 질문을 받은적이 있다. 당시 질문에 대답을 잘 못했는데, 카프카를 통신수단 이상으로 생각하지 않기도 했고 카프카 그 자체에 대해서는 잘 몰랐기 때문이었다. (지금도 잘모르지만)
그렇다면, 카프카 사용시 메시지는 유실될 수 있을까? 한번 알아보려고 한다.
복제
https://pius712.tistory.com/16
위 포스트에서 설명했듯, 카프카에서 토픽의 파티션은 리더와 팔로워로 나뉘게 된다.
카프카는 일반적으로 내결함성을 위해서 여러개의 브로커가 클러스터를 이루고, 리더와 팔로워는 각 브로커에 나뉘어 할당하게 된다. 프로듀서와 컨슈머는 리더와 통신을 하고 해당 데이터를 팔로워에 복제함으로써, 장애시에 내결함성을 가지게 된다.
복제는 리더에 기록된 레코드의 오프셋과 팔로워에 기록된 레코드에 차이가 발생하게 되면, 리더에 추가된 레코드만큼을 팔로워가 가져가는 것을 의미한다.
만약 동기화가 되지 않은 상태에서, 리더 파티션이 속한 브로커에 장애가 난다면 어떻게 될까?
이때는 unclean.leader.election.enable 설정마다 다르게 동작한다.
- unclean.leader.election.enable: true → 장애 복구까지 기다림
- unclean.leader.election.enable: false → 동기화되지 않은 채로 새로운 리더를 선출함.
위와 같이 복제 메커니즘에 의해 바로 메시지 유실 가능성이 생길 수 있는 것인데, 아래에서 조금 더 자세히 살펴보겠다.
ISR(In-Sync Replicas)
ISR 이란 리더와 동기화된 상태인 복제본의 리스트이다. 카프카에서는 리더 파티션의 데이터가 팔로워 파티션에 복제가 완료되어 동기화된 상태를 In-Sync 라고 하며, In-Sync 상태인 Replica 의 집합을 ISR 이라고 부르는 것이다.
acks 옵션
kafka producer 에는 acks 옵션이 있다. acks 는 리더 파티션이 프로듀서의 요청에 응답을 줄 때, 리더의 데이터가 팔로워에 복제된 수를 설정하는 옵션이다.
- acks=0 : 프로듀서가 서버로 부터 아무런 응답을 받지 않아도 성공으로 간주한다.
- acks=1 : 프로듀서가 리더에 데이터가 쓰였으면 성공 응답을 한다.
- acks=all: 리더가 ISR에 데이터가 동기화될 때까지 기다렸다가 응답을 준다.
min.insync.replicas 설정
위의 acks=all 설정에서 의문점이 생길 수 있다. 바로 “acks=all 일때, 브로커가 100개면 100개 모두 기다리나요?” 처럼, 모든 브로커에 복제될 때까지 기다리는가 하는 것인데, 상식적으로 네트워크 비용을 생각하면 그렇지 않을 것처럼 보이고, 실제로도 그렇다.
해당 옵션은 acks 옵션이 acks=all 로 설정되어있을 때 동작하는데, 복제가 성공적으로 이루어졌다 라고 판단되는 ISR 리스트의 최소 숫자이다.
아래의 그림을 예로 살펴보자.
- replication factor: 4
- acks=all
- min.insync.replicas=2
만약 위와 같이 설정이 되어있다면, 리더 파티션이 브로커 3에 복제를 실패한다고 하여도 브로커 4에 복제가 성공하기 때문에, ISR 의 수는 2개 (브로커 2, 브로커 4)이다. min.insync.replicas 설정이 2로 되어있기 때문에, 리더는 프로듀서에게 성공했다는 응답을 하게 된다.
메시지 유실 시나리오
case1. acks=0
acks=0 인 경우, 프로듀서가 소켓에 해당 레코드를 쓰고난 이후에 성공했다고 가정하기 때문에 실제로 성공했는지 실패했는지 알 수가 없다. 네트워크 이슈 혹은 리더 파티션이 속한 브로커의 이슈로 인해 전송에 실패하였더라도 알 수가 없다. 이 경우 메시지 유실이 가능하다.
case2. acks=1
acks=1 인 경우, 리더 파티션에만 데이터가 저장된 상태이다. 만약 아래처럼, 브로커 1의 리더가 브로커 2의 팔로워에게 복제되지 않은 상태에서 브로커1에 장애가 발생하는 경우 메시지 유실이 가능하다.
acks=all 은 유실 없나요?
위에서 살펴본 것처럼 acks=all 이라고 하더라도, min.insync.replicas 옵션에 의해서 실제 ISR 의 수가 달라지게 된다. 그렇기 때문에, 만약 acks=all 인데, min.insync.replicas=1 이면 case2 와 동일하다.
그 외에도, 가능성은 없지만 acks=all 은 모든 팔로워에 복제하는 것이 아니기 때문에 min.insync.replicas 에는 복제가 완료되었지만 해당 브로커가 모두 죽고 나머지 브로커가 승격되는 경우에 메시지 유실이 발생할 수는 있다.
'카프카' 카테고리의 다른 글
카프카 톺아보기 3-1. 컨슈머 개념 (1) | 2024.05.30 |
---|---|
카프카 톺아보기2 - CLI (0) | 2024.05.30 |
카프카 컨슈머 lock 삽질기 - 리밸런싱 (0) | 2024.02.26 |
카프카 톺아보기 - 기본개념 (0) | 2024.02.25 |