내 애플리케이션이 수행하는 작업은 kafka에서 데이터를 읽고 HTTP를 통해 다른 서비스에 액세스하는 것입니다. 나는 한 상자에서 나가는 트래픽이 다른 상자보다 느리다는 것을 발견했습니다. 이 나가는 IP에 대한 tcpdump와 이 상자의 로그를 분석했습니다.
09:24:20.625288 IP (tos 0x0, ttl 64, id 16107, offset 0, flags [DF], proto TCP (6), length 7292)
localIP.57854 > externalIp.http: Flags [.], cksum 0x03fb (incorrect -> 0x614e), seq 52963:60203, ack 464, win 2518, options [nop,nop,TS val 205440553 ecr 262205407], length 7240: HTTP
09:24:20.640851 IP (tos 0x0, ttl 64, id 16112, offset 0, flags [DF], proto TCP (6), length 2948)
localIP.57854 > externalIp.http: Flags [.], cksum 0xf302 (incorrect -> 0xb2a7), seq 60203:63099, ack 464, win 2518, options [nop,nop,TS val 205440557 ecr 262205422], length 2896: HTTP
09:24:20.640897 IP (tos 0x0, ttl 64, id 16114, offset 0, flags [DF], proto TCP (6), length 2948)
localIP.57854 > externalIp.http: Flags [.], cksum 0xf302 (incorrect -> 0x46c8), seq 63099:65995, ack 464, win 2518, options [nop,nop,TS val 205440557 ecr 262205422], length 2896: HTTP
09:24:20.640930 IP (tos 0x0, ttl 64, id 16116, offset 0, flags [DF], proto TCP (6), length 2948)
localIP.57854 > externalIp.http: Flags [.], cksum 0xf302 (incorrect -> 0xedd7), seq 65995:68891, ack 464, win 2518, options [nop,nop,TS val 205440557 ecr 262205422], length 2896: HTTP
09:24:20.640940 IP (tos 0x0, ttl 64, id 16118, offset 0, flags [DF], proto TCP (6), length 2948)
localIP.57854 > externalIp.http: Flags [.], cksum 0xf302 (incorrect -> 0x22df), seq 68891:71787, ack 464, win 2518, options [nop,nop,TS val 205440557 ecr 262205422], length 2896: HTTP
09:24:20.640973 IP (tos 0x0, ttl 64, id 16120, offset 0, flags [DF], proto TCP (6), length 2948)
localIP.57854 > externalIp.http: Flags [.], cksum 0xf302 (incorrect -> 0x7fad), seq 71787:74683, ack 464, win 2518, options [nop,nop,TS val 205440557 ecr 262205422], length 2896: HTTP
09:24:20.641016 IP (tos 0x0, ttl 64, id 16122, offset 0, flags [DF], proto TCP (6), length 2948)
localIP.57854 > externalIp.http: Flags [.], cksum 0xf302 (incorrect -> 0x19e9), seq 74683:77579, ack 464, win 2518, options [nop,nop,TS val 205440557 ecr 262205422], length 2896: HTTP
09:24:20.641027 IP (tos 0x0, ttl 64, id 16124, offset 0, flags [DF], proto TCP (6), length 2948)
localIP.57854 > externalIp.http: Flags [.], cksum 0xf302 (incorrect -> 0xc26d), seq 77579:80475, ack 464, win 2518, options [nop,nop,TS val 205440557 ecr 262205422], length 2896: HTTP
09:24:20.644138 IP (tos 0x0, ttl 64, id 16132, offset 0, flags [DF], proto TCP (6), length 2223)
localIP.57854 > externalIp.http: Flags [P.], cksum 0xf02d (incorrect -> 0x6078), seq 89163:91334, ack 464, win 2518, options [nop,nop,TS val 205440557 ecr 262205425], length 2171: HTTP
09:24:20.660631 IP (tos 0x0, ttl 64, id 16134, offset 0, flags [DF], proto TCP (6), length 775)
localIP.57854 > externalIp.http: Flags [P.], cksum 0xea85 (incorrect -> 0x14c9), seq 90611:91334, ack 464, win 2518, options [nop,nop,TS val 205440562 ecr 262205426], length 723: HTTP
또한 다른 상자에는 다음이 표시됩니다.
09:26:53.610483 IP (tos 0x0, ttl 64, id 27441, offset 0, flags [DF], proto TCP (6), length 14532)
localIP.50978 > externalIp.http: Flags [.], cksum 0xcb4f (incorrect -> 0x3b5c), seq 151537:166017, ack 1390, win 1444, options [nop,nop,TS val 1613152807 ecr 262243666], length 14480: HTTP
09:26:53.610609 IP (tos 0x0, ttl 64, id 27451, offset 0, flags [DF], proto TCP (6), length 16713)
localIP.50978 > externalIp.http: Flags [P.], cksum 0xd3d4 (incorrect -> 0xed92), seq 166017:182678, ack 1390, win 1444, options [nop,nop,TS val 1613152807 ecr 262243668], length 16661: HTTP
09:26:53.632437 IP (tos 0x0, ttl 64, id 53481, offset 0, flags [DF], proto TCP (6), length 52)
localIP.51054 > externalIp.http: Flags [.], cksum 0x92bf (incorrect -> 0x5bcc), ack 464, win 1444, options [nop,nop,TS val 1613152812 ecr 262243674], length 0
09:26:53.638408 IP (tos 0x0, ttl 64, id 2460, offset 0, flags [DF], proto TCP (6), length 11636)
localIP.50892 > externalIp.http: Flags [.], cksum 0xbfff (incorrect -> 0x9468), seq 91408:102992, ack 927, win 1444, options [nop,nop,TS val 1613152814 ecr 262243675], length 11584: HTTP, length: 11584
필드 길이에는 큰 차이가 있습니다. 첫 번째 경우에는 매우 작은 반면, 후자의 경우에는 크고 전체 데이터가 매우 빠르게 전송됩니다. 이 길이 필드는 어떻게 결정되며 어떤 요인이 이에 영향을 줍니까?
답변1
관찰된 길이 차이는 TCP 분할 오프로딩으로 인한 것입니다. 대부분의 최신 네트워크 카드는 패킷을 조각화할 때 CPU 사용량을 줄이기 위해 하드웨어에서 이 기능을 지원합니다. tcpdump
조각화가 발생하기 전에 패킷을 감시하므로 구성된 것보다 훨씬 큰 패킷을 볼 수 있습니다 MTU
(회선의 실제 패킷은 여전히 MTU
크기에 의해 제한됩니다).
ethtool을 사용하여 NIC에 대한 TCP 분할 오프로드를 확인할 수 있습니다(예: eth0 장치 확인).
# ethtool -k eth0 |grep 'tcp-segmentation-offload'
tcp-segmentation-offload: on
다음을 사용하여 비활성화할 수 있습니다.ethtool -K tso off
TSO가 활성화된 경우 표시되는 발신 데이터의 예(최대 64k - TCP 제한)
15:08:22.451667 IP 192.168.230.9.43736 > 192.168.157.102.22: Flags [.], seq 32023713:32088873, ack 19886, win 340, options [nop,nop,TS val 3241810413 ecr 3874669422], length 65160
15:08:22.452203 IP 192.168.230.9.43736 > 192.168.157.102.22: Flags [.], seq 32088873:32154033, ack 19886, win 340, options [nop,nop,TS val 3241810413 ecr 3874669423], length 65160
TSO가 비활성화되면 길이는 MTU(여기서는 1500)에 의해 제한됩니다.
15:09:43.181882 IP 192.168.230.9.43738 > 192.168.157.102.22: Flags [.], seq 9881:11329, ack 4206, win 319, options [nop,nop,TS val 3241830596 ecr 3874750153], length 1448
15:09:43.181886 IP 192.168.230.9.43738 > 192.168.157.102.22: Flags [.], seq 11329:12777, ack 4206, win 319, options [nop,nop,TS val 3241830596 ecr 3874750153], length 1448
페이로드의 가변 길이는 NIC가 병합되는 세그먼트 수에 따라 달라집니다. 이는 당시 서버의 NIC 리소스 및 트래픽에 따라 달라질 수 있습니다.
답변2
~에서수동tcpdump
The general format of a TCP protocol line is:
src > dst: Flags [tcpflags], seq data-seqno, ack ackno,
win window, urg urgent, options [opts], length len
Src and dst are the source and destination IP addresses and ports.
[...] Len is the length of payload data.
TCP에서 페이로드 데이터는 바이트 단위로 표현됩니다. (100% 확실하지는 않지만 파일의 tcpdump 소스에 있습니다.)print-tcp.c
길이 필드에 대한 주석에는 바이트라는 용어만 사용되었으며 애플리케이션이 사용할 데이터인 TCP 데이터그램 내부의 실제 데이터임을 알 수 있습니다.
Kafka는 전송되는 메시지의 양에 따라 대역폭이 달라지는 바이트 스트림을 보낼 수 있는 메시징 애플리케이션입니다.
이 경우 플래그를 읽을 수 있으므로(조각화되지 않음) 패킷에 TCP 조각화가 없지만 [DF]
문제가 되지 않습니다. TCP 데이터 중 유용한 데이터의 길이는 lenght
""바이트입니다.
크기를 선택하는 방법은 TCP 스택(아마도 운영 체제에 따라 다름)과 전송해야 하는 데이터 양에 따라 다릅니다.
다르지만 전혀 문제가 되지 않습니다. TCP는 100바이트만 보내야 할 때 65,365바이트를 보내지 않을 정도로 유연합니다.