TCP의 비밀 병기: 네트워크 흐름 제어 및 네트워크 혼잡 제어

TCP 신뢰성 전송
TCP 프로토콜은 신뢰할 수 있는 전송 프로토콜로 널리 알려져 있지만, 어떻게 전송의 신뢰성을 보장하는 것일까요?

안정적인 데이터 전송을 위해서는 데이터 손상, 손실, 중복, 순서가 뒤바뀐 샤드 등 여러 요소를 고려해야 합니다. 이러한 문제들을 해결하지 못하면 안정적인 데이터 전송은 불가능합니다.

따라서 TCP는 안정적인 전송을 위해 순번, 확인 응답, 재전송 제어, 연결 관리 및 윈도우 제어와 같은 메커니즘을 사용합니다.

본 논문에서는 TCP의 슬라이딩 윈도우, 흐름 제어 및 혼잡 제어에 초점을 맞출 것입니다. 재전송 메커니즘은 다음 절에서 별도로 다룹니다.

네트워크 흐름 제어
네트워크 흐름 제어 또는 네트워크 트래픽 제어는 생산자와 소비자 간의 미묘한 관계를 나타내는 개념입니다. 업무나 면접에서 이러한 상황을 자주 접했을 것입니다. 생산자의 생산 능력이 소비자의 소비 능력을 크게 초과하면 큐가 무한정 커지게 됩니다. 더 심각한 경우로는 RabbitMQ 메시지가 너무 많이 쌓이면 전체 MQ 서버의 성능이 저하될 수 있다는 것을 알고 계실 것입니다. TCP도 마찬가지입니다. 제대로 관리하지 않으면 네트워크에 너무 많은 메시지가 전송되어 소비자가 처리 용량을 초과하게 되고, 생산자는 계속해서 중복 메시지를 전송하여 네트워크 성능에 심각한 영향을 미칩니다.

이러한 현상을 해결하기 위해 TCP는 송신자가 수신자의 실제 수신 용량에 따라 전송하는 데이터 양을 제어할 수 있는 메커니즘, 즉 흐름 제어를 제공합니다. 수신자는 수신 윈도우를, 송신자는 송신 윈도우를 유지합니다. 이러한 윈도우는 하나의 TCP 연결에만 적용되며, 모든 연결이 윈도우를 공유하는 것은 아닙니다.

TCP는 수신 윈도우 변수를 사용하여 흐름 제어를 제공합니다. 수신 윈도우는 송신자에게 캐시 공간에 얼마나 남아 있는지 알려줍니다. 송신자는 수신자의 실제 수용 용량에 따라 전송하는 데이터 양을 제어합니다.

수신 호스트는 송신자에게 자신이 수신할 수 있는 데이터 크기를 알리고, 송신자는 이 한도까지 데이터를 전송합니다. 이 한도가 바로 윈도우 크기입니다. TCP 헤더를 기억하시나요? 수신 윈도우 필드는 수신자가 수신할 수 있거나 수신하고자 하는 바이트 수를 나타내는 데 사용됩니다.

송신 호스트는 주기적으로 윈도우 프로브 패킷을 전송하여 수신 호스트가 데이터를 수신할 수 있는지 여부를 확인합니다. 수신 호스트의 버퍼가 오버플로우될 위험이 있는 경우, 윈도우 크기를 더 작은 값으로 설정하여 송신 호스트에게 전송량을 조절하도록 지시합니다.

다음은 네트워크 흐름 제어 다이어그램입니다.

교통 통제

네트워크 혼잡 제어
혼잡 제어를 소개하기 전에, 수신 윈도우와 송신 윈도우 외에도 혼잡 윈도우라는 것이 있다는 것을 이해해야 합니다. 혼잡 윈도우는 주로 송신자가 수신 윈도우로 데이터를 전송하기 시작하는 속도를 결정하는 문제를 해결하는 데 사용됩니다. 따라서 혼잡 윈도우 역시 TCP 송신자가 관리합니다. 너무 적거나 너무 많은 데이터를 전송하는 것은 바람직하지 않으므로, 적절한 데이터 양을 결정하는 알고리즘이 필요하며, 이것이 바로 혼잡 윈도우 개념의 핵심입니다.

이전 네트워크 흐름 제어 방식에서는 송신자가 수신자의 캐시를 데이터로 채우는 것을 방지했지만, 네트워크 내부에서 무슨 일이 일어나고 있는지는 알 수 없었습니다. 일반적으로 컴퓨터 네트워크는 공유 환경에 있기 때문에 다른 호스트와의 통신으로 인해 네트워크 혼잡이 발생할 수 있습니다.

네트워크가 혼잡한 상태에서 대량의 패킷이 지속적으로 전송되면 지연 및 패킷 손실과 같은 문제가 발생할 수 있습니다. 이때 TCP는 데이터를 재전송하지만, 재전송은 네트워크 부하를 증가시켜 지연과 패킷 손실을 더욱 심화시킵니다. 이러한 악순환이 계속될 수 있습니다.

