Linux TCP 속도 저하/패킷 손실을 디버깅하는 방법

Linux TCP 속도 저하/패킷 손실을 디버깅하는 방법

약 200KByte/초로 느려지는 일부 특정 네트워크 경로를 추적하려고 합니다. 다음 을 포함한 다양한 테스트를 통해 이 성능을 확인했습니다 scp.rsynciperf3

$ iperf3 -c 157.130.91.64 -R
Connecting to host 157.130.91.64, port 5201
Reverse mode, remote host 157.130.91.64 is sending
[  5] local 172.16.1.177 port 47862 connected to 157.130.91.64 port 5201
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec   274 KBytes  2.25 Mbits/sec
[  5]   1.00-2.00   sec   199 KBytes  1.63 Mbits/sec
[  5]   2.00-3.00   sec   202 KBytes  1.66 Mbits/sec
[  5]   3.00-4.00   sec   198 KBytes  1.62 Mbits/sec
[  5]   4.00-5.00   sec   195 KBytes  1.60 Mbits/sec
[  5]   5.00-6.00   sec   184 KBytes  1.51 Mbits/sec
[  5]   6.00-7.00   sec   195 KBytes  1.60 Mbits/sec
[  5]   7.00-8.00   sec   209 KBytes  1.71 Mbits/sec
[  5]   8.00-9.00   sec   192 KBytes  1.58 Mbits/sec
[  5]   9.00-10.00  sec   187 KBytes  1.53 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  2.31 MBytes  1.94 Mbits/sec   65             sender
[  5]   0.00-10.00  sec  1.99 MBytes  1.67 Mbits/sec                  receiver

iperf Done.

문제의 호스트는 타사 호스팅 제공업체에 있습니다. 공동 배치된 데이터 센터에 데이터를 다운로드하고 있습니다.

아직은 공통분모가 무엇인지 잘 모르겠습니다. 내 쪽 네트워크에는 두 개의 라우터, VM 호스트, 가상 머신이 있습니다. VM 호스트와 가장 안쪽 라우터는 VxLAN(즉, ip link add vxlan100 type vxlan...을 통해)을 사용하고 있는데 이것이 문제의 일부인 것으로 의심됩니다. 그러나 VxLAN을 통해 직접 랙 내의 다양한 위치에서 1Gbit 속도(iperf3를 사용하여 측정)를 얻을 수 있습니다. 예를 제공할 수 있지만 위와 같이 읽혀지며 훨씬 더 빠르게 읽혀집니다.

이 시점에서 유일한 단서는 200KByte/sec 전송이 실행되는 동안 트래픽을 캡처하면 Wireshark에서 TCP 재전송, TCP out-of-order 및 TCP Dup ACK 메시지 발생률이 더 높다는 것입니다. 이는 속도 저하와 관련이 있는 것 같습니다. 더 빠른 속도로 실행되는 캡처 트래픽에도 일부 TCP 재전송이 있지만 전송되는 트래픽에 비해 훨씬 적습니다.

제 질문은 패킷 누락의 원인을 찾기 위해 어떻게 디버깅할 수 있느냐는 것입니다. 특별히 확인해야 할 사항이 있나요? 어느 정도 패킷 손실로 인해 속도가 느려지는 것 같은데 어디서 찾을 수 있는지 모르겠습니다. 패킷 손실 자체는 느린 속도에서는 발생하지 않으며, 내 데이터 센터 내의 시스템 내에서도 발생하지 않습니다. 이러한 일이 발생할 것으로 예측할 수 있는 정확한 단일 장소는 없는 것 같습니다. 단지 내 데이터 센터의 가상 머신과 다른 데이터 센터의 다른 머신 사이에서 확실히 발생한다는 것뿐입니다. (그리고 이 다른 머신은 AWS와 같은 다른 장소로의 전송 속도가 더 높기 때문에 제3자 머신입니다. 제가 확인한 결과 네트워크로 전송할 때만 재생됩니다.)

어떤 아이디어가 있나요?

답변1

