Kafka Message Flow 살펴보기 [Consumer 편]

김정형 · 원프레딕트 백엔드 엔지니어
May 15, 2024

Intro

지난 글에서는 Producer에서 메시지를 발송하였을 때, message가 어떻게 처리되고 적재되는지 알아보았습니다. 이번 글에서는 적재된 메시지를 다시 꺼내어 처리할 때 consumer 동작 방식과 message(record) flow를 이해하는 것이 목표입니다.

Consumer 구조

consumer_architecture Consumer는 크게 fetcher와 coordinator로 구성되어 있습니다.

Fetcher

poll이 실행될 때, 적절한 크기의 record를 client에 return 하기 위해 Kafka Cluster로부터 record를 요청하고, client가 받기 직전에 메모리에 미리 저장하는 역할을 합니다.

Fetcher 성능에 영향을 주는 Configuration

fetch.min.byte ~ fetch.max.byte : broker에서 가져올 최소/최대 데이터 크기를 결정합니다. max.partition.fetch.bytes : 하나의 partition에서 가져올 데이터의 최대 크기를 결정합니다. fetch.max.wait.ms : fetch.min.byte에 도달하기까지 기다릴 수 있는 시간을 의미합니다. 이 시간이 지나도 min.byte에 도달하지 못하면 도달하지 못한 데이터 크기를 보냅니다.

coordinator

Kafka Cluster 내부의 coordinator(zookeeper, kraft)와 통신하여 어떻게 데이터를 consume할지, offset commit, consumer group, heartbeat 기능 등을 수행합니다.

poll configuration

데이터를 poll 할 시, 아래와 같은 설정값에 의해 동작이 달라질 수 있습니다. max.poll.records(default : 500)에 의해 fetcher로부터 가져 올 record 수가 정해진다. max.poll.interval.ms : poll 요청을 받은 메시지를 처리할 때 까지 최대 기다릴 수 있는 시간. 이 시간이 초과한다면, 해당 consumer는 rebalancing 될 때 consumer group에서 제외대상이 된다.

Consumer Partition Assignor

Range Assignor

kafka_range_assignor 이 assignor는 default 전략으로 채택되어 있다. 이 전략은 coordinator에 의해 할당된 member id를 기반으로 모든 consumer를 사전식으로 배치하고, topic partition을 이에 해당하는 순서의 숫자 순서로 매핑합니다. producer 측에서 키를 기반으로 partitioning 하였을 때, 같은 알고리즘으로 같은 키를 받았다면 같은 번호의 partition에 저장됩니다. 따라서 이 전략은 같은 키에 대한 일괄처리에 조금 더 나은 성능을 보입니다.

kafka_range_assignor 그러나 키의 개수가 consume의 개수보다 적게 구성되어 있으면 위 모식도와 같이 유휴상태의 consumer가 생길 수 있기 때문에 consumer group 설계에 유의해야합니다.

Round Robin Assignor, Sticky Assignor

kafka_round_robin_assignor 위 2가지의 assignor는 consumer에 대한 partition 분배를 최대한 균등하게 하는 기법입니다. 단순히 consumer에 대한 partition 할당을 균등하게 하는 것이기 떄문에, partitions/consumers가 정확히 나누어 떨어지지 않는 경우, partition 할당을 더 많이 받는 consumer가 생길 수 있으므로 consumer group 설계시 유의해야 합니다.

그러나 두 assignor는 consumer가 문제가 생겼을 시에 대한 대처법에서 차이가 있습니다.

  • round robin : consumer가 문제가 생기면 다시 모두 나열하여 모든 partition - consumer 관계를 재정의하는 방식으로 rebalancing 처리됩니다.

  • sticky : 기존 연결은 유지를 하고, reassign이 필요한 connection만 rebalancing을 수행합니다.

마치며

producer에서 시작하여 consumer에 데이터가 도달하는 여정을 함께 알아보았습니다. 대용량 데이터 스트리밍에 많이 쓰이는 플랫폼인 만큼, 동작방식에 대해서 이해하면 적재적소에 맞는 설계가 가능해 질 것입니다. 견고한 데이터 엔지니어링을 함께 하실 분은 원프레딕트에 합류해주세요!

원프레딕트는 더 나은 제품을 고민하며 기술적인 문제를 함께 풀어낼 동료를 찾고 있습니다.
자세한 내용은 채용 사이트를 참고해 주세요.