따라서 TCP는 네트워크에서 발생하는 상황을 무시할 수 없습니다. 네트워크가 혼잡해지면 TCP는 전송하는 데이터 양을 줄임으로써 스스로를 희생합니다.

따라서 송신자가 네트워크 전체에 데이터를 과도하게 전송하는 것을 방지하기 위해 혼잡 제어 방식이 제안되었습니다. 송신자가 전송해야 하는 데이터 양을 조절하기 위해 TCP는 혼잡 윈도우라는 개념을 정의했습니다. 혼잡 제어 알고리즘은 네트워크 혼잡도에 따라 혼잡 윈도우의 크기를 조정하여 송신자가 전송하는 데이터 양을 제어합니다.

혼잡 윈도우란 무엇인가요? 이것이 송신 윈도우와 어떤 관련이 있나요?

혼잡 윈도우는 송신자가 관리할 수 있는 데이터 양을 결정하는 상태 변수입니다. 혼잡 윈도우는 네트워크 혼잡 수준에 따라 동적으로 변경됩니다.

송신 윈도우는 송신자와 수신자 간에 합의된 윈도우 크기로, 수신자가 수신할 수 있는 데이터 양을 나타냅니다. 혼잡 윈도우와 송신 윈도우는 서로 관련되어 있으며, 송신 윈도우는 일반적으로 혼잡 윈도우와 수신 윈도우 중 최소값과 같습니다. 즉, swnd = min(cwnd, rwnd)입니다.

혼잡 윈도우 cwnd는 다음과 같이 변경됩니다.

네트워크에 혼잡이 발생하지 않는 경우, 즉 재전송 시간 초과가 발생하지 않는 경우, 혼잡 윈도우가 증가합니다.

네트워크에 혼잡이 발생하면 혼잡 윈도우가 감소합니다.

송신자는 지정된 시간 내에 ACK 확인 응답 패킷이 수신되는지 여부를 관찰하여 네트워크 혼잡 여부를 판단합니다. 송신자가 지정된 시간 내에 ACK 확인 응답 패킷을 수신하지 못하면 네트워크가 혼잡한 것으로 간주합니다.

혼잡 윈도우 외에도 TCP 혼잡 제어 알고리즘에 대해 논의해 보겠습니다. TCP 혼잡 제어 알고리즘은 크게 세 부분으로 구성됩니다.

느린 시작:초기에 cwnd 혼잡 윈도우는 비교적 작으며, 송신자는 네트워크 용량에 빠르게 적응하기 위해 혼잡 윈도우를 기하급수적으로 증가시킵니다.
교통 체증 회피:혼잡 윈도우가 특정 임계값을 초과하면 송신자는 혼잡 윈도우의 증가 속도를 늦추고 네트워크 과부하를 방지하기 위해 혼잡 윈도우를 선형적으로 증가시킵니다.
빠른 회복:혼잡이 발생하면 송신자는 혼잡 윈도우를 절반으로 줄이고 빠른 복구 상태로 진입하여 수신된 중복 ACK를 통해 네트워크 복구 위치를 파악한 후 혼잡 윈도우를 다시 증가시킵니다.

느린 시작
TCP 연결이 설정되면 혼잡 윈도우 cwnd는 초기에는 최소 MSS(최대 세그먼트 크기) 값으로 설정됩니다. 따라서 초기 전송 속도는 약 MSS/RTT 바이트/초가 됩니다. 실제 사용 가능한 대역폭은 일반적으로 MSS/RTT보다 훨씬 크기 때문에 TCP는 최적의 전송 속도를 찾으려 하며, 이는 슬로우 스타트를 통해 달성할 수 있습니다.

슬로우 스타트 과정에서 혼잡 윈도우 cwnd 값은 1 MSS로 초기화되고, 전송된 패킷 세그먼트가 수신 확인될 때마다 cwnd 값은 1 MSS씩 증가하여 2 MSS가 됩니다. 이후에는 패킷 세그먼트 전송이 성공할 때마다 cwnd 값이 두 배씩 증가하는 방식으로 계속 증가합니다. 구체적인 증가 과정은 다음 그림에 나와 있습니다.

 네트워크 혼잡 제어

하지만 송금률은 항상 증가할 수는 없습니다. 언젠가는 증가가 멈춰야 합니다. 그렇다면 송금률 증가는 언제 끝날까요? 슬로우 스타트 전략은 일반적으로 다음과 같은 몇 가지 방식으로 송금률 증가를 종료합니다.

첫 번째 방법은 슬로우 스타트 전송 과정 중 패킷 손실이 발생하는 경우입니다. 패킷 손실이 발생하면 TCP는 송신측 혼잡 윈도우 cwnd를 1로 설정하고 슬로우 스타트 프로세스를 재시작합니다. 이때 슬로우 스타트 임계값 ssthresh라는 개념이 도입되는데, 그 초기값은 패킷 손실을 발생시킨 cwnd 값의 절반입니다. 즉, 혼잡이 감지되면 ssthresh 값은 윈도우 값의 절반이 됩니다.

