在我们的 REHL 服务器中,应用程序发送和 tcpdump 日志之间的延迟为总是对于大消息来说非常大,大约 200 毫秒(见下文 697572-488690=208882 微秒),而小消息的延迟非常小,只有几微秒。
我认为没有一个TCP定时器可以解释200ms的延迟。这种延迟通常是由于 Nagle 算法针对小消息造成的,但这里的情况并非如此,因为高延迟仅适用于大消息。
并附上一条大消息:
IBM MQ 跟踪日志摘录:
12:13:12.488685 4172.1 RSESS:000001 ----{ ccxSend
12:13:12.488688 4172.1 RSESS:000001 -----{ cciTcpSend
12:13:12.488690 4172.1 RSESS:000001 ------{ send
12:13:12.488697 4172.1 RSESS:000001 ------} send rc=OK
12:13:12.488711 4172.1 RSESS:000001 Sending 1138 bytes
[large message]
12:13:12.488714 4172.1 RSESS:000001 RetCode (OK)
12:13:12.488716 4172.1 RSESS:000001 -----} cciTcpSend rc=OK
tcpdump 提取:
12:13:05.884715 IP (tos 0x0, ttl 49, id 60415, offset 0, flags [DF], proto: TCP (6), length: 68) otherHost.otherPort > ourHost.ourPort: P, cksum 0x7673 (correct), 2893948259:2893948287(28) ack 1576932354 win 1024 ....
12:13:05.884718 IP (tos 0x0, ttl 64, id 60352, offset 0, flags [DF], proto: TCP (6), length: 40) ourHost.ourPort > otherHost.otherPort: ., cksum 0xcd9c (correct), ack 2893948287 win 5768
12:13:12.697572 IP (tos 0x0, ttl 64, id 60353, offset 0, flags [DF], proto: TCP (6), length: 1064) ourHost.ourPort > otherHost.otherPort: P, cksum 0x0059 (incorrect (-> 0x6a5a), 1576932354:1576933378(1024) ack 2893948287 win 5768
[first packet of large message]
12:13:12.708367 IP (tos 0x0, ttl 49, id 61060, offset 0, flags [DF], proto: TCP (6), length: 40) otherHost.otherPort > ourHost.ourPort: ., cksum 0xe024 (correct), ack 1576933378 win 0
12:13:12.708865 IP (tos 0x0, ttl 49, id 61061, offset 0, flags [DF], proto: TCP (6), length: 40) otherHost.otherPort > ourHost.ourPort: ., cksum 0xdc24 (correct), ack 1576933378 win 1024
12:13:12.708869 IP (tos 0x0, ttl 64, id 60354, offset 0, flags [DF], proto: TCP (6), length: 154) ourHost.ourPort > otherHost.otherPort: P, cksum 0xfcca (incorrect (-> 0xa1fb), 1576933378:1576933492(114) ack 2893948287 win 5768
[second packet of large message]
12:13:12.716154 IP (tos 0x0, ttl 49, id 61062, offset 0, flags [DF], proto: TCP (6), length: 40) otherHost.otherPort > ourHost.ourPort: ., cksum 0xdc24 (correct), ack 1576933492 win 910
12:13:12.717202 IP (tos 0x0, ttl 49, id 61063, offset 0, flags [DF], proto: TCP (6), length: 68) otherHost.otherPort > ourHost.ourPort: P, cksum 0x71e5 (correct), 2893948287:2893948315(28) ack 1576933492 win 1024
12:13:12.717209 IP (tos 0x0, ttl 64, id 60355, offset 0, flags [DF], proto: TCP (6), length: 40) ourHost.ourPort > otherHost.otherPort: ., cksum 0xc90e (correct), ack 2893948315 win 5768
带有一条小消息(摘录中的上下文较少):
15:15:33.133940 4215.1 RSESS:000001 ------{ send
15:15:33.133954 4215.1 RSESS:000001 ------} send rc=OK
...
15:15:33.133966 4215.1 RSESS:000001 Sending 512 bytes
[small message]
15:15:33.133969 4215.1 RSESS:000001 RetCode (OK)
tcp转储:
15:15:33.133949 IP (tos 0x0, ttl 64, id 37357, offset 0, flags [DF], proto: TCP (6), length: 552) ourHost.ourPort > otherHost.otherPort: P, cksum 0xfe58 (incorrect (-> 0x2dd8), 1566021015:1566021527(512) ack 2491002247 win 5768
[small message]
系统和驱动版本:
Linux 2.6.18-128.el5 #1 SMP 12 月 17 日星期三 11:41:38 EST 2008 x86_64 x86_64 x86_64 GNU/Linux
红帽企业 Linux 服务器版本 5.3 (Tikanga)
# /usr/sbin/ethtool -i bond0
driver: bonding
version: 3.2.4
firmware-version: 2
$ cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.2.4 (January 28, 2008)
Bonding Mode: fault-tolerance (active-backup)
Currently Active Slave: eth2
# /usr/sbin/ethtool -i eth2
driver: e1000e
version: 1.2.10-NAPI
firmware-version: 5.12-2
下一步?
在没有找到这个问题的根本原因的情况下,我在想:
- 只是想升级粘合或者e1000e司机。顺便问一下,为了检查是否涉及任何绑定错误,有人知道绑定驱动程序版本和发行说明在哪里吗?
- 要求另一方设置更大的 TCP 窗口,因为当一条消息只需发送一个数据包时不会出现问题。此外,这还将减少 10 毫秒的延迟,即大消息的第一个数据包和第二个数据包之间的时间。
还有人有其他想法吗?有没有办法获取 bond 或 e1000e 驱动程序的跟踪日志?
答案1
send
您在每次调用or时传递的字节太少write
。您需要尝试每次调用至少传递 2KB,或者更好,每次调用传递 4KB。如果可能,累积整个逻辑消息并立即发送。这将节省系统调用,更有效地打包数据包,并防止延迟的 ACK 破坏您的延迟。
答案2
根据Linux 调优:专家指南来自 ESnet 网络性能知识库:
注意:对于 Redhat Enterprise Linux 5.3 - 5.5 及其变体(Centos、Scientific Linux 等)使用的许多版本的 2.6.18 内核,bic 和cubic 似乎都存在错误。我们建议在 2.6 中使用 htcp .18.x 内核是安全的。
我在 上找不到有关 bic 或cubic bug 的任何详细信息红帽错误数据库或其他任何地方,因此没有证据表明这是实际答案。