- 개념
Kafka는 Kafka cluster로 운영되고, cluster는 브로커의 집합이다.
브로커는 프로듀서에게 메세지를 받아서 저장하고, 컨슈머는 메세지를 차례대로 꺼내간다.
브로커가 여럿일 경우, 일련의 메세지를 파티션으로 나누어 분산 처리할 수 있다.
k개의 브로커에 대해 파티션 x번은 x%k번째 브로커가 리더로서 저장한다.(모든 브로커가 저장하긴 한다.)
그러나 파티션 별로 ordering이 보장이 될 뿐이라, 일련의 메세지를 순서대로 재구성하려면 파티션을 사용하면 안된다.
- exactly-once
메세지를 주고받을때, at least once / at most once / exactly once라는 semantic 종류가 있다.
Kafka 초기 버전은 at least once를 보장하여 네트워크 장애로 인해 중복되는 메세지를 막을 방법이 없었다.
그러나 1.0.0 부터인가 enable.idempotence 기능이 추가되면서 exactly once가 보장되기 시작한다.
또한, 0.11.0 부터 transactional messaging 기능이 추가되었기에, 이를 사용하면 producer 측에서도 exactly once를 보장할 수 있을 것이다. 이는 아래에서 자세히 설명한다.
enable.idempotence는 정확히 말하면 Kafka에서 exactly-once를 보장한다는 의미인데, producer와 consumer는 알아서 application에서 잘 처리해서 exactly-once를 만들어야 된다. 해당 기능은 연결되는 producer마다 PID(producer ID, 32bit)를 부여하고 메세지마다 serial number(64bit)를 붙여서 네트워크 장애로 인해 여러번 메세지가 와도 broker가 중복을 막을 수 있다는 말이다. producer는 죽었다가 재연결하면 PID가 새로 발급되기 때문에, producer가 죽었다가 재연결한 뒤 같은 메세지를 보내면 이는 중복을 막을 수 없다. 만약 PID와 serial number를 producer application이 설정할 수 있다면 그나마 쉽게 producer측 exactly-once를 구현할 수 있을텐데, 약간 아쉬운 기능이다.
※ 참고로 ogg-bd의 kafka handler는 자기네 옵션 중 blocking send(ack=all), tx mode(=tx)를 켜면 exactly-once를 지원한다고 한다. 즉, 아마 ogg-bd 또한 idempotence 기능과 transactional messaging을 사용해서 구현할 것이다.
- producer / consumer의 exactly-once 구현
producer는 메세지를 보내는 동시에(atomic하게) 자신의 디스크에 워터마크를 쓸 수 없기 때문에 producer application의 exactly-once는 만들기 어려운 감이 있다. consumer는 읽어서 처리한 후에 워터마크를 찍어놓고 죽었다가 다시 켜면 확인하도록 해서 (producer보단 쉽게?)exactly-once가 된다.
producer의 exactly-once는 다음과 같이 구현할 수 있다. 메세지 하나에 오라클의 scn같은 serial number를 붙이면서, 같은 tx에 serial number 값을 producer만 보는 토픽 t로 보내서 저장하면 producer가 죽었다가 다시 깨어나도 kafka가 어디까지 받았는지 토픽 t를 통해 알 수 있기 때문이다.(producer application이 토픽 t를 consume한다는 가정이다.)
추가적인 방법으로는, 메세지가 멱등 연산만을 보내도록 제한하는 방법이다. 메세지가 중복되어 수신자가 두 개의 같은 메세지를 보고 똑같이 어떤 함수를 실행해도, 멱등 연산이라면 최종적인 결과에는 영향이 없기 때문이다. 다만 보내려는 메세지를 멱등 연산으로 만들려면 추가적인 정보(ex 연산에 대한 UUID)가 필요하기도 하는 등 섬세한 설계가 필요하다.
참고자료:
idempotence producer features: https://www.cloudkarafka.com/blog/2019-04-10-apache-kafka-idempotent-producer-avoiding-message-duplication.html
tx msg 한글 설명: https://gunju-ko.github.io/kafka/2018/03/31/Kafka-Transaction.html
kafka 공식 producer API: https://kafka.apache.org/20/javadoc/org/apache/kafka/clients/producer/KafkaProducer.html
'backend' 카테고리의 다른 글
oracle golden gate 19c 예제 (0) | 2020.08.28 |
---|---|
DB transaction isolation level (0) | 2020.04.03 |
분산 데이터베이스의 CAP 이론 (0) | 2019.08.31 |
Load Balancer (0) | 2019.08.03 |