Kafka Partition 복제
- Kafka 에서는 가용성을 위해 replication 을 제공한다. 이 때 kafka 에서 replication은 각 Topic 의 partition 들을 다른 브로커들로 복제하는 것을 말한다.
- topic 생성 시, replication 수를 지정할 수 있으며,
replication-factor
option 값을 지정하여 설정 (default.replication.factor = 1
)
- 이 때,
replication-factor
의 경우, broker(node) 수를 넘지 못한다.
- 이 때,
./bin/kafka-topics.sh --bootstrap-server localhost:9092 --replication-factor 3 --partitions 3 --topic sample --create
replication factor 를 높이게 될 때, 가용 노드가 모종의 이유로 줄어드는 경우, 다른 노드에도 동일한 partition 의 레플리카가 있기 때문에 가용성이 증가하는 것은 분명하다.
하지만 replication 수가 증가할수록 다른 노드간 복제를 위한 리소스 증가와 디스크 사용량이 증가한다는 트레이드오프를 분명히 인지하여, data 중요도에 따라 적절한 값을 조정해야한다.
보통 특별한 이유가 없다면 replication-factor
의 값을 3 으로 설정하는 것이 안정성 면에선 좋다.
Leader/Follower Partition & ISR (In Sync Replication)
위에서 설명한 바와 같이 partition 복제가 발생하는데, Kafka 도 다른 master/slave 구조와 같이 leader/follower 구조를 지니며
leader → follwer 방향으로 복제가 비동기으로 처리한다.
이러한 일관성을 유지하기 위해서, Kafka Producer/Consumer 는 늘 데이터의 원본(leader) 파티션을 타겟으로 produce/consume 이 일어난다.
만약 장애로 인해 leader partition 의 브로커가 중단되었을 때는 다른 follwer 파티션이 리더로 선정된다. 이 때 리더로 승격되는 follwer 파티션은 대부분 ISR(In Sync Replication) 에 속한 파티션에서 선출이 된다 (왜 보통이라 했는 지는 다른 예시를 통해 설명)
ISR(In Sync Replication) 은 정상적으로 복제를 보장하는 replication group 을 뜻한다.
앞서 설명한 바와 같이 리더와 팔로워간의 복제는 비동기로 동작하기 때문에, 일시적으로 두 파티션 간의 일관성이 깨질 수 있다. 이를 위해 ISR 개념이 kafka 에 도입되었다.
ISR 는 토픽/브로커 config 인 min.insync.replicas
를 통해 결정되며, producer 의 config 인 acks
와 연관이 깊다.
replication-factor
: topic 의 partition 복제본이 몇 개 생성하는 지에 대한 옵션min.insync.replicas
: 최소한의 리더 파티션의 동기화를 보장하는 레플리카 수를 지정하는 옵션 (리더 파티션도 해당 수에 포함된다는 것을 명심하자.)acks=<all(-1), 0, 1>
: producer 에서 보낸 메시지가 정상적으로 파티션에 작성되었는가 에 대한 설정- 이 때
all
인 경우 프로듀서는min.insync.replicas
설정 개수만큼의 파티션에 대한 write 응답을 대기해야함.
- 이 때
ISR 간 동기화는 Pull 방식으로 동작하며, Follwer 에서 leader 에게 fetch 요청을 보내고, Leader 에서 응답으로 follwer 에게 메시지를 전송한다.
- 이 때, Fetch 요청에 Follwer들이 다음 메시지의 offset 이 포함되며, 항상 수신 순서로 처리
위에서 잠시 언급한 브로커(노드) 중단의 경우 ISR 에 속하는 Follwer 파티션이 선출되는데,
Follwer replica 가 일정 시간 이상 Fetch 요청을 하지 않거나, 시간 내에 Leader 파티션의 마지막 offset 메시지 복제를 실패한다면, 동기화 실패로 Follwer 파티션은 ISR 에서 제거된다.
- 복제 실패 시간은
[replica.lag.time.max.ms]
를 통해 설정
ISR 설정은 broker level 혹은 topic level 모두 가능하다.
Broker Level ISR configuration
- broker level 에서 default value 는 1이다.
kafka config 중 config/server.properties
파일에 min.insync.replicas=2
다음과 같이 설정하거나,
cli command 를 통해 설정 가능하다.
kafka-configs.sh --bootstrap-server localhost:9092 --alter --entity-type brokers --entity-default --add-config min.insync.replicas=2
설정 확인 command
$ kafka-configs.sh --bootstrap-server localhost:9092 --describe --entity-type brokers --entity-default
Default configs for brokers in the cluster are:
min.insync.replicas=2 sensitive=false synonyms={DYNAMIC_DEFAULT_BROKER_CONFIG:min.insync.replicas=2}
min.insync.replicas
설정 제거
kafka-configs.sh --bootstrap-server localhost:9092 --alter --entity-type brokers --entity-default --delete-config min.insync.replicas
Topic Level ISR Configuration
Topic 이 이미 존재한다고 가정하고, min.insync.replicas
config 추가 cli command
kafka-configs.sh --bootstrap-server localhost:9092 --alter --entity-type topics --entity-name configured-topic --add-config min.insync.replicas=2
topic 정보 확인
kafka-topics.sh --bootstrap-server localhost:9092 --describe --topic configured-topic
Topic: configured-topic TopicId: CDU7SBxBQ1mzJGnuH68-cQ PartitionCount: 3 ReplicationFactor: 1 Configs: min.insync.replicas=2
Topic: configured-topic Partition: 0 Leader: 2 Replicas: 2 Isr: 2
Topic: configured-topic Partition: 1 Leader: 3 Replicas: 3 Isr: 3
Topic: configured-topic Partition: 2 Leader: 1 Replicas: 1 Isr: 1
설정 제거
kafka-configs.sh --bootstrap-server localhost:9092 --alter --entity-type topics --entity-name configured-topic --delete-config min.insync.replicas
Kafka Producer Acknowledgement(Ack)
위에서 잠시 나온 producer 의 ack
에 대해서 좀 더 보자.
해당 옵션의 설정은 acks=<all(-1), 0, 1>
3가지가 존재한다.
The default value of acks has changed with Kafka v3.0:
- if using Kafka < v3.0, acks=1
- if using Kafka >= v3.0, acks=all
acks = 0
- 리더 파티션이 메시지를 받으면 즉시 프로듀서에게 ack 메시지를 반환. (잘 수신했는 지 별도 확인이 없음)
- 메시지를 리더 파티션에 쓰기 직전에 브로커가 죽는다면 메시지 유실된다.
- 안정성은 낮지만, 프로듀서 입장에서는 네트워크 오버헤드가 가장 낮으므로 처리량을 높일 수 있음
acks = 1
- 리더 파티션에만 메시지를 잘 썼다면 ack 메시지를 반환.
- 리더 파티션에 메시지를 썼음을 보장할 수 있지만, 만약 리더 파티션이 위치한 브로커가 다운되는 경우 팔로워에는 복제가 되지 않았기 때문에 메시지 손실이 발생할 수 있음
- 세가지 옵션 중 처리량/안정성 면에서 중간 값
acks = all (-1)
min.insync.replicas
에 설정한 개수 만큼의 레플리카에 메시지를 쓴 경우에만 ack 응답- 다시 언급하지만 리더 파티션은 레플리카 개념에 포함된다.
replication.factor=N
이고min.insync.replicas=M
이면, N-M 개의 브로커가 다운되는 상황까지는 topic 운영을 이어갈 순 있다.min.insync.replicas=2
일 때로 가정- 리더 파티션 + 팔로워1 까지 작성이 완료되었을 때 ack를 반환
- 리더를 포함한 세 개의 복제본이 동기화되어 있으면, 이후 쓰기 작업은 정상적으로 진행된다.
- 만약 세 개의 복제본 중 적어도 두 개가 동기화되어 있으면, 여전히 쓰기 작업은 가능합니다.
- 그러나
min.insync.replicas
보다 적은 수의 복제본이 ISR에 속해있다면, 여기선 두개의 브로커가 사용 불가능하면, 브로커는 더 이상 쓰기 작업을 진행하지 않고 브로커에선 프로듀서에게NotEnoughReplicasException
에러를 보낸다.
참고
'kafka' 카테고리의 다른 글
Kafka Streams (0) | 2022.01.20 |
---|---|
kafka - Consumer (0) | 2022.01.18 |
kafka - Producer (0) | 2022.01.18 |
Kafka의 구조 (0) | 2022.01.17 |