Apache Kafka - Replica Recovery
Replica Recovery
acks=all의 중요성
- 위의 그림은 Partition이 하나 있고 Replica가 3개로 구성되어있고
Leader X, Follower Y, Follower Z는 모두 ISR리스트에 들어가 있고
Producer는 메시지(M1,M2,M3,M4)를 보낼 때 acks=all, retires=MAX_INT, enable.idempotence=false 옵션을 사용한 그림이다.
- 현재 M1,2,3,4가 Leader X에 들어왔다.
- Follwer Y는 M1,2까지는 복제하고 Commit까지 완료한 상태고 M3은 복제는 했지만 Commit은 못한 상태다.
- Follower Z는 M1,2를 복제하고 Commit한 상태다.
이 때 Broker X에 장애가 발생한다면?
- Controller가 Y를 Leader로 선출했다고 가정해보자.
- Leader가 새로 선출되었기 때문에 Leader Epoch가 0에서 1로 증가했다.
- Follower Z는 M3를 fetch 한다.
- Leader Y는 High Wark Mark를 진행시킨다.
- Follower Z는 다시 fetch를 수행하여 High Water Mark를 수신하고 진행시킨다.
Question) M3는 Commit 된적이 없는데 왜 Y는 M3를 가지고 있을 수 있는가?
- Apache Kafka는 Leader로 선정된 Partition에 있는 데이터를 지우지 않는다.
- Broker X는 M3,M4에 대한 ack를 Producer에게 보내지 못한다. (acks=all이였기 때문)
- Producer는 retris에 의해 M3,M4를 다시 보낸다.
- idempotence=false(순서보장옵션)이므로 Leader Y에 M3가 중복으로 발생한다.
- Follower Z는 M3(중복),M4를 다시 fetch한다.
- Follower Z는 fetch를 다시 수행하고 High Water Mark를 수신하고 진행시킨다.
만약 acks=1이었다면?
- Leader X가 장애가 일어나면서 Follower Y,Z는 M4를 복제하지 못한 상태다.
- 하지만 Leader X가 장애가 발생하기 전에 Producer는 이미 M4에 대한 ack를 수신했다.
- Y가 Leader로 선출되면서 Leader Epoch가 0에서 1로 증가한다.
- Follower Z는 M3를 fetch 한다.
- Follower Z는 fetch를 다시 수행하고 High Water Mark를 수신하고 진행시킨다.
- 하지만 Producer가 M4 송신을 retry 하지 않게 되므로 M4는 영원히 잃어버리게 되는 결과를 초래하게 된다.
장애가 발생했던 X가 복구된다면?
- Follwer X가 복구되면 Zookeeper에 연결된다.
- Follower X는 Controller로 부터 Metadata 정보를 받는다.
- Follower X는 Leader Y로부터 Leader Epoch를 fetch 한다.
- Follower X는 Leadership이 변경된 시점부터 Truncate 한다.
- Follower X는 Leader Y를 fetch 한다.
- Follower X는 fetch를 다시 수행하고 High Water Mark를 수신하고 진행시킨다.
- 이렇게 한번 복제가 일어나면 다시 ISR 리스트에 복귀하게 된다.
Availability And Durability
- Topic Parameter : unclean.leader.election.enable
- ISR 리스트에 없는 Replica를 Leader로 선출할 것인지에 대한 옵션 (default : false)
- ISR 리스트에 Replica가 하나도 없으면 Leader를 선출하지 않는다. - 서비스 중단
- ISR 리스트에 없는 Replica를 Leader로 선출한다. - 데이터 유실
- Topic Parameter : min.insync.replicas
- 최소 요구되는 ISR의 개수에 대합 옵션 (default : 1) (보통 2로 많이씀)
- ISR이 min.insync.replcias 보다 적을 경우 Producer는 NotEnoughReplicas 예외를 수신하게 된다.
- Producer에서 acks=all과 함께 사용할 때 더 강력하게 보장한다. + min.insync.replicas=2
- n개의 Replica가 있고, min.insync.replicas=2인 경우 n-2개의 장애를 허용할 수 있다.
가용성과 내구성 중 선택은?
- 데이터 유실이 없게 하려면?
- Topic: replication.factor는 2보다 커야한다. (최소 3이상)
- Producer: acks는 all이어야 한다.
- Topic: min.insync.replicas는 1보다 커야한다. (최조 2이상)
- 데이터 유실이 다소 있더라도 가용성을 높게 하려면?
- Topic: unclean.leader.election.enable를 true로 설정한다.
요약
- replication.factor
- acks
- min.insync.replicas
- unclean.leader.election.enable