두 번째 방법은 슬로우 스타트 임계값 ssthresh와 직접적으로 연관시키는 것입니다. ssthresh 값은 혼잡이 감지될 때 윈도우 값의 절반이므로, cwnd가 ssthresh보다 클 경우 윈도우 값이 두 배가 될 때마다 패킷 손실이 발생할 수 있습니다. 따라서 cwnd를 ssthresh와 같게 설정하는 것이 가장 좋습니다. 이렇게 하면 TCP가 혼잡 제어 모드로 전환되어 슬로우 스타트가 종료됩니다.

슬로우 스타트가 종료되는 마지막 방법은 중복된 ACK 패킷이 세 개 감지될 경우입니다. TCP는 빠른 재전송을 수행하고 복구 상태로 진입합니다. (ACK 패킷이 세 개 발생하는 이유가 명확하지 않다면, 재전송 메커니즘 부분에서 별도로 설명하겠습니다.)

교통 혼잡 회피
TCP가 혼잡 제어 상태에 진입하면 cwnd 값은 혼잡 임계값 ssthresh의 절반으로 설정됩니다. 이는 패킷 세그먼트가 수신될 때마다 cwnd 값이 두 배로 증가하는 것이 아니라, 전송이 완료될 때마다 최대 패킷 세그먼트 길이(MSS)만큼만 증가하는 비교적 보수적인 방식을 채택한다는 것을 의미합니다. 예를 들어, 10개의 패킷 세그먼트에 대한 확인 응답(ACK)이 수신되더라도 cwnd 값은 MSS만큼만 증가합니다. 이는 선형 증가 모델이며, 증가량에는 상한선이 있습니다. 패킷 손실이 발생하면 cwnd 값은 MSS로 변경되고, ssthresh 값은 cwnd의 절반으로 설정됩니다. 또는 중복된 ACK 응답이 3개 수신되면 MSS 증가가 중지됩니다. cwnd 값을 절반으로 줄인 후에도 중복된 ACK 응답이 3개 수신되면 ssthresh 값은 cwnd의 절반으로 기록되고 빠른 복구 상태로 진입합니다.

빠른 회복
고속 복구 상태에서는 수신된 중복 ACK(즉, 순차적으로 도착하지 않은 ACK)마다 혼잡 윈도우 cwnd 값이 1 MSS씩 증가합니다. 이는 네트워크에서 성공적으로 전송된 패킷 세그먼트를 활용하여 전송 효율을 최대한 향상시키기 위한 것입니다.

손실된 패킷 세그먼트에 대한 ACK가 도착하면 TCP는 cwnd 값을 감소시킨 후 혼잡 회피 상태로 진입합니다. 이는 혼잡 윈도우의 크기를 제어하고 네트워크 혼잡이 더 이상 증가하는 것을 방지하기 위한 것입니다.

혼잡 제어 상태 이후 타임아웃이 발생하면 네트워크 상태가 더욱 심각해져 TCP는 혼잡 회피 상태에서 슬로우 스타트 상태로 전환됩니다. 이 경우 혼잡 윈도우 cwnd 값은 최대 패킷 세그먼트 길이인 1 MSS로 설정되고, 슬로우 스타트 임계값 ssthresh 값은 cwnd의 절반으로 설정됩니다. 이는 네트워크가 복구된 후 혼잡 윈도우 크기를 점진적으로 다시 증가시켜 전송 속도와 네트워크 혼잡도 사이의 균형을 유지하기 위한 것입니다.

요약
신뢰할 수 있는 전송 프로토콜인 TCP는 순번, 확인 응답, 재전송 제어, 연결 관리 및 윈도우 제어를 통해 안정적인 전송을 구현합니다. 이 중 흐름 제어 메커니즘은 수신자의 실제 수신 용량에 따라 송신자가 전송하는 데이터 양을 조절하여 네트워크 혼잡 및 성능 저하 문제를 방지합니다. 혼잡 제어 메커니즘은 송신자가 전송하는 데이터 양을 조정하여 네트워크 혼잡 발생을 방지합니다. 혼잡 윈도우와 전송 윈도우는 서로 연관되어 있으며, 혼잡 윈도우의 크기를 동적으로 조정하여 송신자의 데이터 양을 제어합니다. TCP 혼잡 제어 알고리즘은 슬로우 스타트, 혼잡 회피, 빠른 복구의 세 가지 주요 부분으로 구성되며, 각기 다른 전략을 통해 혼잡 윈도우의 크기를 조정하여 네트워크 용량 및 혼잡 정도에 적응합니다.

다음 절에서는 TCP의 재전송 메커니즘을 자세히 살펴보겠습니다. 재전송 메커니즘은 TCP에서 신뢰할 수 있는 데이터 전송을 구현하는 데 중요한 부분입니다. 손실되거나 손상되었거나 지연된 데이터를 재전송하여 데이터의 안정적인 전송을 보장합니다. 다음 절에서는 재전송 메커니즘의 구현 원리와 전략을 자세히 소개하고 분석할 예정입니다. 기대해 주세요!


게시 시간: 2025년 2월 24일