Kafka 기본구성 요소와 동작 - shinminsoo118/Kafka GitHub Wiki

Kafka의 기본구성 요소와동작

  • kafka는 발행-구독(publish-subscribe) 모델을 기반으로 동작하며 크게 producer, consumer, broker로 구성된다.

  • kafka의 broker는 topic을 기준으로 메세지를 관리한다. Producer는 특정 topic의 메세지를 생성한 뒤 해당 메세지를 broker에 전달한다. broker가 전달받은 메세지를 topic별로 분류하여 쌓아놓으면, 해당 topic을 구독하는 consumer들이 메세지를 가져가서 처리하게 된다.

  • kafka는 확장성(scale-out)과 고가용성을 위하여 broker들이 클러스터로 구성되어 동작하도록 설계되어 있다. 심지어 broker가 1개 밖에 없을때에도 클러스터로써 동작한다. 클러스터내의 broker에 대한 분산 처리는 아래의 그림과 같이 Apache Zookeeper가 담당한다.

기존 메시징 시스템과의 차이점

(기존 메시징 시스템 : ActiveMQ, RabbitMQ 등)
  • 대용량의 실시간 로그 처리에 특화되어 설계된 메시징 시스템으로써 기존 범용 메시징 시스템대비 TPS가 매우 우수하다. 단, 특화된 시스템이기 때문에 범용 메시징 시스템에서 제공하는 다양한 기능들은 제공하지 않는다.

  • 분산 시스템을 기본으로 설계되었기 때문에,기존 메시징 시스템에 비해 분산 및 복제 구성을 손쉽게 할 수 있다.

  • AMQP 프로토콜이나 JMS API를 사용하지 않고 단순한 메세지를 헤더를 지닌 TCP기반의 프로토콜을에 의한 오버헤드를 감소한다.

  • Producer가 broker에게 다수의 메시지를 전송할 때 각 메시지를 개별적으로 전송해야하는 기존 메시징 시스템과는 달리, 다수의 메시지를 batch형태로 broker에게 한 번에 전달 할 수 있어 TCP/IP 라운드트립 횟수를 줄일 수 있다.

  • 메시지를 기본적으로 메모리에 저장하는 기존 메시징 시스템과는 달리 메시지를 파일 시스템에 저장한다.
    1)파일 시스템에 메시지를 저장하기 때문에 별도의 설정을 하지 않아도 데이터의 영속성이 보장된다.
    2)기존 메시징 시스템에서는 처리되지 않고 남아있는 메시지의 수가 많을수록 시스템의 성능이 크게 감소하였으나, kafka에서는 메시지를 파일 시스템에 저장하기 때문에 메시지를 쌓아두어도 성능이 크게 감소하지 않는다. 또한 많은 메시지를 쌓아둘 수 있기 때문에, 실시간 처리뿐만 아니라 주기적인 batch작업에 사용할 데이터를 쌓아두는 용도로도 사용할 수 있다.
    3)Consumer에 의해 처리된 메시지를 곧바로 삭제하는 기존 메시징 시스템과는 달리 처리된 메시지를 삭제하지 않고 파일 시스템에 그대로 두었다가 설정된 수명이 지나면 삭제한다. 처리된 메시지를 일정 기간동안 삭제하지 않기 때문에 메시지 처리 도중 문제가 발생하였거나 처리 로직이 변경되었을 경우 consumer가 메시지를 처음부터 다시 처리하도록 할 수 있다.

  • 기존의 메시징 시스템에서는 broker가 consumer에게 메세지를 push해 주는 방식인데 반해, kafka는 consumer가 broker로부터 직접 메시지를 가지고 가는 pull방식으로 동작한다. 따라서 consumer는 자신의 처리능력만큼의 메시지만 broker로부터 가져오기 때문에 최적의 성능을 낼 수 있다.

  1. 기존의 push방식의 메시징 시스템에서는 broker가 직접 각 consumer가 어떤 메세지를 처리해야 하는지 계산하고 어떤 메시지를 처리중인지 트랙킹하였는데, kafka에서는 consumer가 직접 필요한 메시지를 broker로부터 pull하므로 broker의 consumer와 메시지 관리에 대한 부담이 경감되었다.
  2. 메시지를 pull 방식으로 가져오므로, 메시지를 쌓아두었다가 주기적으로 처리하는 batch consumer의 구현이 가능하다.

