TCP Nagle 알고리즘

2025. 12. 26. 18:10·Network

1. TCP Nagle 알고리즘

1.1. 왜 필요했는가?

1980년대 초반 ARPANET 네트워크에서 작은 크기의 패킷이 과도하게 생성되어 네트워크 효율이 급격히 저하되는 문제가 발생했습니다. 특히 Telnet과 같은 대화형 서비스에서는 사용자가 입력한 1바이트의 데이터를 전송하기 위해 20바이트의 TCP 헤더와 20바이트의 IP 헤더가 결합되어 총 41바이트의 패킷이 생성되었습니다. 이로 인해 실제 데이터 대비 헤더가 40배 더 커지는 비효율이 발생했으며, 이러한 작은 패킷들이 네트워크 대역폭을 점유하여 혼잡을 가중시켰습니다. John Nagle은 이러한 네트워크 혼잡 제어 및 대역폭 효율화를 위해 1984년 RFC 896을 통해 Nagle 알고리즘을 제안했습니다.

1.2. 동작 원리

Nagle 알고리즘은 전송할 데이터를 일정 크기만큼 모아서 한꺼번에 보내는 방식을 취합니다. 이때 기준이 되는 단위는 MSS(Maximum Segment Size)입니다. MSS는 TCP 세그먼트가 담을 수 있는 최대 데이터 크기를 의미하며, 일반적으로 이더넷 환경에서는 MTU(1500바이트)에서 IP 및 TCP 헤더 크기를 제외한 1460바이트로 설정됩니다.

RFC 896에서는 Nagle 알고리즘을 다음과 같이 정의합니다.

"inhibit the sending of new TCP segments when new outgoing data arrives from the user if any previously transmitted data on the connection remains unacknowledged."

 

즉, 이전에 전송한 데이터에 대한 확인 응답(ACK)을 받지 못했다면, 새로 도착한 데이터를 새로운 TCP 세그먼트로 보내지 않는다는 뜻입니다. 이를 의사코드로 나타내면 다음과 같습니다.

if there is new data to send then
    if the window size ≥ MSS and available data is ≥ MSS then
        send complete MSS segment now
    else
        if there is unconfirmed data still in the pipe then
            enqueue data in the buffer until an acknowledge is received
        else
            send data immediately
        end if
    end if
end if

 

2. TCP_NODELAY

2.1. 설명

TCP_NODELAY는 TCP 소켓에서 Nagle 알고리즘을 비활성화하기 위해 사용되는 옵션입니다. 이 옵션을 활성화하면 TCP 스택은 Nagle 알고리즘을 비활성화하여 데이터 크기와 관계없이 send() 함수가 호출되는 즉시 네트워크로 패킷을 전송합니다. 즉, 데이터가 MSS만큼 모이거나 이전 패킷에 대한 ACK이 올 때까지 기다리지 않고 즉시 전송을 수행하여 지연 시간을 최소화합니다.

TCP_NODELAY의 기본값은 0(비활성화)입니다. 즉, 기본적으로 Nagle 알고리즘이 활성화되어 있으며, 명시적으로 활성화해야 Nagle 알고리즘이 비활성화됩니다.

2.2. 설정 방법

Go

package main

import "net"

conn, _ := net.Dial("tcp", "localhost:8080")
tcpConn := conn.(*net.TCPConn)

// TCP_NODELAY 활성화
tcpConn.SetNoDelay(true)

// TCP_NODELAY 비활성화
tcpConn.SetNoDelay(false)

 

3. 언제 어떤것을 사용해야 하는가

3.1. Nagle 알고리즘을 써야하는 경우

Nagle 알고리즘은 네트워크의 대역폭을 효율적으로 사용해야 하고, 한 번에 많은 데이터를 보내는 처리량(Throughput) 중심의 서비스에 적합합니다. 예를 들어, 대용량 파일 전송, 배치 데이터 처리, 로그 수집 시스템 등에서는 개별 패킷의 즉각적인 전송보다 전체적인 네트워크 효율성이 더 중요합니다.

3.2. TCP_NODELAY를 활성화해야 하는 경우

TCP_NODELAY는 데이터 크기와 상관없이 즉각적인 반응이 필요한 저지연(Low Latency) 중심의 서비스에 필수적입니다. 온라인 게임, 실시간 채팅, REST API, 데이터베이스 쿼리, 분산 시스템의 RPC 통신 등 사용자나 시스템이 빠른 응답을 기대하는 환경에서는 TCP_NODELAY 활성화가 권장됩니다.

3.3. 기타 유의사항

  • Delayed ACK와의 상호작용
    Nagle 알고리즘과 TCP Delayed ACK이 동시에 활성화되면 심각한 성능 저하가 발생할 수 있습니다. Delayed ACK은 수신측에서 ACK를 즉시 보내지 않고 일정 시간 지연시켜 네트워크 효율을 높이는 최적화 기법입니다. 송신측은 Nagle 알고리즘으로 인해 ACK를 기다리고, 수신측은 Delayed ACK으로 인해 ACK 전송을 지연시킴으로써 예상치 못한 문제가 발생할 수 있습니다.
  • 현대 네트워크 환경의 변화
    과거와 달리 현재는 네트워크 대역폭이 매우 넉넉해졌습니다. 따라서 패킷 오버헤드를 줄이는 것보다 사용자의 빠른 경험(Low Latency)이 훨씬 중요해졌습니다. 이러한 이유로 Nginx, Redis, Node.js, HTTP/2, gRPC 등 대부분의 현대적 서버 엔진과 프레임워크들은 TCP_NODELAY를 기본적으로 활성화하여 배포하고 있습니다.

 

4. 참고

  • https://www.rfc-editor.org/rfc/rfc896
  • https://docs.redhat.com/ko/documentation/red_hat_enterprise_linux_for_real_time/8/html/optimizing_rhel_8_for_real_time_for_low_latency_operation/assembly_improving-network-latency-using-tcp_nodelay_optimizing-rhel8-for-real-time-for-low-latency-operation
  • https://en.wikipedia.org/wiki/Nagle%27s_algorithm#Large-write_case
  • https://news.hada.io/topic?id=14740
'Network' 카테고리의 다른 글
  • 오픈소스 네트워킹
  • VxLAN
  • ZeroTier 소개
  • NAT(Network Address Trasition)
yeseong9769
yeseong9769
  • yeseong9769
    ys.tech.blog
    yeseong9769
  • 전체
    오늘
    어제
    • 분류 전체보기 (47)
      • Artificial Intelligence (6)
      • BigData (2)
      • Cloud (12)
      • Linux (3)
      • Network (9)
      • Mobile (1)
        • Android (1)
      • 정보보안 (9)
        • Blockchain (4)
  • 블로그 메뉴

    • 홈
    • 태그
  • 태그

    anvil
    AWS
    bedrock
    Bitcoin
    boto3
    Calico
    cast
    Ceph
    cloudnative
    conda
  • hELLO· Designed By정상우.v4.10.5
yeseong9769
TCP Nagle 알고리즘
상단으로

티스토리툴바