TCP——Linux 上的性能调优

调整 TCP
我们希望提高 TCP 应用程序的性能。 我们在这里所做的一些事情可以帮助我们的公共服务,主要是 HTTP/HTTPS,尽管整个 Internet 的性能受到完全超出我们控制的延迟和拥塞的限制。但是我们在数据中心内确实拥有完全的控制权,我们必须优化 TCP 以优化 NFS 和其他内部服务。
我们将首先为 TCP 缓冲区提供足够的内存。然后,我们将禁用两个选项,它们对具有高延迟和可变带宽的 WAN 链接很有帮助,但会降低快速 LAN 的性能。最后,我们将增加初始拥塞窗口大小。
TCP 的内存管理
TCP 的内核参数在
/proc/sys/net/core/[rw]mem*和 中设置/proc/sys/net/ipv4/tcp*,适用于 IPv4 和 IPv6。与到目前为止我们看到的所有类别一样,只有少数可用的内核参数可以让我们进行有用的更改。剩下的就别管了。参数
core/rmem_default和 core/wmem_default 是默认的接收和发送 tcp 缓冲区大小,而 core/rmem_max和core/wmem_max 是可以使用 设置的最大接收和发送缓冲区大小 setsockopt(),以字节为单位。参数
ipv4/tcp_rmem和 ipv4/tcp_wmem 是每个打开套接字的读取(接收)和写入(传输)缓冲区的内存量(以字节为单位)。每个都包含三个数字:最小值、默认值和最大值。参数
tcp_mem是所有 TCP 应用程序总计 4096 字节页面中的内存量。它包含三个数字:最小值、压力和最大值。压力是 TCP 将开始回收缓冲内存以将内存使用量降至最低的阈值。您想避免达到该阈值。# grep 。/proc/sys/net/ipv4/tcp*mem /proc/sys/net/ipv4/tcp_mem:181419 241895 362838 /proc/sys/net/ipv4/tcp_rmem:4096 87380 6291456 /proc/sys/net/ipv4/tcp_wmem:4096 16384 4194304
当服务器和客户端位于延迟低于 1 毫秒的 10 Gbps LAN 或通过高延迟低速 WAN 进行通信时,增加服务器和客户端的默认值
tcp_rmem和 最大值 。tcp_wmem在这些情况下,它们的 TCP 缓冲区可能会填满并限制吞吐量,因为 TCP 窗口大小不能足够大以处理从另一端接收 ACK 的延迟。IBM 的 高性能计算页面 推荐 4096 87380 16777216。然后,对于
tcp_mem,将其设置为最大值的两倍tcp_[rw]mem 乘以运行的网络应用程序的最大数量除以每页 4096 字节。增加
rmem_max,wmem_max 因此它们至少与 和 的第三个值一样 tcp_rmem大tcp_wmem。计算带宽延迟积, 即线路上传输的数据总量,作为带宽(以字节 / 秒为单位)乘以往返延迟时间(以秒为单位)的乘积。具有 2 毫秒往返延迟的 1 Gbps LAN 意味着每秒 125 MB 乘以 0.002 秒或 250 KB。
如果主机上没有这么大的缓冲区,发送者必须停止发送并等待确认,这意味着网络管道没有保持满,我们没有使用全部带宽。 随着带宽延迟产品的增加,增加缓冲区大小。 但是,要小心。 带宽延迟乘积是理想的,尽管您无法真正测量它的波动情况。如果您为从网络边缘出站的连接提供的缓冲区明显大于带宽延迟乘积,那么您只会导致整个 Internet 的缓冲区拥塞,而不会让您自己的事情变得更快。
随着 Windows XP 机器的退役,互联网拥塞将变得更糟。XP 没有窗口缩放,因此它对 WAN 缓冲区饱和的影响要小得多。
TCP 选项
由布尔值控制的 TCP 选择性确认 (TCP SACK)
tcp_sack允许接收方向发送方提供有关丢失段的更多详细信息,从而减少重传量。这在高延迟网络上很有用,但禁用它以提高高速 LAN 的吞吐量。也禁用tcp_dsack,如果你不发送 SACK 你当然不想发送重复!前向确认在 SACK 之上工作,如果 SACK 是,则将被禁用。有一个选项
tcp_slow_start_after_idle 可以使通信逐渐开始或恢复。_如果_您使用的是 3G 或 4G (LTE) 移动网络等变速 WAN,这将很有帮助。但在 LAN 或固定带宽 WAN 上,您希望连接开始时尽可能快。有几种 TCP 拥塞控制算法,它们作为模块加载,
/proc/sys/net/ipv4/tcp_available_congestion_control 并将列出当前加载的模块。它们旨在从高速 WAN 上的数据包丢失中快速恢复,因此您可能感兴趣也可能不感兴趣。Reno 是大多数操作系统使用的 TCP 拥塞控制算法。要了解有关其他一些选择的更多信息:BIC 立方体 高速 TCP 可扩展的 TCP TCP 低优先级 TCP 维诺 是啊 TCP TCP 伊利诺伊州 数据中心 TCP (DCTCP)用于加载所需的模块,
modprobe然后 将所需的选项放入. echo``sysctl``tcp_congestion_control设置内核参数
以下文件
/etc/sysctl.d/02-netIO.conf 将sysctl在引导时使用。### /etc/sysctl.d/02-netIO.conf ### TCP 内核设置
提供足够的缓冲内存。 # rmem_max 和 wmem_max 是 TCP 最大缓冲区大小 # 可通过 setsockopt() 设置,以字节为单位 # tcp_rmem 和 tcp_wmem 是每个套接字的字节数。 # tcp_mem 用于所有 TCP 流,在 4096 字节的页面中。 # 以下是 IBM 的建议 #高性能计算页面 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.core.rmem_default = 16777216 net.core.wmem_default = 16777216 net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 87380 16777216 # 这个服务器可能同时有 200 个客户端,所以: # 最大值(tcp_wmem)* 2 * 200 / 4096 net.ipv4.tcp_mem = 1638400 1638400 1638400
禁用 TCP SACK(TCP 选择性确认), # DSACK(重复 TCP SACK)和 FACK(前向确认) net.ipv4.tcp_sack = 0 net.ipv4.tcp_dsack = 0 net.ipv4.tcp_fack = 0
禁用有用的逐渐增加速度 # 在变速 WAN 上,但不适合我们 net.ipv4.tcp_slow_start_after_idle = 0
调整初始窗口大小
每个 TCP 段上的报头都包含一个 16 位字段,用于通告其当前接收窗口大小(从 0 到 65,535),以及一个 32 位字段报告确认号。这意味着已接收到流中确认位置之前的所有内容,并且接收方有足够的 TCP 缓冲内存供发送方传输最新确认后的窗口大小(以字节为单位)。
这个想法是通过沿途使用缓冲区来更有效地流式传输数据,以在任一方向上 “在飞行中” 存储段和确认。在快速交换的 LAN 中,改进来自于允许接收器在做其他事情的同时继续填充缓冲区,推迟确认数据包直到接收缓冲区开始填充。
Increases in the initial TCP window parameters can significantly improve performance. The initial receive window size or initrwnd specifies the receive window size advertised at the beginning of the connection, in segments, or zero to force Slow Start.
The initial congestion window size or initcwnd limits the number of TCP segments the server is willing to send at the beginning of the connection before receiving the first ACK from the client, regardless of the window size the client advertise. The server might be overly cautious, only sending a few kbytes and then waiting for an ACK because its initial congestion window is too small. It will send the smaller of the receiver’s window size and the server’s initcwnd. We have to put up with whatever the client says, but we can crank up the initcwnd value on the server and usually make for a much faster start.
Researchers at Google studied this. Browsers routinely open many connections to load a single page and its components, each of which will otherwise start slow. They recommend increasing initcwnd to at least 10.
CDN Planet has an interesting and much simpler article showing that increasing initcwnd to 10 cuts the total load time for a 14 kbyte file to about half the original time. They also found that many content delivery networks use an initcwnd of 10 and some set it even higher.
The initrwnd and initcwnd are specified in the routing table, so you can tune each route individually. If specified, they apply to all TCP connections made via that route.
First, look at the routing table. Let’s use this simple example. This server has an Internet-facing connection on enp0s2 and is connected to an internal LAN through enp0s3. Let’s say it’s an HTTP/HTTPS server on the Internet side, and an client of NFSv4 over TCP on the internal side.
# ip route show default via 24.13.158.1 dev enp0s2 10.1.1.0/24 dev enp0s3 proto kernel scope link src 10.1.1.100 24.13.158.0/23 dev enp0s2 proto kernel scope link src 24.13.159.33
Now we will modify the routes to specify both initcwnd and initrwnd of 10 segments:
# ip route change default via 24.13.158.1 dev enp0s2 initcwnd 10 initrwnd 10
ip route change 10.1.1.0/24 dev enp0s3 proto kernel scope link src 10.1.1.100 initcwnd 10 initrwnd 10
ip route change 24.13.158.0/23 dev enp0s2 proto kernel scope link src 24.13.159.33 initcwnd 10 initrwnd 10
ip route show
default via 24.13.158.1 dev enp0s2 initcwnd 10 initrwnd 10 10.1.1.0/24 dev enp0s3 proto kernel scope link src 10.1.1.100 initcwnd 10 initrwnd 10 24.13.158.0/23 dev enp0s2 proto kernel scope link src 24.13.159.33 initcwnd 10 initrwnd 10
The appropriate commands could be added to
/etc/rc.d/rc.local for application at boot time.Changes to the TCP window size also affect UDP buffering. On nets faster than 1 Gbps make sure that your applications use
setsockopt() to request larger SO_SNDBUF and SO_RCVBUF.Going Further
Calomel has a great page on performance tuning, although it is specific to FreeBSD. But read through their descriptions of how to tune BSD kernel parameters, and apply what you can to an analysis and tuning of your server.
And next…
Now that we have tuned the networking protocols, we can tune NFS file service running on top of TCP.
Loading...
keepalived