후손을 위해 이 문제를 어떻게 해결했는지에 대한 후속 답변을 게시하겠습니다. 나는 패킷 손실을 추적하려는 다른 사람들에게 도움이 될 수 있는 몇 가지 단계를 수행했습니다.

iperf3문제를 재현하기 위한 훌륭한 도구입니다.

섬기는 사람:iperf3 -s

클라이언트: ( iperf3 -c 157.130.91.64 -R또는 -R 없이 다른 방향으로 이동)

tcpdump그런 다음 패킷을 파일에 기록 했지만액세스할 수 있는 모든 지점에서 동시에 이 패킷 캡처를 실행합니다.. 호스트 사이에서 두 개의 Linux 라우터를 제어하고 VxLAN이 자체 인터페이스를 사용했기 때문에 결국 9개의 별도 지점을 얻었고 다음 명령을 사용하여 캡처했습니다.

tcpdump -w /tmp/machineX-eno1.cap

그런 다음 scp이 파일을 데스크탑에서 편집하고 부리토를 얻은 다음 Wireshark UI를 사용하여 9개의 서로 다른 샘플을 샅샅이 뒤져 스트리밍 패킷이 손실되는 정확한 위치를 알아냈습니다. (Wireshark는 UI로서 매우 훌륭하여 내부의 TCP 흐름을 볼 수 있도록 VxLAN 트래픽 압축 해제와 같은 작업도 수행할 수 있습니다. 하지만 tcpdump복사하여 붙여넣을 수 있는 멋진 텍스트 출력을 제공하므로 아래 예에서는 이를 사용 하겠습니다. .)

이제 링크가 포화되면 패킷 손실이 발생하는 것이 정상이지만 이 경우 예상보다 훨씬 빨리 손실이 발생합니다. TCP의 경우 "창"은 "승인이 필요하기 전에 전송할 수 있는 데이터의 양"을 추적하는 데 사용됩니다. 창은 적당한 크기로 시작하여 성능이 향상되고 패킷 손실이 없어짐에 따라 증가합니다. 모든 상황에서 첫 번째 손실된 패킷은 스트림에서 수 메가바이트만큼 발생합니다. 그러나 문제의 경우 패킷 손실이 발생하기 전에 약 260k 데이터만 스트림으로 전송할 수 있습니다.

내 예에서 볼 수 있듯이 tcpdump -n -r [filename]클라이언트 시스템에서 패킷 손실은 다음과 같습니다.

13:40:00.344219 IP 157.130.91.64.5201 > 172.16.1.177.50298: Flags [.], seq 246161:253401, ack 38, win 227, options [nop,nop,TS val 4032728542 ecr 187200696], length 7240
13:40:00.344232 IP 172.16.1.177.50298 > 157.130.91.64.5201: Flags [.], ack 253401, win 2745, options [nop,nop,TS val 187200770 ecr 4032728542], length 0
13:40:00.345642 IP 157.130.91.64.5201 > 172.16.1.177.50298: Flags [.], seq 253401:260641, ack 38, win 227, options [nop,nop,TS val 4032728542 ecr 187200696], length 7240
13:40:00.345673 IP 172.16.1.177.50298 > 157.130.91.64.5201: Flags [.], ack 260641, win 2858, options [nop,nop,TS val 187200771 ecr 4032728542], length 0
13:40:00.345772 IP 157.130.91.64.5201 > 172.16.1.177.50298: Flags [.], seq 260641:269329, ack 38, win 227, options [nop,nop,TS val 4032728542 ecr 187200696], length 8688

위의 마지막 패킷까지는 모든 것이 괜찮아 보입니다. 표시된 것처럼 스트림의 오프셋 269329로 전송되는 것을 볼 수 있습니다 seq 260641:269329. 문제가 다음 패킷을 기다리고 있습니다.

13:40:00.345772 IP 157.130.91.64.5201 > 172.16.1.177.50298: Flags [.], seq 301185:304081, ack 38, win 227, options [nop,nop,TS val 4032728543 ecr 187200697], length 2896

맙소사, 269329부터 301184까지의 데이터는 어디로 갔나요? 정확히. 다음 패킷에 표시되는 데이터입니다 seq 301185:304081. 때때로 패킷이 순서 없이 도착할 수 있지만 스트림을 살펴봐도 문제가 되는 데이터가 드러나지 않습니다.

