백엔드 데이터 인프라 85편 — Kafka Design: Efficiency (Zero-Copy · Batch 압축)

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

백엔드 데이터 인프라 85편. Kafka Design Efficiency — *마지막 한 방울 짜내기* 기법. sendfile() 시스템 콜 기반 zero-copy 메커니즘·MessageSet batching·end-to-end 압축 (gzip·snappy·zstd·lz4) 선택 가이드까지 풀어쓴 학습 노트.

📚 백엔드 데이터 인프라 · 85편 — Kafka Design: Efficiency (Zero-Copy · Batch 압축)

이 글은 백엔드 데이터 인프라 시리즈 130편 중 85편이에요. 84편 에서 디스크 sequential I/O (순차 읽기·쓰기) 의 비밀을 잡았다면, 이번 85편은 마지막 한 방울 짜내기 기법 — Efficiency. Zero-copy·batching·compression 세 가지 무기.

Efficiency가 어렵게 느껴지는 이유

Persistence 까지는 디스크 활용 패턴 이었는데, Efficiency 는 OS (운영체제) 시스템 콜·CPU·네트워크 트레이드오프 같은 낮은 레벨 영역이에요.

첫째, Zero-copy 가 뭔지 가 안 잡힙니다. 왜 copy 가 비싸고 어떻게 zero 가 되는지 가 OS 레벨에서 흐름을 그려봐야 잡혀요.

둘째, 압축 알고리즘 4가지 (gzip·snappy·zstd·lz4) 중 언제 어느 걸 골라야 하는지 가 명확하지 않습니다.

이 글에서 Kafka 의 3가지 효율 기법·각각의 정확한 메커니즘·운영 선택까지 짚어볼게요.

Zero-Copy — sendfile() 시스템 콜

전통적 데이터 전송 — 4번 copy

Consumer 가 디스크 파일을 읽어 네트워크로 보내는 가장 흔한 시나리오:

1. 디스크 → kernel buffer (DMA copy)
2. kernel buffer → user buffer (Kafka 프로세스)
3. user buffer → kernel socket buffer
4. kernel socket buffer → NIC (DMA copy)

4번 copy + 2번 context switch (user ↔ kernel, 커널·사용자 영역 사이 문맥 전환). DMA (Direct Memory Access, CPU 없이 메모리 직접 전송) 가 첫·마지막 단계를 맡아도 중간 두 단계는 CPU 가 직접 옮겨야 하고, 각 copy 와 switch 마다 CPU 사이클·메모리 대역폭 이 갈려요.

Zero-Copy — 1번 copy

Linux 의 sendfile() 시스템 콜 사용:

1. 디스크 → kernel buffer
2. kernel buffer → NIC (DMA, kernel 안에서)

user space 거치지 않음. CPU 사용 최소화, 메모리 대역폭도 대폭 절약.

Java 에서 사용

// java.nio.channels.FileChannel.transferTo()
fileChannel.transferTo(position, count, socketChannel);

내부적으로 sendfile() 을 부릅니다. Kafka 가 consumer 에게 메시지 전송 시 이 메커니즘으로 흘려요.

효과

벤치마크에서 sendfile 사용 시 처리량 60~70% 향상. consumer 가 많을수록 효과가 커져요.

여기서 시험 함정이 하나 있어요 — TLS (Transport Layer Security, 전송 암호화) 활성 시 zero-copy 효과 감소. TLS 암호화는 user space CPU 처리 가 필요해서 kernel zero-copy 우회가 불가능해요. 대규모 컨슈머 환경 + TLS 면 별도 kernel TLS (kTLS, 커널에서 암호화) 검토가 필요합니다.

Batching — MessageSet

단일 메시지 vs Batch

Producer 가 메시지 1개씩 보내면 TCP (Transmission Control Protocol, 네트워크 전송 프로토콜) overhead 도 N 번, 디스크 syscall (시스템 호출) 도 N 번, 압축 CPU 도 N 번 들어요.

Batch 모드는 수십~수백 메시지를 MessageSet (메시지 묶음) 으로 한꺼번에 처리. TCP 도 한 번, 디스크도 한 번에 write, 압축도 MessageSet 전체 한 번. 결과는 처리량 10~100배.

Producer 측 설정

linger.ms=10              # 최대 10ms 대기 후 batch 전송
batch.size=16384          # 또는 16KB 채워지면 즉시 전송
compression.type=lz4

linger.ms (전송 직전 대기 시간) 가 지연 vs 처리량 trade-off 의 핵심. 0 이면 즉시 (낮은 지연), 큰 값이면 큰 batch (높은 처리량).

Broker 측

Broker 가 MessageSet 을 통째로 디스크에 저장. consumer 에게 전송할 때도 통째로 (zero-copy).

같은 MessageSet 이 write·read·network 모두 통과

핵심 — producer 가 만든 batch 가 broker 디스크·consumer 까지 같은 형식 으로 흐릅니다. 중간에 재batch·재압축 없음.

한 줄 정리 — Producer batch = broker storage = consumer delivery. 한 번 batching = 모든 단계 효율.

Compression — 4가지 알고리즘

Producer 가 MessageSet 압축 → broker 저장·전송 모두 압축 상태 → consumer 가 압축 해제.

4가지 옵션 비교

알고리즘 압축률 압축 속도 압축 해제 속도 CPU
none 1.0× 무한 무한 0
gzip 3~5× 느림 보통 높음
snappy 2~3× 빠름 빠름 낮음
lz4 2~3× 매우 빠름 매우 빠름 낮음
zstd 3~4× 빠름 빠름 중간

선택 가이드

