Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

15장. Kafka 소켓 버퍼 크기 설정

Kafka는 네트워크를 통해 데이터를 주고받는 시스템입니다. 이때 Kafka 브로커는 보내거나 받는 데이터를 일시적으로 담아두는 소켓 버퍼(Socket Buffer) 를 사용합니다. 이 버퍼가 충분하지 않으면 빠른 네트워크에서도 데이터를 처리하지 못해 성능 저하나 데이터 유실이 발생할 수 있습니다.


15.1 소켓 버퍼란?

소켓 버퍼는 TCP 통신에서 데이터를 임시로 저장하는 공간입니다. Kafka는 데이터를 주고받을 때 이 공간을 거쳐 송수신을 하며, 버퍼가 작으면 처리 속도가 줄어들고, 버퍼가 충분하면 성능을 안정적으로 유지할 수 있습니다.


15.2 최소, 기본, 최대 버퍼 크기란?

TCP에서는 버퍼 크기를 다음 세 단계로 나눠서 관리합니다.

항목설명
최소 (min)절대 보장해야 하는 가장 작은 버퍼 크기 (일반적으로 4KB)
기본 (default)연결이 시작할 때 사용하는 기본 버퍼 크기 (Kafka에서는 512KB 권장)
최대 (max)네트워크 상황이 좋을 때 확장 가능한 최대 버퍼 크기 (안정적인 값은 2MB이지만, 실제 작업 부하에 근거하여 BDP 계산 기반으로 더 크게 설정 가능)

15.3 Kafka에서 기본 버퍼를 512KB로 설정하는 이유

  • Kafka는 1MB 이상의 데이터를 한 번에 주고받는 경우가 많습니다.
  • 기본 버퍼가 너무 작으면 TCP Slow Start 구간이 길어져 Throughput이 제대로 나오지 않습니다.
  • 512KB로 설정하면 1Gbps~10Gbps 환경에서 빠른 네트워크 부하에도 초기 성능이 안정적으로 유지됩니다.
  • 실무에서는 안정성을 중시해서 128KB로도 기본값을 줄일 수 있지만, Kafka의 대량 메시지 처리 특성상 512KB 이상을 기본으로 설정하는 것이 권장됩니다.

15.4 버퍼 크기는 어떻게 정할까? (BDP 기반)

버퍼 크기를 정할 때 사용하는 기준이 바로 BDP(Bandwidth Delay Product) 입니다.

📘 BDP란?

BDP는 “네트워크 대역폭과 지연 시간(RTT)을 고려하여, 버퍼에 저장할 수 있는 최적의 데이터 양“입니다.

공식:

BDP = (네트워크 속도(Gbps) × 왕복 지연 시간(RTT, 초)) ÷ 8

bit 단위 대역폭을 byte로 바꾸기 위해 ÷ 8을 합니다.

네트워크를 충분히 활용하려면 최소 BDP만큼의 버퍼가 필요하고, 실무에서는 BDP × 1.5~2배 여유를 주는 것이 일반적입니다.


15.5 버퍼 크기 결정 흐름

TCP 소켓 버퍼 크기는 다음 흐름으로 결정됩니다.

  1. 소켓 생성 시 기본값 적용

    • net.core.rmem_default (수신 버퍼 기본값)
    • net.core.wmem_default (송신 버퍼 기본값)
  2. TCP 연결 후 네트워크 상황에 따라 자동 확장

    • net.ipv4.tcp_rmem (수신 버퍼 최소/기본/최대 범위)
    • net.ipv4.tcp_wmem (송신 버퍼 최소/기본/최대 범위)
  3. 소켓 버퍼 크기 확장 시 최대 한도 제한

    • net.core.rmem_max, net.core.wmem_max 값을 넘지 못함
  4. 서버 전체 TCP 메모리 총량 제한

    • net.ipv4.tcp_mem에 설정된 값 이상으로는 전체 TCP 소켓 메모리를 사용할 수 없음
    • tcp_mem 값은 페이지 단위(보통 4KB)로 설정되며, 경고선(soft limit)과 절대 한계(hard limit)를 초과할 경우 새 소켓 생성이나 버퍼 확장이 거부될 수 있음
    • TCP 소켓 하나는 송신(wmem) 버퍼와 수신(rmem) 버퍼를 모두 사용합니다.
    • 서버 전체의 모든 소켓의 송신/수신 버퍼 사용량 합계를 기준으로 net.ipv4.tcp_mem 리밋이 적용됩니다.

net.ipv4.tcp_mem 세 값의 의미 및 설정 기준

의미설정 기준
첫 번째 값 (경고 없이 허용)이 범위까지는 정상 운영예상 TCP 메모리 사용량
두 번째 값 (소프트 리밋)초과 시 커널이 버퍼 회수(cleanup) 시작경고 없이 허용 × 1.5배
세 번째 값 (하드 리밋)초과 시 소켓 생성 실패, 버퍼 확장 거부소프트 리밋 × 2배

📘 Kafka 환경에서는 어떻게 설정할까?

Kafka는 송신과 수신 트래픽이 대체로 비슷하게 발생하는 구조입니다.