Topic과 Partition

kafka의 topic은 partation이라는 단위로 쪼개어져 클러스터의 각 서버들에 분산되어 저장되고, 고가용성을 위하여 복제 설정을 할 경우 이 또한 partition 단위로 각 서버들에 분산되어 복제되고 장애가 발생하면 partition 단위로 fail over가 수행된다.

위의 그림은 하나의 topic이 3개의 partiation에 분산되어 순차적으로 저장되는 모습을 보여주고 있다.

각 partition은 0부터 1씩 증가는 offset값을 메시지에 부여하는데 이 값은 partition내에서 메시지를 식별하는 ID로 사용된다.
Offset값은 partition마다 별도로 관리되므로 메시지를 식별할 때는 partition번호와 offset 값을 함께 사용한다.

Partition의 복제

kafka에서는 고가용성을 위하여 각 partition을 복제하여 클러스터에 분산시킬 수 있다. 아래의 그림은 해당 topic의 replication factor를 3으로 설정한 상태의 클러스터이다. 각 partition들은 3개의 replica를 가지며 R0, R1, R2로 표시되어 있다.

Replication factor를 N으로 설정할 경우 N개의 replica는 1개의 leader와 N-1개의 follower로 구성된다. 위의 그림에서는 각 partition마다 하나의 leader가 존재하며 2개의 follower(푸른색)가 존재한다.

각 partition factor에 대한 읽기와 쓰기는 모두 leader에서 이루어지며, follower는 단순히 leader를 복제하기만 한다. 만약 leader에 장애가 발생할 경우 follower 중 하나가 새로운 leader가 된다. kafka의 복제 모델인 ISR 모델를 가진 topic f개의 장애까지 버틸 수 있도록 한다.

Leader에서만 읽기와 쓰기를 수행한다고 하면 부하 분산이 되지 않는다고 생각할 수 있는데,각 partition의 leader가 클러스터 내의 broker들에 균등하게 분배되도록 알고리즘이 설계되어 있기 때문에 부하는 자연스럽게 분산이 된다. 위의 그림처럼 3개의 broker에 P0, P1, P2의 leader가 균등하게 분배되므로 부하 또한 자연스럽게 분산되게 된다.

Consumer와 Consumer Group

메시징 모델은 크게 큐(queue)모델과 발행구독(publish-subscribe)모델로 나뉜다. 큐 모델은 메시지가 쌓여있는 큐로부터 메시지를 가져와서 consumer pool에 있는 consumer 중 하나에 메시지를 할당하는 방식이고, 발행 구독 모델은 topic을 구독하는 모든 consumer에게 메시지를 브로드캐스팅하는 방식이다.

kafka에서는 consumer group이라는 개념을 도입하여 두가지 모델을 발행-구독 모델로 일반화하였다. kafka의 partition은 consumer group당 오로지 하나의 consumer의 접근만을 허용하며, 해당 consumer를 partition owner라고 부른다. 따라서 동일한 consumer group에 속하는 consumer끼리는 동일한 partition에 접근할 수 없다.

한 번 정해진 partition owner는 broker나 consumer구성의 변동이 있지 않는한 계속 유지된다. Consumer가 추가/제거되면 추가/제거된 consumer가 속한 consumer group 내의 consumer들의 partition 재분배가 발생되고 broker가 추가/제거되면 전체 consumer group에서 partition 재분배가 발생한다.

Consumer group을 구성하는 consumer의 수가 partition의 수보다 작으면 하나의 consumer가 여러 개의 partition을 소유하게 되고, 반대로 consumer의 수가 partition의 수보다 많으면 여분의 consumer는 메시지를 처리하지 않게되므로 partition개수와 consumer수의 적절한 설정이 필요하다.

⚠️ **GitHub.com Fallback** ⚠️