카프카의 구성요소, 동작원리, Exactly-delivery-once 모델 차용

카프카란?

아파치 재단의 카프카는 pub-sub모델의 메세지 큐이고, 분산환경에 특화되어 설계되어 있다는 특징을 가짐으로써, 기존의 RabbitMQ와 같은 다른 메세지큐와의 성능 차이가 난다(훨씬 빠르게 처리한다). 그 외에도 클러스터 구성, fail-over, replication와 같은 여러 가지 특징들을 가지고 있다.

Pub-Sub 모델

카프카는 pub-sub(발행/구독) 모델을 사용하기 때문에, 발행/구독모델이 뭔지 알아보자. pub-sub은 메세지를 특정 수신자에게 직접적으로 보내주는 시스템이 아니다. publisher는 메세지를 topic을 통해서 카테고리화 한다. 분류된 메세지를 받기를 원하는 receiver는 그 해당 topic을 구독(subscribe)함으로써 메세지를 읽어 올 수 있다. 즉, publisher는 topic에 대한 정보만 알고 있고, 마찬가지로 subscriber도 topic만 바라본다. publisher 와 subscriber는 서로 모르는 상태다. 가장 간단한 예제를 들어보자, 신문사에서 신문의 종류(topic)에 메세지를 쓴다. 우리는 그 해당 신문을 구독한다.

카프카의 구성요소 및 특징

Topic과 partition

메세지는 topic으로 분류되고, topic은 여러개의 파티션으로 나눠 질 수 있다. 파티션내의 한 칸은 로그라고 불린다. 데이터는 한 칸의 로그에 순차적으로 append된다. 메세지의 상대적인 위치를 나타내는게 offset이다. 배열에서의 index를 생각하면 좀 쉬울듯.

그러면, 왜 하나의 토픽에 여러개의 파티션을 나눠서 메세지를 쓸까 ? 의문이 들것이다. 하나의 topic에 하나의 파티션만 가진 상황과 하나의 topic에 여러개의 파티션을 가진 두가지를 비교해 보면 된다. 메세지는 카프카의 해당 토픽에 쓰여진다. 쓰는 과정도 시간이 소비된다. 몇 천건의 메세지가 동시에 카프카에 쓰여진다고 생각해보자. 그러면 하나의 파티션에 순차적으로 append될 텐데, 처리하는게 좀 버겁지 않나 ?그렇기 때문에 여러개의 파티션을 두어서 분산저장을 하는 것이다. 그러면 쓰는 처리가 병렬로 처리될테니 시간이 그만큼 절약 하게 될 것 아닌가? 물론 좋다는 말은 항상 trade-off이다. (주의)한 번 늘린 파티션은 절대로 줄일 수 없기 때문에 운영중에, 파티션을 늘려야 하는건 충분히 고려해봐야한다.

또한, 파티션을 늘렸을 때 메세지가 Round-robin방식으로 쓰여진다. 즉, 순차적으로 메세지가 쓰여지지 않는다는 말이다. 이 말은, 나중에 해당 토픽을 소비하는 소비자가 만약에 메세지의 순서가 엄청 중요한 모델(증권시스템)이라면 순차적으로 소비됨을 보장해 주지 않기 때문에 상당히 위험한 것이다.

Producer, Consumer

Producer는 메세지를 생산하는 주체이다. 메세지를 만들고 Topic에 메세지를 쓴다. Producer는 Consumer의 존재를 알지 못한다. 그냥 카프카에 메세지를 쓴다. 만약에 여러개의 토픽에 여러개의 파티션을 나누고, 특정 메세지들을 분류해서 특정 파티션에 저장하고 싶다면, key 값을 통해서 분류해서 넣을 수 있다. 너무나 고급과정이기 때문에, 실제 사용하는 지, 무엇보다도 이렇게 까지 필요한지에 대한 의문은 있다.

Consumer는 소비자로써 메세지를 소비하는 주체이다. 역시 Producer의 존재를 모른다. 해당 topic을 구독함으로써, 자기가 스스로 조절해가면서 소비할 수 있는 것이다. 소비를 했다는 표시는 해당 topic내의 각 파티션에 존재하는 offset의 위치를 통해서 이전에 소비했던 offset위치를 기억하고 관리하고 이를 통해서, 혹시나 Consumer가 죽었다가 다시 살아나도, 전에 마지막으로 읽었던 위치에서 부터 다시 읽어들일 수 있다. 그렇기 때문에 fail-over에 대한 신뢰가 존재한다.