![网络数据包无序/重复 ACK](https://linux22.com/image/595751/%E7%BD%91%E7%BB%9C%E6%95%B0%E6%8D%AE%E5%8C%85%E6%97%A0%E5%BA%8F%2F%E9%87%8D%E5%A4%8D%20ACK.png)
我目前遇到了我们刚刚搬入的新数据中心的网络性能方面的一个非常大的问题,老实说,我不知道该怎么办;所以我正在寻找一些灵感。
数据中心有一个托管网络,我无法访问,但我们负责管理其中的主机。
一般信息
- 我们在数据中心环境 (Dell R210s 和 R710s) 中有 11 台主机 (全部是 Debian Squeeze)。
- 每个主机都有两个活动接口,它们以 bond0 主动/被动设置 (eth0 和 eth1) 进行设置。
- 主机上的网络堆栈基本上按照默认的 Debian 设置,我们不会尝试性能优化或类似操作。
- 该问题在十一台主机中的任何一台上都是相同/可复制的,但仅适用于跨越网络边界的流量(即,它不适用于内部主机之间的流量)。
- 数据中心支持团队将一台笔记本电脑连接到其余主机所在的同一交换机,但无法重现该问题;因此可以说这一定是内部主机本身的配置问题,而不是网络问题。
问题
在出站传输中,传输以较大的窗口大小快速启动,但在远程服务器上,数据包的接收顺序混乱,这反过来又导致发送重复的 ACK。很快,窗口大小就大幅缩小(稳定在 40,000 到 60,000 字节之间),传输速度从每秒兆字节下降到约 200-300KB/秒。
对于入站传输,一切都“良好”(其中“良好”定义为 2MB/秒的持续传输速率)。
因此,将一个 20MB 文件通过 SCP 传输出数据中心时,其速度将以 ~2.2MB/秒开始,但会下降到 ~275KB/秒,总共需要 01 分 14 秒,而将同一个 20MB 文件通过 SCP 传输到数据中心时,其速度将以 ~2.2MB/秒开始,保持稳定在 ~2.0-2.2MB/秒之间,并在 00 分 09 秒内完成。
我尝试过的
- 我已经验证主机和网络硬件之间没有协商混淆——所有链路都被各方视为 1GbE 全双工。
- 我已尝试禁用窗口缩放。
- 我已尝试将 net.ipv4.tcp_rmem 和 net.ipv4.tcp_wmem 从其 debian 默认值中缩小。
- 我尝试禁用 bond0 并仅通过普通的 eth0 接口传输文件。
- 我尝试过转移到多个遥远的外部端点;所有端点都存在同样的问题(即,我确信问题出在数据中心端,而不是另一端)。
- 我已经对到多个外部端点的路由运行了 mtr 检查(我可以在所有这些端点上复制问题)——这些路由是不同的(经过几跳之后完全不同),虽然其中一些路由显示出一定程度的数据包丢失;事实上,所有端点(具有不同的路由和不同的数据包丢失程度)的行为都非常相似,这使我相信问题不是由来自内部 DC 的三到四个跳以上的任何东西引起的(因为这些是每条路由的公共跳数——并且这些跳数没有显示任何明显的数据包丢失)。
以下是入站/出站流量的流量分析(从 DC 中的主机角度来看)。如您所见,存在(非常)频繁的重复 ACK,导致传输速度远低于应有的速度。另请注意,在入站传输中,不会发生同样的问题。
tshark -r outbound-bond0.pcap -q -z io,stat,1,\
"COUNT(tcp.analysis.retransmission) tcp.analysis.retransmission",\
"COUNT(tcp.analysis.duplicate_ack)tcp.analysis.duplicate_ack",\
"COUNT(tcp.analysis.lost_segment) tcp.analysis.lost_segment",\
"COUNT(tcp.analysis.fast_retransmission) tcp.analysis.fast_retransmission"
===================================================================
IO Statistics
Interval: 1.000 secs
Column #0: COUNT(tcp.analysis.retransmission) tcp.analysis.retransmission
Column #1: COUNT(tcp.analysis.duplicate_ack)tcp.analysis.duplicate_ack
Column #2: COUNT(tcp.analysis.lost_segment) tcp.analysis.lost_segment
Column #3: COUNT(tcp.analysis.fast_retransmission) tcp.analysis.fast_retransmission
| Column #0 | Column #1 | Column #2 | Column #3
Time | COUNT | COUNT | COUNT | COUNT
000.000-001.000 8 22 0 2
001.000-002.000 4 28 0 3
002.000-003.000 4 33 0 4
003.000-004.000 4 25 0 3
004.000-005.000 3 28 0 3
005.000-006.000 4 38 0 4
006.000-007.000 6 22 0 4
007.000-008.000 4 14 0 2
008.000-009.000 5 33 0 4
009.000-010.000 1 10 0 1
010.000-011.000 4 25 0 2
011.000-012.000 2 25 0 2
012.000-013.000 3 35 0 3
013.000-014.000 2 23 0 2
014.000-015.000 4 50 0 4
015.000-016.000 3 22 0 2
016.000-017.000 5 28 0 3
017.000-018.000 3 29 0 3
018.000-019.000 3 31 0 3
019.000-020.000 5 17 0 2
020.000-021.000 4 40 0 4
021.000-022.000 7 27 0 3
022.000-023.000 5 37 0 4
023.000-024.000 10 17 0 1
024.000-025.000 3 10 0 1
025.000-026.000 4 9 0 2
026.000-027.000 3 10 0 1
027.000-028.000 4 47 0 4
028.000-029.000 5 35 0 4
029.000-030.000 3 14 0 2
030.000-031.000 9 24 0 3
031.000-032.000 4 20 0 3
032.000-033.000 6 37 0 5
033.000-034.000 3 19 0 3
034.000-035.000 3 17 0 1
035.000-036.000 3 42 0 3
036.000-037.000 6 49 0 5
037.000-038.000 1 7 0 1
038.000-039.000 9 59 0 6
039.000-040.000 3 23 0 3
040.000-041.000 1 12 0 1
041.000-042.000 4 39 0 2
042.000-043.000 6 15 0 0
043.000-044.000 2 25 0 2
044.000-045.000 3 41 0 3
045.000-046.000 1 8 0 1
===================================================================
tshark -r inbound-bond0.pcap -q -z io,stat,1,\
"COUNT(tcp.analysis.retransmission) tcp.analysis.retransmission",\
"COUNT(tcp.analysis.duplicate_ack)tcp.analysis.duplicate_ack",\
"COUNT(tcp.analysis.lost_segment) tcp.analysis.lost_segment",\
"COUNT(tcp.analysis.fast_retransmission) tcp.analysis.fast_retransmission"
===================================================================
IO Statistics
Interval: 1.000 secs
Column #0: COUNT(tcp.analysis.retransmission) tcp.analysis.retransmission
Column #1: COUNT(tcp.analysis.duplicate_ack)tcp.analysis.duplicate_ack
Column #2: COUNT(tcp.analysis.lost_segment) tcp.analysis.lost_segment
Column #3: COUNT(tcp.analysis.fast_retransmission) tcp.analysis.fast_retransmission
| Column #0 | Column #1 | Column #2 | Column #3
Time | COUNT | COUNT | COUNT | COUNT
000.000-001.000 0 0 0 0
001.000-002.000 0 0 0 0
002.000-003.000 0 0 0 0
003.000-004.000 0 0 0 0
004.000-005.000 0 0 0 0
005.000-006.000 0 0 0 0
006.000-007.000 0 0 0 0
007.000-008.000 1 26 1 0
008.000-009.000 1 70 0 1
009.000-010.000 21 184 5 4
010.000-011.000 4 42 4 2
011.000-012.000 9 48 3 2
012.000-013.000 0 0 0 0
013.000-014.000 0 0 0 0
014.000-015.000 1 29 1 1
===================================================================
坦白说,我完全不知所措。非常欢迎提出下一步该尝试的建议。
答案1
如果您确定问题是由无序数据包引起的,那么我可以很容易地想到一件会导致您的数据包无序的事情:您和 DC 边缘之间的某处有一个多链路以太通道,配置了每个数据包的循环负载平衡。请您的提供商专门寻找这一点。