내 TCP 처리량이 UDP 처리량보다 훨씬 큰 이유는 무엇입니까?

내 TCP 처리량이 UDP 처리량보다 훨씬 큰 이유는 무엇입니까?

나는 하드웨어나 커널 구성(모든 기본 설정, 새로운 OS 설치, Linux 커널 3.11 TCP/IP 스택)에 대해 특별한 작업을 하지 않았으며 TCP를 통해 초당 약 383만 개의 메시지를 보냈고 평균 0.75개에 불과했습니다. 초당 백만 개의 메시지가 UDP를 통해 전송됩니다. 이는 두 프로토콜에 대한 나의 기대와 완전히 반대되는 것 같습니다.

큰 차이가 발생하는 가장 큰 이유는 무엇입니까? Ubuntu 13.10에서 진단하는 방법은 무엇입니까?

#TCP RESULTS
Recv   Send    Send                          Utilization       Service Demand
Socket Socket  Message  Elapsed              Send     Recv     Send    Recv
Size   Size    Size     Time     Throughput  local    remote   local   remote
bytes  bytes   bytes    secs.    10^6bits/s  % S      % S      us/KB   us/KB

87380  65536     64    10.00      1963.43   32.96    17.09    5.500   2.852

#UDP RESULTS
Socket  Message  Elapsed      Messages                   CPU      Service
Size    Size     Time         Okay Errors   Throughput   Util     Demand
bytes   bytes    secs            #      #   10^6bits/sec % SS     us/KB

4194304      64   10.00     7491010      0      383.5     28.97    24.751
212992            10.00     1404941              71.9     25.03    21.381

이 테스트에는 10G 크로스오버 케이블을 통해 직접 연결된 두 개의 동일한 테스트 서버가 있습니다. 이 예에 사용된 NIC는 기본적으로 구성되어 마더보드의 PCIe 3.0 x8 슬롯에 연결되고 NUMA 컨트롤러를 통해 CPU와 통신하는 Intel X520입니다.

답변1

테스트 설정에 대한 세부 정보를 얻지 못하는 것 외에도 주요 문제는 64바이트의 메시지 크기를 사용하고 있다는 것입니다. 이는 일반적인 1500바이트 MTU와는 거리가 멀고 UDP를 매우 비효율적으로 만듭니다. TCP는 링크를 효율적으로 활용하기 위해 회선에서 여러 전송을 단일 패킷으로 결합하는 반면(TCP_NODELAY가 설정되지 않은 경우) 각 UDP 메시지는 단일 패킷이 됩니다. 숫자를 관점에서 보면 약 23개의 64바이트 메시지가 하나의 MTU 크기 TCP 패킷으로 결합되는 반면, UDP에는 동일한 양의 데이터에 대해 23개의 개별 패킷이 필요합니다. 이러한 각 패킷은 호스트에서 전송되고, 온라인으로 전송되고, 피어에서 수신되는 오버헤드를 나타냅니다. 귀하의 사례에서 볼 수 있듯이 하드웨어가 모든 패킷을 전송하고 수신할 만큼 빠르지 않기 때문에 UDP 패킷의 약 80%가 손실됩니다.

따라서 이 벤치마크에서 배울 수 있는 내용은 다음과 같습니다.

  • UDP는 신뢰할 수 없습니다(80% 패킷 손실).
  • 패킷 크기가 MTU보다 훨씬 작으면 UDP는 비효율적입니다.
  • TCP는 링크를 완전히 활용하도록 고도로 최적화되어 있습니다.

귀하의 기대에 따르면 UDP가 더 나을 것입니다. 모든 주요 파일 전송(ftp, http...)이 왜 TCP 기반 프로토콜을 사용하여 수행되는지 궁금한 적이 있습니까? 벤치마크를 보면 그 이유를 알 수 있습니다.

그렇다면 사람들은 왜 UDP를 사용하는 걸까요?

  • 실시간 데이터(예: VoIP)의 경우 오래된 메시지는 신경 쓰지 않으므로 발신자가 링크를 효율적으로 활용하기 위해 메시지를 더 큰 패킷으로 결합하는 것을 원하지 않습니다. 그리고 패킷이 너무 늦게 도착하는 것보다는 패킷 손실을 받아들이는 편이 낫습니다.
  • 대기 시간이 긴 링크(예: 위성)의 경우 TCP의 기본 동작은 링크를 효율적으로 사용하는 데 적합하지 않습니다. 따라서 이 경우 어떤 사람들은 UDP로 전환하고 TCP의 신뢰성 계층을 다시 구현하여 대기 시간이 긴 링크에 맞게 최적화하는 반면, 다른 사람들은 링크를 더 잘 활용하기 위해 기존 TCP 스택을 조정합니다.
  • 데이터 "삭제": 때로는 로그 메시지(syslog)와 같은 패킷 손실에 신경쓰지 않고 데이터를 보내는 것이 더 중요합니다.
  • 짧은 상호 작용: TCP를 사용하면 연결을 설정하고 상태를 유지해야 하며, 이는 클라이언트와 서버 모두에서 시간과 리소스를 소비합니다. 짧은 상호 작용(예: 짧은 요청 및 응답)의 경우 너무 많은 오버헤드가 발생할 수 있습니다. 따라서 DNS는 일반적으로 UDP를 사용하여 수행되지만 재시도는 UDP를 기반으로 구축됩니다.

관련 정보