본문 바로가기

Message Queue/Kafka

Kafka란?

Kafka란?

  • 아파치 카프카(Apache Kafka)는 LinkedIn에서 개발된 분산 메시징 시스템입니다. 
  • 발행-구독(publish-subscribe) 모델을 기반으로 동작하며 크게 producer, consumer, connectors, streams processors, broker로 구성됩니다.

특징

  • 카프카의 브로커(broker)는 토픽(topic)을 기준으로 메시지를 관리합니다.
  • 프로듀서(producer)는 특정 토픽의 메시지를 생성한 뒤 해당 메시지를 브로커에게 전달합니다. 브로커가 전달받은 메시지를 토픽별로 분류하여 쌓아놓으면, 해당 토픽을 구독하는 컨슈머(consumer)들이 메시지를 가져가서 처리하게 됩니다.
  • 카프카는 확장성(scale-out)과 고가용성(high availability)을 위하여 브로커들이 클러스터로 구성되어 동작하도록 설계되어있습니다.

토픽, 파티션

  • 카프카 클러스터는 토픽이라는 곳에 데이터를 저장합니다.
  • 카프카에 저장되는 메시지는 토픽으로 분류되고 토픽은 여러개의 파티션으로 나눠집니다.
  • 파티션안에는 메시지의 위치를 나타내는 오프셋(offset)이 있는데, 이 오프셋 정보를 이용해서 가져간 메시지의 위치정보를 알 수 있습니다.

컨슈머, 컨슈머 그룹

  • 컨슈머는 카프카 토픽에서 메시지를 읽어오는 역할을 합니다.
  • 컨슈머 그룹은 하나의 토픽에 여러 컨슈머 그룹이 동시에 접속해 메시지를 가져올 수 있습니다.
  • 컨슈머그룹은 컨슈머가 프로듀서의 메시지 생성 속도를 따라가지 못할 때, 컨슈머 확장을 용이하게 할 수 있도록 하기위한 기능입니다.

메시지 발행 속도 > 컨슈머 메시지 소비 속도

  • consumer가 메시지를 가져가는 속도보다 프로듀서가 메시지를 보내는 속도가 더 빨라지게되고, 토픽에는 시간이 지남에 따라 consumer가 아직 읽어가지 못한 메시지들이 점점 쌓이게 될 것입니다.
  • 이러한 경우, 컨슈머 그룹 consumer group01 에 컨슈머 consumer02, consumer03 을 추가해서 내부적으로 균형을 맞추도록 할 수 있습니다.
    동일한 컨슈머그룹내에서 컨슈머가 추가되면 consumer01이 가지고 있는 소유권이 consumer02, consumer03으로 이동하게 되어 균형을 맞출 수 있습니다.

리밸런스

  • 컨슈머 그룹안에서 컨슈머들은 메시지를 가져오고 있는 토픽의 파티션에 대해 소유권을 공유하고 있습니다. 컨슈머가 추가되거나 삭제되었을 때 토픽에 대한 소유권이 이동하게 되는데,
    이를 리밸런스(rebalance) 라고 합니다.
  • 리밸런스를 하는 동안에는 일시적으로 컨슈머는 메시지를 가져올 수 없습니다.
  • 리밸런스가 일어나면 토픽의 각 파티션마다 하나의 컨슈머가 연결되고, 리밸런스가 끝나면 컨슈머들은 각자 담당하고 있는 파티션으로부터 메시지를 가져오게 됩니다.
  • 리밸런스가 일어난 후 각각의 컨슈머는 이전에 처리했던 토픽의 파티션이 아닌 다른 새로운 파티션에 할당됩니다.
  • 컨슈머는 새로운 파티션에 대해 가장 최근 커밋된 오프셋을 읽고, 그 이후부터 메시지들을 가져오기 시작합니다.

Kafka Message 중복 소비

1) 리밸런싱으로 인한 문제

컨슈머 옵션 속성에서 리밸런싱을 발생시킬수 있는 요소 검색

max.poll.interval.ms 설정시간에 poll() 메소드가 호출되지 않아 리밸런스가 발생하는 경우

  • 컨슈머는 메시지를 가져오기위해 브로커에 poll()요청을 보내고, 컨슈머는 가져온 메시지를 처리한 후, 해당 파티션의 offset을 커밋하게 됩니다.
  • poll요청을 보내고 다음 poll을 요청을 보내는데 까지의 시간이 max.poll.interval.ms의 기본값인 300000 (5분) 보다 늦으면 브로커는 컨슈머에 문제가 있다고 판단하여 리밸런싱을 일으키게 됩니다.
  • 설정에 정해진 레코드 수만큼 가져오고 서버에서 레코드를 정해진 시간안에 처리를 하지 못한다면, 결국 rebalancing을 일으키고, 실제로 처리된 offset보다 파티션에 커밋된 offset이 작아 Consumer에 의해 중복 처리 될수 있는 것입니다.