따라서 전체 TCP 메모리 소모량을 다음 기준으로 예상하고 설정합니다.

  1. NIC 속도와 RTT를 기반으로 BDP를 계산한다.
  2. 활성 소켓 수를 고려하여 예상 TCP 메모리 소비량을 구한다.
  3. 송수신 합산을 고려해 예상량 × 2배로 계산한다.
  4. 여유를 주기 위해 예상 사용량의 1.5배 이상으로 소프트 리밋을 설정한다.
  5. 소프트 리밋의 약 2배를 하드 리밋으로 설정한다.

이렇게 설정하면 Kafka 브로커가 다수의 프로듀서와 컨슈머를 동시에 처리할 때에도 안정적인 네트워크 성능을 유지할 수 있습니다.


15.6 다수의 소켓 연결 시 버퍼 크기 조정

Kafka는 여러 프로듀서 및 컨슈머와 동시에 TCP 연결을 유지합니다. 따라서 단일 소켓이 NIC의 전체 대역폭을 모두 사용할 수 없으므로, 연결된 소켓 수를 고려하여 버퍼를 조정해야 합니다.

  • NIC 속도가 10Gbps라면 송신과 수신 각각 10Gbps이며, 동시에 사용 가능합니다.
  • 총 예상되는 프로듀서 및 컨슈머 소켓 수로 NIC 속도를 나누어 단일 소켓당 버퍼 크기를 산정해야 합니다.

예시 (RTT 50ms, NIC 10Gbps):

  • BDP = 1250MB/s × 0.05초 = 62.5MB
  • 프로듀서 소켓 100개: 단일 소켓당 수신 버퍼 최소 크기 ≈ 62.5MB ÷ 100 ≈ 0.625MB
  • 컨슈머 소켓 200개: 단일 소켓당 송신 버퍼 최소 크기 ≈ 62.5MB ÷ 200 ≈ 0.3125MB

15.7 설정 방법

Linux 커널 설정 (/etc/sysctl.conf)

# 소켓 기본 버퍼 크기 (512KB)
net.core.rmem_default = 524288
net.core.wmem_default = 524288

# 소켓 최대 버퍼 크기 (2MB)
net.core.rmem_max = 2097152
net.core.wmem_max = 2097152

# TCP 동적 버퍼 크기 (min, default, max)
net.ipv4.tcp_rmem = 4096 524288 2097152
net.ipv4.tcp_wmem = 4096 524288 2097152

# TCP 메모리 총량 제한 (페이지 단위)
net.ipv4.tcp_mem = 65536 131072 262144

tcp_mem 설정은 순서대로 (경고 없이 허용되는 값, 소프트 리밋, 하드 리밋)이며, 각 값은 페이지 수입니다. 예를 들어 65536 페이지는 약 256MB(65536 × 4KB)입니다.

적용 명령어:

sudo sysctl -p

Kafka 설정 (server.properties)

# Kafka 소켓 버퍼 크기 설정
socket.receive.buffer.bytes=2097152
socket.send.buffer.bytes=2097152

BDP에 따라 더 큰 값을 적용할 수도 있습니다.

※ 참고: Kafka 브로커 설정(socket.receive.buffer.bytes, socket.send.buffer.bytes)은 OS 커널 설정(net.core.rmem_max, net.core.wmem_max)의 최대값을 초과할 수 없습니다. Kafka가 요청한 값이 커널 최대값을 넘으면 커널이 강제로 잘라 적용합니다. 따라서 OS와 Kafka 설정을 함께 조정해야 합니다.


15.8 확인 및 측정 팁

  • RTT 측정: ping [IP주소]
  • NIC 속도 확인: ethtool [인터페이스명]
  • 현재 소켓 버퍼 확인: ss -tnm 명령어로 소켓별 버퍼 크기 확인 가능

※ 인터페이스명은 ip addr 또는 ip link show 명령어로 실제 서버에 설정된 이름을 확인한 후 사용해야 합니다. (예: eth0, ens5 등)


15.9 추가적으로 고려해야 할 TCP 관련 설정

net.ipv4.tcp_window_scaling

TCP 윈도우 스케일링 기능을 활성화하는 옵션입니다.

net.ipv4.tcp_window_scaling = 1

이 값을 1로 설정하면 클라이언트가 데이터를 더 효율적으로 전송할 수 있으며, 브로커도 수신 데이터를 더 잘 버퍼링할 수 있습니다. 빠른 네트워크 환경에서는 필수로 켜야 하는 옵션입니다.

net.ipv4.tcp_max_sync_backlog

브로커가 동시에 처리할 수 있는 TCP 연결 요청 대기열 크기를 설정하는 옵션입니다.

net.ipv4.tcp_max_sync_backlog = 4096

기본값은 1024로 작기 때문에, Kafka 브로커처럼 많은 클라이언트 연결을 받을 경우 4096 이상으로 설정하는 것이 좋습니다.

net.core.netdev_max_backlog

네트워크 인터페이스가 처리하지 못한 패킷을 임시로 커널 큐에 쌓아두는 최대 수를 정하는 옵션입니다.

net.core.netdev_max_backlog = 5000

기본값은 1000인데, 멀티 기가비트 NIC 환경에서는 큐 길이를 크게 늘려야 네트워크 트래픽 급증 시에도 패킷 손실을 방지할 수 있습니다.