백엔드 데이터 인프라 96편. Kafka Producer 설정 20가지 — acks·idempotence·batch·linger·buffer·retries·delivery.timeout·max.in.flight·partitioner·compression 등 자주 튜닝하는 핵심 설정을 카테고리별로 풀어쓴 학습 노트.
이 글은 백엔드 데이터 인프라 시리즈 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=allretries > 0max.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 - Reliability —
acks=all+enable.idempotence=true(3.0+ 기본) - 운영 황금 조합 =
acks=all+idempotence=true+ brokermin.insync.replicas=2 retries기본 = 거의 무한대delivery.timeout.ms= 전체 send 의 최대 시간 (retries보다 상위)- Batching —
batch.size(16KB 기본) +linger.ms(0 기본) +buffer.memory(32MB) linger.ms권장 = 실시간 0~5 / 균형 5~20 / 처리량 50~100max.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+)- Network —
request.timeout.ms (30초)·connections.max.idle.ms - Transactional —
transactional.id+transaction.timeout.ms client.id= 운영 모니터링 가독성- 운영 환경 권장 조합 — 일반·고처리량·매우 안전 3가지 패턴
- 함정 —
min.insync.replicasbroker 측 누락 - 함정 —
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 에서 모든 설정의 자세한 사양을 확인할 수 있어요.
시리즈 다른 편 (앞뒤 글 모음)
이전 글:
- 91편 — Kafka Producer API 깊이 (Serializer · Callback · Interceptor)
- 92편 — Kafka Consumer API 깊이 (Commit · Rebalance · Seek)
- 93편 — Kafka Admin Client API (Topic·ACL·Consumer Group 관리)
- 94편 — Kafka Broker 설정 30가지 (실무 핵심)
- 95편 — Kafka Topic 설정 (Retention · Compression · Cleanup)
다음 글: