티스토리 뷰

이전글:2025.05.02 - [기술노트/Apach Kafka] - Kafka 기초1 - 토픽, 파티션, 오프셋


카프카에서 프로듀서(Producer)는 끊임없이 생성되는 데이터를 카프카의 토픽에 흘려보내는 역할을 한다.
이번 글에서는 카프카 프로듀서가 무엇이며, 어떻게 동작하여 데이터를 안정적으로 전송하는 지에 대해 자세히 알아본다.

그림1. 프로듀서가 Kafka 클러스터의 특정 토픽으로 메시지를 전송하는 개념도

프로듀서(Producer)란?

프로듀서(Producer)란 카프카의 토픽(Topic)으로 데이터를 전송하는 역할을 담당하는 애플리케이션 또는 컴포넌트의미한다. 프로듀서는 생성된 메시지를 특정 토픽의 특정 파티션(Partition)으로 보내는 주체이다.

 

프로듀서는 카프카 서버(Broker)와 연결하여, 토픽을 기준으로 메세지를 발행하는데 이때, 토픽은 내부적으로 어러 파티션으로 나뉘게 되고, 프로듀서는 나눠진 파티션 중 어느 파티션으로 보낼지 직접 또는 간접적으로 결정하게 된다.

(브로커는 프로듀서에게 메세지를 푸시받고 메세지를 저장만 함)

그림2. 프로듀서가 Kafka 브로커를 통해 특정 파티션으로 메시지를 전송하는 과정

파티션 선택 전략

이전 글에서 잠깐 나왔던 파티션 순서 보장과 관련된 내용]]에서 나온 예시와 같이
프로듀서가 메세지를 토픽으로 보낼 때, 해당 메세지가 어떤 파티션에 저장될지는 중요한 문제다.
이는 프로듀서의 설정, 특히 메세지 키(key)의 유무에 따라 달라진다.

 

메세지 키(key)가 없는 경우

kafka 2.4부터는 키가 없을 경우 Sticky Partitioner가 기본적으로 적용된다.
Sticky Partitioner배치 효율성과 지연 시간(latency) 을 크게 향상 시켰다.

 

기존 라운드 로빈 방식에서는 파티션을 순차적으로 할당해 메세지가 여러 파티션에 분산되어 배치(batch) 가 작아지고, 그로 인해 네트워크 오버헤드의 증가 및 지연 시간 상승 문제가 발생했다.

 

Sticky Partitioner는 이러한 문제를 해결하기 위해, 하나의 파티션에 메시지를 집중적으로 전송하여 배치 크기를 키운 후, 배치가 완료되면 다른 파티션으로 전환하는 전략을 사용한다.

 

Sticky Partitioner은 다음과 같이 동작한다.

  1. 프로듀서는 하나의 파티션을 선택하여 해당 파티션에 메시지를 전송함
  2. 배치가 가득 차거나 일정 시간이 경과하면, 프로듀서는 다른 파티션을 선택하여 메시지를 전송함
  3. 반복

그림3. Sticky Partitioner 과 라운드로빈 동작방식 비교

 

Sticky Partitioner는 기존 라운드 로빈 방식에 비해 지연시간이 절반 이상으로 감소하고,
파티션 수가 증가할수록 성능 향상 효과가 뛰어나다.

그림4. Sticky Partitioner 라운드 로빈 지연시간 비교

 

그래프를 보면, 파티션 수가 증가할수록 기존 Default(라운드 로빈) 방식은 p99 지연 시간이 급격히 상승하는 반면, Sticky Partitioner는 일정 수준을 유지하며 훨씬 안정적인 성능을 보여준다.

 

즉, Sticky Partitioner는 고파티션 환경에서 특히 뛰어난 지연 시간 최적화 효과를 가진다.

 

 

(카프카 2.4 이전)

기본적으로 라운드 로빈(Round-Robin) 방식을 사용하여 토픽 내의 여러 파티션에
메시지를 번갈아 가며 분산하여 전송한다.

 

라운드 로빈 파티셔닝은 다음과 같은 방식으로 작동한다.

  1. 프로듀서 내부의 파티셔너(Partitioner) 가 키가 있는지 판단함.
  2. 키가 없으면 카프카는 메세지를 각 파티션에 순차적으로 분배함.

이는 특정 파티션에 데이터가 몰리는 것을 방지하고, 로드 밸런싱 효과를 가져온다.

그림5. 라운드로빈 개념도

 

라운드 로빈 방식은 특정 키에 의존하지 않고 메세지를 균등하게 분산시켜 부하가 집중되는 것을
방지하지만, 순서를 보장하지 않는다.

메시지 키(Key)가 있는 경우

메시지에 키를 지정하면, 프로듀서는 이 키를 사용하여 특정 파티션을 결정한다.
기본적으로 카프카는 해싱(Hashing) 알고리즘(기본: murmur2) 을 사용하며,
동일한 키를 가진 메시지는 항상 동일한 파티션으로 전송된다.

 

키 기반 파티셔닝은 다음과 같이 동작한다.

  1. 프로듀서 내부의 파티셔너(Partitioner) 가 키가 있는지 판단함.
  2. 키가 있으면 키에 해시 함수를 적용하여 해시 값을 계산함
  3. 해시 값에 파티션 수를 나눈 나머지 값을 사용하여 메세지를 특정 파티션에 할당함

예를 들어, order_id 를 메시지 키로 사용한다면,
특정 주문 ID를 가진 모든 메시지는 항상 같은 파티션에 순서대로 기록된다.

그림6. 키 기반 파티셔닝 개념도

 

이는 메시지 처리의 순서 보장이 필요할 때 매우 유용하다.

파티션 수가 변경되면 문제가 있을까?

프로듀서는 메세지를 전송할 때 키를 기반으로 해시 함수를 적용하여 특정 파티션에 메세지를 할당한다.
이때, 파티션 수가 변경되면(증가만 가능) 해시 함수의 결과가 달라지게 되고,
동일한 키의 메세지가 다른 파티션으로 라우팅 된다.

카프카 메시지 구조

프로듀서가 전송하는 메시지는 단순한 데이터 덩어리가 아니라,
여러 중요한 정보들을 포함하는 구조체이다.

 

Kafka 메시지는 크게 다음 두 관점으로 나눌 수 있다.

  • 논리 구조 (Producer가 전송하는 메시지 단위)
  • 레코드 저장 구조 (Broker에 저장되는 메시지 단위)

논리 구조 (Producer 측 구조)

키(Key)
메시지를 식별하거나 파티셔닝에 사용되는 값이다.
null일 수도 있고, 문자열, 숫자, 바이너리 등 다양한 형태를 가질 수 있다.

값(Value)
실제 전송하고자 하는 메시지의 본문이다.
보통 JSON, Avro, Protobuf 등의 형태로 직렬화된 데이터가 담긴다.

헤더(Header)
선택적으로 사용할 수 있는 키-값 쌍의 메타데이터이다.
라우팅 정보, 버전 정보 등을 담을 수 있다.

타임스탬프(Timestamp)
메시지가 생성된 시간 또는 브로커에 기록된 시간이다.

레코드 저장 구조 (Broker 측 구조)

파티션(Partition) 및 오프셋(Offset)
메시지가 저장될 파티션 번호와 해당 파티션 내에서의 고유한 순서 번호이다.
파티션은 프로듀서가 지정하거나 파티셔셔에 의해 결정되며, 오프셋은 브로커에 의해 할당된다.

 

압축(Compression)
메시지 크기를 줄이기 위해 gzip, snappy, lz4, zstd 등의 압축 코덱을 사용할 수 있다.
이는 네트워크 대역폭과 스토리지 공간을 절약하는 데 도움이 된다.

메세지는 어떤 식으로 흘러갈까?

  1. 프로듀서가 메세지를 생성 후 파티션 결정
  2. 파티션을 담당하는 브로커로 전송
  3. 브로커는 메세지를 저장 후 필요에 따라 복제
  4. 컨슈머는 메세지를 읽고 처리

데이터 전송을 위한 직렬화(Serializer)

카프카는 네트워크를 통해 데이터를 주고받기 때문에,
메세지의 키와 값을 바이트 배열(byte array) 형태로 변환한다.

 

이 변환 과정을 직렬화(Serialization) 라고 하며,
프로듀서는 직렬화기를 사용하여 객체를 바이트 배열로 만든다.

 

예를 들어, 키가 정수 123이고 값이 문자열 "hello world"라면,
각각 IntegerSerializer와 StringSerializer를 통해 바이트 배열로 변환된다.

그림7. 직렬화 예시

 

카프카는 String, Integer, Long, Float, Double 등 기본 타입 직렬화기 외에도
JSON, Avro, Protobuf와 같은 복잡한 데이터 구조를 위한 직렬화기도 지원하거나
사용자가 직접 구현할 수 있다.

파티셔너(Partitioner)와 키 해싱의 역할

앞서 언급했듯이, 메시지 키가 있을 경우 프로듀서는 이 키를 바탕으로 메시지를 보낼 파티션을 결정한다.

이 로직을 수행하는 컴포넌트가 바로 파티셔너(Partitioner)이다.

 

기본 파티셔너는 다음과 같은 과정으로 작동한다:

  1. 메시지 키의 바이트 배열을 가져온다
  2. 해당 바이트 배열에 해싱 알고리즘(기본적으로 murmur2) 을 적용한다
  3. 생성된 해시 값을 해당 토픽의 총 파티션 수로 나눈 나머지 값을 사용하여 파티션 번호를 결정한다
    • 즉, hash(key) % numPartitions 공식을 적용한다

그림8. 파티셔너에 의한 분배 예시

 

이러한 방식을 통해 동일한 키를 가진 메시지들은 항상 같은 파티션으로 전송되므로,
데이터 처리의 순서성과 일관성을 보장할 수 있다.

 

필요에 따라 사용자 정의 파티셔너를 구현하여 특정 비즈니스 로직에 맞게 파티션을 선택하도록 확장할 수도 있다. 이는 특별한 데이터 분배나 처리 요구사항이 있을 때 유용하다.

맺음말

지금까지 카프카로 데이터를 보내는 첫 관문인 프로듀서에 대해 자세히 알아보았다.
프로듀서가 어떻게 메시지를 구성하고, 파티션을 선택하며, 데이터를 효율적으로 전송하는지 이해하는 것은 안정적이고 성능 좋은 카프카 기반 시스템을 구축하는 데 있어 매우 중요하다

 

다음 글에서는 컨슈머에 대해 다뤄보겠다.

참고 및 출처

'기술노트 > Apach Kafka' 카테고리의 다른 글

Kafka 기초5 - 브로커(Broker)  (0) 2025.05.19
Kafka 기초4 - 컨슈머 그룹  (0) 2025.05.16
Kafka 기초3 - 컨슈머  (0) 2025.05.02
Kafka 기초1 - 토픽, 파티션, 오프셋  (0) 2025.05.02
Kafka 기초0 - Apache Kafka란  (0) 2025.05.02
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/09   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함