우리는 다음을 살펴봄으로써 이를 확인합니다 ack.

13:40:00.345805 IP 172.16.1.177.50298 > 157.130.91.64.5201: Flags [.], ack 269329, win 2994, options [nop,nop,TS val 187200771 ecr 4032728542], length 0
13:40:00.345857 IP 172.16.1.177.50298 > 157.130.91.64.5201: Flags [.], ack 269329, win 3039, options [nop,nop,TS val 187200771 ecr 4032728542,nop,nop,sack 1 {301185:304081}], length 0
13:40:00.345934 IP 157.130.91.64.5201 > 172.16.1.177.50298: Flags [.], seq 304081:306977, ack 38, win 227, options [nop,nop,TS val 4032728543 ecr 187200697], length 2896
13:40:00.345934 IP 157.130.91.64.5201 > 172.16.1.177.50298: Flags [.], seq 306977:309873, ack 38, win 227, options [nop,nop,TS val 4032728543 ecr 187200697], length 2896
13:40:00.345934 IP 157.130.91.64.5201 > 172.16.1.177.50298: Flags [.], seq 309873:312769, ack 38, win 227, options [nop,nop,TS val 4032728543 ecr 187200697], length 2896
13:40:00.345935 IP 157.130.91.64.5201 > 172.16.1.177.50298: Flags [.], seq 312769:314217, ack 38, win 227, options [nop,nop,TS val 4032728543 ecr 187200697], length 1448
13:40:00.345971 IP 172.16.1.177.50298 > 157.130.91.64.5201: Flags [.], ack 269329, win 3084, options [nop,nop,TS val 187200771 ecr 4032728542,nop,nop,sack 1 {301185:306977}], length 0
13:40:00.345995 IP 172.16.1.177.50298 > 157.130.91.64.5201: Flags [.], ack 269329, win 3129, options [nop,nop,TS val 187200772 ecr 4032728542,nop,nop,sack 1 {301185:309873}], length 0
13:40:00.346005 IP 172.16.1.177.50298 > 157.130.91.64.5201: Flags [.], ack 269329, win 3175, options [nop,nop,TS val 187200772 ecr 4032728542,nop,nop,sack 1 {301185:312769}], length 0
13:40:00.346011 IP 172.16.1.177.50298 > 157.130.91.64.5201: Flags [.], ack 269329, win 3197, options [nop,nop,TS val 187200772 ecr 4032728542,nop,nop,sack 1 {301185:314217}], length 0

클라이언트에서 서버로 다시 보내는 반복 전송을 볼 수 있습니다 ack 269329. 이는 클라이언트가 스트림의 해당 지점 이전에 전체 패킷 세트만 수신했으며 그 뒤의 데이터는 누락되었음을 나타냅니다.

이제 라우터("다음 홉")에서 tcpdump를 확인하면 실제로 수신(및 전달)되는 것을 볼 수 있습니다. 이는 수신 인터페이스에서 나온 것이므로 NAT로 인해 대상 IP가 다르지만 송신에는 다음이 표시됩니다. 동일한 데이터 팩):

13:40:00.356167 IP 157.130.91.64.5201 > 32.133.287.15.50298: Flags [.], seq 253401:273673, ack 38, win 227, options [nop,nop,TS val 4032728542 ecr 187200696], length 20272
13:40:00.356235 IP 157.130.91.64.5201 > 32.133.287.15.50298: Flags [.], seq 273673:293945, ack 38, win 227, options [nop,nop,TS val 4032728543 ecr 187200696], length 20272
13:40:00.356291 IP 157.130.91.64.5201 > 32.133.287.15.50298: Flags [.], seq 293945:301185, ack 38, win 227, options [nop,nop,TS val 4032728543 ecr 187200697], length 7240
13:40:00.356367 IP 157.130.91.64.5201 > 32.133.287.15.50298: Flags [.], seq 301185:304081, ack 38, win 227, options [nop,nop,TS val 4032728543 ecr 187200697], length 2896

