In-Sync Replicas 리스트 관리
- Leader가 관리한다.
- 메시지가 ISR 리스트의 모든 Replica에서 수신되면 Commit된 것으로 간주한다.
- Kafka Cluster의 Controller가 모니터링하는 ZooKeeper의 ISR 리스트에 대한 변경 사항은 Leader가 관리한다.
- Follower가 실패하는 경우, Leader에 의해 ISR 리스트에서 삭제되고 Leader는 새로운 ISR을 사용하여 Commit한다.
- (1)에서 replica.lag.time.max.ms 이내에 Follower가 fetch하지 않으면, ISR에서 제거한다.
- Broker 1이 ZooKeeper에게 ISR 변경을 알린다.
- ZooKeeper는 Partition Metadata에 대한 변경 사항을 Controller에 전달한다.
- Leader가 실패하는 경우, Controller는 Follower 중에서 새로운 Leader를 선출하고 새 Leader와 ISR 정보를 먼저 ZooKeeper에 Push한 다음, 로컬 캐싱을 위해 Broker에 Push한다.
- ZooKeeper가 session timeout을 통해서 Leader Broker의 장애를 감지한다.
- Controller가 새로운 Leader를 선출하고 새로운 ISR 리스트를 ZooKeeper에 기록한다.
- Controller가 모든 Broker에게 새로운 ISR 정보를 Write한다.
- Client는 메타 데이터를 요청하여 새로운 Leader 정보를 받는다.
Broker Failure
* 상황: Broker 4대, Partition 4, Replication Factor 3
Partition 생성 시, Broker들 사이에서 Partition들이 분산하여 배치된다.
Partition 3의 경우 Leader가 죽었기 때문에, Broker 1, Broker 2에 존재하는 Follower Partition 중 하나가 새로운 Leader로 선정된다.
* Partition에 Leader가 없으면, Leader가 선출될 때까지 해당 Partition을 사용할 수 없게 된다.
* Producer의 send()는 retries 파라미터가 설정되어 있으면 계속 재시도를 하지만, 데이터는 전송될 수 없다.
* retries = 0인 경우, NetworkException이 바로 발생한다.
Replica Recovery
* 상황 1: acks = all
Leader Partition 0에 장애가 발생하면, 여기서는 Partition 1이 새로운 Leader로 선정되었다고 가정한다. (Partition 1의 M3 데이터는 Commit 전 상태이다.)
- M3, M4를 Commit 하기 전에 Partition 0에 장애가 발생
- Partition 1이 새로운 Leader로 선출 -> Leader Epoch가 0에서 1로 증가한다.
- Partition 2는 M3를 fetch한다.
- Partition 1은 High Water Mark를 진행한다.
- Partition 2는 fetch를 다시 수행하고 High Water Mark를 수신하고 진행한다.
- Producer는 M3, M4에 대한 ACK를 미수신한 상태이므로 M3, M4 송신을 재시도한다.
- idempotence=false이므로, Partition 1에서 M3는 중복된다.
- Partition 2는 M3, M4를 fetch한다.
- Partition 2는 fetch를 다시 수행하고 High Water Mark를 수신하고 진행한다.
* Partition 0이 장애에서 복구된다.
- Partition 0이 복구되면 ZooKeeper에 연결
- Partition 0은 Controller로부터 metadata를 받는다.
- Partition 0은 Partition 1로부터 Leader Epoch를 fetch한다.
- Partition 0은 Leader가 변경된 시점부터 Truncate(이전 Commit 지점 이후의 데이터를 전부 삭제한다. M3, M4 데이터 삭제)
- Partition 0은 Partition 1로부터 데이터를 받아 M1, M2, M3, M3, M4 상태로 만들어진다.
- Partition 0이 ISR 조건에 만족하면 ISRs에 포함된다.
* 상황 2: acks = 1
Leader Partition 0에 장애가 발생하면, 여기서는 Partition 1이 새로운 Leader로 선정되었다고 가정한다. (Partition 1의 M3 데이터는 Commit 전 상태이다.)
- Partition 0에서 장애가 발생하기 전에 Producer는 M4에 대한 ACK를 수신
- Partition 1이 Leader로 선출된다. -. Leader Epoch가 0에서 1로 증가한다.
- Partition 2가 M3를 fetch한다.
- Partition 1은 High Water Mark를 진행한다.
- Partition 2는 fetch를 다시 수행하고 High Water Mark를 수신하고 진행한다.
- Producer는 M4에 대한 ACK를 받았으므로, M4 송신을 재시도하지 않아 M4 데이터는 유실된다.
* Availability와 Durability
가용성과 내구성 중 어느 것을 선택할 것인가?
** Topic 파라미터 - unclean.leader.election.enable: ISR 리스트에 없는 Replica를 Leader로 선출할 것인지에 대한 옵션(default: false)
해당 옵션이 false일 때, ISR 리스트에 아무 것도 존재하지 않는다면 Leader 선출을 하지 않는다. -> 서비스 중단으로 이어질 수 있다.
해당 옵션을 true로 설정하면, ISR 리스트에 없는 Replica도 Leader로 선출한다. -> 데이터 유실
** Topic 파라미터 - min.insync.replicas: 최소 요구되는 ISR의 개수에 대한 옵션(default: 1)
해당 옵션이 1이면, Leader는 반드시 ISR에 존재하므로 오류가 발생하지 않아 보통 2로 사용한다.
ISR이 min.insync.replicas보다 작은 경우, Producer는 NotEnoughReplicas 예외를 수신한다.
Producer에서 acks=all + min.insync.replicas=2로 사용하면 더 강력하게 보장한다.
즉, n개의 Replica가 존재하고, min.insync.replicas=2인 경우 n-2개의 장애까지 허용할 수 있다.
데이터 유실을 없게 Kafka를 사용하고자 한다면?
Topic: replication.factor는 2보다 커야 한다.(최소 3이상), min.insync.replicas는 1보다 커야 한다.
Producer: acks는 -1, all 이여야 한다.
데이터 유실이 다소 존재하더라도 가용성을 높게 하려면?
Topic: unclean.leader.election.enable를 true로 사용한다.
'Kafka' 카테고리의 다른 글
[Kafka] Kafka Log File (0) | 2022.10.15 |
---|---|
[Kafka] Partition Assignment Strategy (0) | 2022.10.14 |
[Kafka] Replication (1) (0) | 2022.10.12 |
[Kafka] Consumer (2) (0) | 2022.10.11 |
[Kafka] Consumer (1) (0) | 2022.10.10 |