10G(82599EB) 网卡测试优化(kernel)

kernel 方面的优化,这里面大部分都会涉及到 tcp stack。
首先需要了解一个概念,BDP(bandwidth delay product),即两端的带宽跟 RTT 的乘积,比如,我们的 10G 网络,正常情况在 9.4G 到 9.9G 浮动,按照最差的 9.4 来算,RTT 正常的在 0.2ms 左右,他们的 BDP=9.4×10^6kbit/sx0.2×10^-3s=1.88×10^3kbit=235kByte
下面两张图截取自《TCP Implementation in Linux: A Brief Tutorial》,大致的描绘了包从进到出涉及到的几个层面(Device driver, kernel space, User space) 

对于一个包来说,从 IP 层到 TCP 层,经过状态机,最终进入到 TCP recv buffer 通过 read() 转入到 User space(app)。如果这个 buffer(net.ipv4.tcp_rmem) 比 BDP 小的话,其 throughput 会降低。对应的,对于发包来说,从 user space 的 app 通过 write() 调用到 kernel space 进入 TCP send buffer(net.ipv4.tcp_wmem, per socket)。

net.core.netdev_max_backlog 这个决定了一个设备里面等待 cpu 处理(rx)的的最大 queue 数量,如果新接受到的包超过该值,则会被 discarded,这个发生在 ip layer 到 tcp layer 过程中。

注意: core.rmem_max 会覆盖 ipv4.tcp_rmem,core.wmem_max 会覆盖 ipv4.tcp_wmem,上面的几个的单位都是 bytes。ipv4.tcp_mem 是以 pages 为单位而非 bytes。net.core.rmem_default,rmem_default 不应该大于 rmem_max。

上面的四个都是发生在 socket 层面,只对 end-to-end 有效,如果是 bridge/router 则无效。而 netdev_max_backlog 会同时影响端到端以及路由交换的机器。

对于整个网络而言,在接受方向有两个主要的 queue: NIC 的 rx buffer 以及 socket queue。前者在《10G(82599EB) 测试优化(ethtool)》提到过,后者则是上面提到的。两者都需要经过实践,才能得到一个比较满意的效果。

还有个就是 tcp_congestion_control/tcp_available_congestion_control。目前主流的 OS 会提供 cubic reno 这两个,一致偏向使用 CUBIC,2.6.19 之后使用该算法,包括目前的 3.0.0 等,也就是目前主流的稳定的内核(2.6.18, 2.6.32)使用的都是该算法。这个没得说,目前综合性能最好的。当然,如果你是想访问国外的,比如科学上网之类的, 当然使用 hybla,加载,开启:
# modprobe tcp_hybla
# echo hybla > /proc/sys/net/ipv4/tcp_congestion_control

除了上面几个重要的之外,还有几个需要注意的。

1. tcp_timstamps 会在 TCP header 额外的增加 12bytes,10G 网络可以关闭。
2. 对于 tcp_sack 来说,对于 WAN 的效果可能会比较好,但是会增加 CPU util,开不开对 LAN 影响不是很大,都 10G 的 LAN 了,可以肯定的说不会出现丢包这种网络很糟糕的情况
3. tcp_low_latency higher throughput > low latency,这个目前主流的系统默认都是 0。
4. tcp_mtu_probing 对于开启了 jumbo frames 的机器来说,需要开启,默认是 0。这个主要是为了弥补使用 PMTUD 调整 MTU 出现的一些问题。如果置为 2,则会牵扯到 tcp_base_mss,默认为 512,即使用 tcp_base_mss 作为起始的 MSS 值。与之相关的还有 ip_no_pmtu_disc 这个参数,默认为 0,即依然会优先使用传统的 PMTUD,只有当遇到 blackhole 的时候才会使用 PLPMTUD(Packetization Layer Path MTU Discovery),也就是上面提到的技术。 另外,像 fs.file-max, net.ipv4.ip_local_port_range 这类通用性的就不在这里说了,记得修改。

下面是一个范例:
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 600000
net.core.wmem_default = 600000
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_mem = 10000000 10000000 10000000
net.core.netdev_max_backlog = 600000
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_sack = 0
net.ipv4.tcp_low_latency = 0
net.ipv4.tcp_mtu_probing = 1
net.ipv4.tcp_base_mss = 512
net.ipv4.ip_no_pmtu_disc = 0
net.ipv4.tcp_congestion_control = cubic

北京的冬天

今年是呆老大哥首都的第三个年头。11 年冬天大部分时间是呆南京的,所以准确的说是,到目前为止经历了 2.5 个北京的冬天。总的来说,还是比较爽的,尤其是室内,回家关门脱衣至 two piece 就可以活动了。虽然比较干,但是这个是可以通过加湿器部分解决的,再加上点大宝润唇膏什么的,还凑活。

其实写这个博客的目的主要是为了让大家看下面这张图的,这是前段时间推上看到的一张,当时就笑了 :D

“还要小心那些冬天里能唰的一下起床的人”,嗯,我现在就是能唰的一下起床的人,不是因为我拥有“不能想象的决心和意志力”,而是因为,北京(北方)的冬天太暖和了。

使用 ping 部分实现跟 fping 类似的功能

很早之前记录了一篇使用 fping 测试网络质量的博客,最近在看 ping 文档的时候发现其实 ping 在某些功能上可以实现跟 fping 类似的效果,比如要快速的发出 1000 个 ICMP 的包,可以像下面这样:
$ sudo ping -i 0.01 -c 1000 jaseywang.me
$ sudo fping -C 10 -p 10  jaseywang.me

两个注意的地方,第一要使用 root,第二 interval 的单位不一样,注意区别。
使用 time 做了个测试,相同的 interval,相同的包的数量、大小。

fping:
jaseywang.me : xmt/rcv/%loss = 1000/983/1%, min/avg/max = 215/232/264

real  0m26.241s
user  0m0.054s
sys 0m0.170s

ping:
— jaseywang.me ping statistics —
1000 packets transmitted, 985 packets received, 1.5% packet loss
round-trip min/avg/max/stddev = 220.645/233.683/254.227/4.993 ms

real  0m11.632s
user  0m0.050s
sys 0m0.150s

是不是 ping 在这个时候比 fping 还更快些。当然,他们之间一个是 sync,一个则是 async,不要搞错。