CPU 여유가 있고 네트워크가 비싼 환경이면 gzip / zstd (압축률 우선). CPU 가 부족하고 네트워크는 충분하면 snappy / lz4 (속도 우선). 균형을 원하면 zstd (최신, 가장 균형). 소량·테스트면 none (압축 없음).

기본 권장은 zstd (Kafka 2.1+). 가장 균형 잡혔어요.

효과 — 텍스트·JSON 데이터

JSON 같은 반복적 텍스트5~10배 압축 까지 가요. 디스크·네트워크 비용 대폭 절감.

바이너리·이미지는 압축률 1.0~1.5×. 효과가 미미해요.

여기서 정말 중요한 자리 — 이미 압축된 데이터 (이미지·동영상·미리 압축된 파일) 는 압축 효과 없음. CPU 만 낭비합니다. application level 에서 미리 압축 하든지, 아니면 압축 disable.

End-to-End 압축 vs Per-Message

여기서 시험 함정 — Kafka 는 message 한 개씩 압축 X, MessageSet 전체 압축.

Per-message 압축은 각 메시지마다 별도 압축 헤더 가 붙고, 짧은 메시지압축 후 오히려 더 커지는 경우가 생겨요. Per-MessageSet 압축은 수십~수백 메시지를 통째로 압축 하니 효율이 매우 높고, 반복 패턴 도 전부 활용해요.

이게 Kafka 압축이 효과적인 이유 입니다.

CPU vs 네트워크 — 트레이드오프

시나리오 압축 알고리즘
같은 머신 (loopback) none (CPU 절약)
같은 데이터센터 (10 Gbps) snappy / lz4
다른 데이터센터 (1 Gbps) zstd
인터넷·VPN (제한된 대역폭) gzip / zstd

대부분 환경에서는 zstd 또는 lz4 가 답이에요. snappy 는 historical reasons (예전부터 기본값이라 호환성 이유) 로 자주 보입니다.

Producer-Side 추가 효율

Async Send

producer.send(record, (metadata, exception) -> {
    if (exception != null) {
        // 실패 처리
    }
});

비동기 send 가 동기 send (.send().get()) 보다 훨씬 빠릅니다. 내부 buffer + batch 가 자동으로 도와줘요.

Direct ByteBuffer

Kafka client 가 off-heap ByteBuffer (JVM heap 바깥의 메모리 버퍼) 를 써서 JVM heap 압박 X.

Lingering for Larger Batches

linger.ms=20

20ms 대기 후 batch 전송 — 지연 vs 처리량 트레이드오프.

Consumer-Side 효율

Fetch Min Bytes

fetch.min.bytes=1024
fetch.max.wait.ms=500

최소 1KB 또는 500ms 후 batch 받음 → 큰 batch 처리 효율.

Max Poll Records

max.poll.records=500

한 번에 최대 500개 받음 → batch 처리.

한계·실무 함정

1. 이미 압축된 데이터에 압축

위에서 강조. CPU 만 낭비. 비활성.

2. linger.ms 너무 큼 = 지연 폭증

linger 100ms + batch 못 채워서 100ms 풀 대기 = 최대 100ms 지연. 실시간 시스템에서는 낮은 linger (5~10ms).

3. TLS + zero-copy 충돌

위에서 강조. 대규모 + TLS = kTLS 또는 TLS proxy.

4. 압축 ratio 모니터링

효과 없으면 비활성. broker 메트릭 MessagesInPerSec·BytesInPerSec 비율로 추정.

5. zstd 클라이언트 지원

오래된 클라이언트 = zstd 미지원. 도입 전 모든 producer/consumer 버전 확인.

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

  • Zero-Copy = sendfile() 시스템 콜로 user space 거치지 않음
  • 전통 = 4번 copy + 2번 context switch
  • Zero-copy = 1번 copy (DMA only)
  • Java = FileChannel.transferTo()
  • 효과 = 처리량 60~70% 향상, consumer 많을수록 큼
  • 함정 — TLS 활성 시 zero-copy 효과 감소 (user space 암호화)
  • 해결 = kTLS (kernel TLS) 또는 TLS proxy
  • Batching = MessageSet 단위로 수십~수백 메시지 묶음
  • 처리량 10~100배 향상
  • Producer 설정 = linger.ms + batch.size + compression.type
  • linger.ms = 지연 vs 처리량 trade-off
  • 같은 MessageSet 이 write·read·network 모두 통과 — 재batch 없음
  • Compression 4가지 = gzip · snappy · lz4 · zstd
  • gzip = 압축률 ↑ CPU ↑
  • snappy = 속도 ↑ CPU ↓
  • lz4 = 매우 빠름
  • zstd = 가장 균형 (Kafka 2.1+ 권장)
  • 기본 권장 = zstd
  • 효과 — JSON 5~10배 / 바이너리·이미지 1.0~1.5배
  • 이미 압축된 데이터 = 압축 X (CPU 낭비)
  • Per-MessageSet 압축 (Per-message 가 아닌) — 반복 패턴 전부 활용
  • 환경별 선택 — 같은 머신=none / 같은 DC=snappy/lz4 / 다른 DC=zstd / 인터넷=gzip/zstd
  • Producer 추가 효율 — async send, off-heap ByteBuffer, linger
  • Consumer 추가 효율 — fetch.min.bytes, max.poll.records
  • 함정 — linger 너무 큼 = 지연 폭증
  • 함정 — 이미 압축된 데이터에 압축
  • 함정 — TLS + zero-copy 충돌
  • 함정 — zstd 클라이언트 호환성 확인

공식 문서: Kafka Design — Efficiency 에서 자세한 사양을 확인할 수 있어요.

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

이전 글:

다음 글:

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

답글 남기기

error: Content is protected !!