백엔드 데이터 인프라 96편 — Kafka Producer 설정 20가지 (Batching · Retries · Idempotence)

2026-05-17백엔드 데이터 인프라

백엔드 데이터 인프라 96편. Kafka Producer 설정 20가지 — acks·idempotence·batch·linger·buffer·retries·delivery.timeout·max.in.flight·partitioner·compression 등 자주 튜닝하는 핵심 설정을 카테고리별로 풀어쓴 학습 노트.

📚 백엔드 데이터 인프라 · 96편 — Kafka Producer 설정 20가지 (Batching · Retries · Idempotence)

이 글은 백엔드 데이터 인프라 시리즈 130편 중 96편이에요. 95편 까지 broker·topic 설정을 잡았다면 이번 96편은 클라이언트 쪽 차례 — Producer 설정 20가지를 정리해요. 86편 Design·91편 API 와 직결되는 실무 튜닝 영역.

Producer Config가 어렵게 느껴지는 이유

설정끼리 상호작용이 많아요. idempotence(중복 메시지 자동 차단) 를 켜는 순간 acks·retries·max.in.flight 가 같이 자동으로 바뀌는 식의 조건부 default가 곳곳에 박혀 있어요.

첫째, 버전마다 default가 달라요. Kafka 3.0+ 부터 idempotence 가 기본 true 인데 이전 버전은 false 였어요.

둘째, timeout 종류가 많아요. request.timeout.ms·delivery.timeout.ms·retry.backoff.ms 셋의 관계가 한눈에 안 들어와요.

이 글에서는 카테고리별로 20개를 짚고 운영 환경 권장 조합까지 같이 봐요.

1. 필수 설정 (3개)

bootstrap.servers

bootstrap.servers=kafka1:9092,kafka2:9092,kafka3:9092

여러 broker 를 한 번에 적어 둬요. 한 broker 가 죽어도 다른 쪽으로 fallback 이 돼요.

key.serializer · value.serializer

key.serializer=org.apache.kafka.common.serialization.StringSerializer
value.serializer=org.springframework.kafka.support.serializer.JsonSerializer

91편에서 깊이 다뤄요.

2. 신뢰성 (Reliability) — 가장 중요

acks

acks=all                    # 가장 안전, 모든 ISR 확인
# acks=1                    # leader 만 확인
# acks=0                    # fire-and-forget

여기서 ISR(In-Sync Replicas, 동기화된 복제본 집합) 과 fire-and-forget(보내고 응답 안 기다림) 이 처음 나와요. 86편에서 깊이 다루고, 운영 환경은 all 권장이에요.

enable.idempotence

enable.idempotence=true     # Kafka 3.0+ 기본

자동 활성 조건은 세 가지예요.

  • acks=all
  • retries > 0
  • max.in.flight.requests.per.connection ≤ 5

켜면 중복 메시지가 자동으로 걸러져요 (86편 깊이).

retries

retries=2147483647          # 거의 무한대 (기본)

일시적 실패는 알아서 retry 해 줘요. idempotent 와 같이 켜야 안전해요.

retry.backoff.ms

retry.backoff.ms=100        # 100ms (기본)

Retry 사이 대기 시간이에요. 지수 backoff 가 자동으로 적용돼요.

retry.backoff.max.ms

retry.backoff.max.ms=1000   # 1초 (기본)

Exponential backoff 의 상한선.

delivery.timeout.ms

delivery.timeout.ms=120000  # 2분 (기본)

전체 send 의 최대 시간 이에요. 첫 send 부터 마지막 ACK(broker 가 메시지 받았다는 응답) 까지 합산해서 끊어요. retries 와 별개로 시간 한계가 따로 걸려요.

3. 성능·Batching

batch.size

batch.size=16384             # 16KB (기본)

Per-partition batch buffer 예요. 채워지면 바로 전송하고, 값을 키울수록 batch 효율이 올라가요.

linger.ms

linger.ms=0                  # 0 (기본) = 즉시 전송
# 운영 환경
linger.ms=5
linger.ms=10

batch.size 가 안 채워졌어도 linger.ms 만큼 기다렸다 보내요. 처리량과 지연 사이 trade-off 가 여기서 갈려요.