따라서 라우터는 자신이 패킷을 보낸다고 생각하고 호스트는 패킷을 받지 않는다는 것이 분명합니다.

추가 조사를 통해 나는 이 퍼즐의 또 다른 매우 흥미로운 부분을 발견했습니다.

  • 이러한 패킷은 MTU인 1500바이트보다 큽니다. 이제 1500 MTU는 링크 계층에 포함되지 않으므로 이더넷 헤더도 포함되지 않습니다. 그런데 이 패킷이 아직도 20k 정도인데 이게 뭐지..
  • 이는 대량 전송 오프로드/LSO(대량 수신 오프로드/LRO의 경우 그 반대)로 인해 발생합니다.이를 통해 기본적으로 운영 체제는 이러한 대규모 패킷을 네트워크 카드로 보내고 받을 수 있으며, 네트워크 카드는 필요한 헤더(TCP 헤더 포함)를 다시 작성하여 MTU와 일치하는 의미상 동일한 패킷 세트를 형성합니다. 따라서 운영 체제는 20k 데이터 패킷을 보내고 네트워크 카드는 12개의 데이터 패킷을 펀치하여 외부로 보냅니다. 각 데이터 패킷은 1500바이트 미만입니다. 수신할 때는 그 반대입니다.
  • LSO, LRO 및 기타 하드웨어 최적화를 비활성화할 수 있습니다.방정식에서 이를 제거하고 전송되는 내용을 더 잘 이해하려면 ethtool다음을 사용하십시오.ethtool -K enp12s0 rx off tx off sg off tso off gso off gro off lro off rxvlan off txvlan off rxhash off
  • 제가 아는 한 이것은 실제로 개선되기는 하지만 충분하지는 않습니다. 1.5Mbit가 아닌 1Gbit 네트워크 카드에서 10Mbit를 얻습니다.
  • ethtool오류를 찾는 데에도 사용할 수 있습니다., 예를 들어 ethtool -S enp12s0 | grep err- 이것은 흥미로운 결과를 만들어낼 수 있습니다. 발견한 개별 오류(있는 경우)를 살펴보십시오. 이것이 문제의 원인일 수 있습니다.
  • 어떤 경우에는 라우터 중 하나에서 tcpdump를 사용하여 캡처할 때 tcpdump를 실행하면 성능이 향상될 수 있습니다.(이것은 나에게 매우 이상합니다). 분명히 이것은 일부 버퍼가 일찍 플러시되는 등의 이유로 인해 발생할 수 있지만 이 시점에서는 어떤 장치에 문제가 있는지 꽤 분명해졌습니다. 패킷 로깅을 수행하고 성능이 크게 향상된다면 모니터링하고 있는 장치가 문제의 원인입니다.
  • 또한 케이블, SFP 어댑터, 스위치 포트 등을 확인하는 것이 좋습니다.(내 경우에는 이 중 어느 것도 문제가 되지 않았습니다)

요점: 패킷을 덤프하고 네트워크에서 문제가 있는 위치를 좁힌 다음 위의 아이디어나 생각할 수 있는 다른 방법을 사용하여 근본 원인인지 확인하고 iperf3를 사용하여 조건을 쉽게 시뮬레이션하여 무엇을 결정하는지 확인합니다. 의도한(또는 더 나아가 의도하지 않은) 효과를 얻기 위해 변경되었습니다.

내 경우에는 Linux 라우터로 사용하던 머신이 신뢰할 수 없는 소스에서 구입했는데(직접 이름을 지정하지는 않지만 "blaamazon"과 운율이 비슷함) ethtool에서 오류가 표시되고 있었습니다. 그러나 이 라우터를 통과하는 대부분의 트래픽은 괜찮으며 특정 트래픽 패턴만 위에 표시된 패킷 손실로 인해 어려움을 겪게 된다는 점은 주목할 가치가 있습니다. 따라서 임시 연결 테스트는 모두 통과하지만 특정 부하에서는 패킷이 손실되고 연결 속도가 느려집니다. 그러나 결국 위의 절차를 통해 제어할 수 없는 장치가 발견되어 제거되었습니다.

관련 정보