권장 값은 이렇게 잡아요.

  • 실시간 = 0~5ms
  • 균형 = 5~20ms
  • 처리량 우선 = 50~100ms

buffer.memory

buffer.memory=33554432       # 32MB (기본)

Producer 전체가 쓰는 메모리 buffer 예요. 가득 차면 send() 가 블로킹되거나 timeout 으로 빠져요.

max.block.ms

max.block.ms=60000           # 1분 (기본)

Buffer 가 가득 차거나 metadata fetch 가 오래 걸릴 때 send() 가 얼마나 기다릴지의 한계.

max.in.flight.requests.per.connection

max.in.flight.requests.per.connection=5    # 기본

Connection 하나당 동시에 떠 있을 수 있는 in-flight 요청 수예요.

여기 시험 함정이 하나 있어요 — idempotence 자동 활성 조건이 ≤ 5 라서, 6 이상으로 올리면 idempotent 가 자동으로 꺼져요. 명시적으로 idempotent 가 필요하면 반드시 5 이하로 잡아요.

4. Compression

compression.type

compression.type=none         # 기본
# 권장
compression.type=zstd
compression.type=lz4
compression.type=snappy

85편에서 깊이 다루고, 운영 환경은 zstd 가 가장 균형이 좋아요.

5. Partitioning

partitioner.class

partitioner.class=...              # null = default partitioner (Sticky, 2.4+)

Custom partitioner 를 끼우고 싶을 때 써요. 91편에서 더 깊이 봐요.

partitioner.adaptive.partitioning.enable

partitioner.adaptive.partitioning.enable=true    # 기본

true 면 느린 partition 을 자동으로 피해 가요. Kafka 3.3+ 부터 들어온 기능.

6. Network·Timeout

request.timeout.ms

request.timeout.ms=30000          # 30초 (기본)

Broker 에 보낸 한 요청을 얼마나 기다릴지예요. 넘기면 retry 가 걸려요.

connections.max.idle.ms

connections.max.idle.ms=540000    # 9분 (기본)

쉬고 있는 connection 을 자동으로 끊는 기준.

socket.send.buffer.bytes · socket.receive.buffer.bytes

socket.send.buffer.bytes=131072
socket.receive.buffer.bytes=65536

TCP buffer 크기예요. 고대역폭 환경에서는 키워서 써요.

7. Transactional

transactional.id

transactional.id=my-producer-1

값을 지정하면 Transactional Producer 로 동작해요. 88편 EOS(Exactly-Once Semantics, 정확히 한 번 전달) 에서 깊이 다뤄요.

transaction.timeout.ms

transaction.timeout.ms=60000       # 60초 (기본)

Transaction 하나가 살아 있을 수 있는 최대 시간.

8. Interceptor·Metric

interceptor.classes

interceptor.classes=com.example.MyInterceptor

91편 ProducerInterceptor(전송 전후 가로채는 훅) 에서 깊이 봐요.

metric.reporters

metric.reporters=org.apache.kafka.common.metrics.JmxReporter

JMX(Java 표준 모니터링 인터페이스)·Prometheus·Datadog 등 메트릭을 어디로 흘릴지 정해요.

client.id

client.id=order-service

Broker log 와 메트릭에 그대로 찍히는 식별자예요. 운영 모니터링 가독성이 여기서 결정돼요.

운영 환경 권장 조합

일반 백엔드 (균형)

bootstrap.servers=kafka1:9092,kafka2:9092,kafka3:9092
key.serializer=org.apache.kafka.common.serialization.StringSerializer
value.serializer=org.springframework.kafka.support.serializer.JsonSerializer

# Reliability
acks=all
enable.idempotence=true

# Performance
batch.size=32768
linger.ms=10
buffer.memory=67108864
compression.type=zstd

# Network
request.timeout.ms=30000
delivery.timeout.ms=120000

# Identity
client.id=order-service-prod-1

매우 빠른 처리량 (로그·메트릭 — 손실 OK)

acks=0
enable.idempotence=false
compression.type=lz4
batch.size=65536
linger.ms=50
buffer.memory=134217728

매우 안전 (결제·금융)

acks=all
enable.idempotence=true
transactional.id=payment-producer-1
max.in.flight.requests.per.connection=1
delivery.timeout.ms=300000          # 5분 (충분한 retry 시간)

설정 상호작용 — 함정 모음

1. acks=all + min.insync.replicas 누락

89·94편에서 한 번 짚었던 함정이에요. broker 측에서도 같이 잡아 줘야 의미가 살아요.

2. enable.idempotence=true + max.in.flight > 5

이러면 idempotent 가 자동으로 꺼져요. 5 이하로 명시해 두는 게 안전해요.

3. linger.ms 너무 큼

값을 키운 만큼 그대로 지연이 늘어요. 실시간 자리에서는 낮게 잡아요.

4. buffer.memory 작음

send() 가 자주 blocking 으로 빠져요. 고처리량 환경이면 128MB 이상으로 잡아요.

5. delivery.timeout.ms < retries × retry.backoff.ms

retry 가 채 끝나기도 전에 delivery timeout 이 먼저 떨어져서 실패로 끊겨요. 두 값을 일관되게 맞춰요.

6. compression.type=none + 큰 메시지

디스크와 네트워크 사용량이 그대로 폭증해요. 최소 lz4 는 깔고 가요.

모니터링 메트릭

JMX 로 노출되는 핵심 메트릭은 이렇게 정리해요.

  • record-send-rate — 초당 메시지 수
  • record-error-rate — 초당 에러
  • batch-size-avg — 평균 batch 크기
  • compression-rate-avg — 압축 효율
  • request-latency-avg — 평균 응답 시간
  • buffer-available-bytes — buffer 여유

운영 모니터링은 Grafana + Kafka JMX exporter 조합이 기본이에요.

Spring Boot 적용

spring:
  kafka:
    bootstrap-servers: kafka1:9092,kafka2:9092
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
      acks: all
      retries: 2147483647
      properties:
        enable.idempotence: true
        linger.ms: 10
        batch.size: 32768
        buffer.memory: 67108864
        compression.type: zstd
        request.timeout.ms: 30000
        delivery.timeout.ms: 120000
        client.id: order-service

시험 직전 한 번 더 — Kafka Producer Config 함정 압축 노트

  • 필수 = bootstrap.servers + key.serializer + value.serializer
  • Reliabilityacks=all + enable.idempotence=true (3.0+ 기본)
  • 운영 황금 조합 = acks=all + idempotence=true + broker min.insync.replicas=2
  • retries 기본 = 거의 무한대
  • delivery.timeout.ms = 전체 send 의 최대 시간 (retries 보다 상위)
  • Batchingbatch.size (16KB 기본) + linger.ms (0 기본) + buffer.memory (32MB)
  • linger.ms 권장 = 실시간 0~5 / 균형 5~20 / 처리량 50~100
  • max.in.flight.requests.per.connection = 5 (기본)
  • idempotence 자동 활성 조건 = ≤ 5, 6 이상이면 idempotent 비활성
  • Compression = zstd 권장 (대부분)
  • Partitioning = default = Sticky Partitioner (2.4+)
  • partitioner.adaptive.partitioning.enable=true = 느린 partition 자동 회피 (3.3+)
  • Networkrequest.timeout.ms (30초)·connections.max.idle.ms
  • Transactionaltransactional.id + transaction.timeout.ms
  • client.id = 운영 모니터링 가독성
  • 운영 환경 권장 조합 — 일반·고처리량·매우 안전 3가지 패턴
  • 함정 — min.insync.replicas broker 측 누락
  • 함정 — max.in.flight > 5 이면 idempotent 비활성
  • 함정 — linger.ms 너무 큼 = 지연 폭증
  • 함정 — buffer.memory 작음 = send blocking
  • 함정 — delivery.timeout.ms < retries × backoff 일관성
  • 함정 — compression none + 큰 메시지 = 디스크 폭증
  • 모니터링 = JMX (record-send-rate·error-rate·batch-size·latency)
  • Spring Boot = spring.kafka.producer.* + properties.*

공식 문서: Kafka Producer Configs 에서 모든 설정의 자세한 사양을 확인할 수 있어요.

시리즈 다른 편 (앞뒤 글 모음)

이전 글:

다음 글:

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

답글 남기기

error: Content is protected !!