net.ipv4.tcp_adv_win_scale计算额外开销的大小:

文章插图
如果
net.ipv4.tcp_adv_win_scale的值为1,则二分之一的缓冲空间用来做额外开销,如果为2的话,则四分之一缓冲空间用来做额外开销 。因此recvbuffer的最佳值应该设置为:

文章插图
三、数据包的发送发送数据包经过的路径:

文章插图
和接收数据的路径相反,数据包的发送从上往下也经过了三层:用户态空间的应用、系统内核空间、最后到网卡驱动 。应用先将数据写入TCP sendbuffer,TCP层将sendbuffer中的数据构建成数据包转交给IP层 。IP层会将待发送的数据包放入队列QDisc(queueingdiscipline) 。数据包成功放入QDisc后,指向数据包的描述符sk_buff被放入RingBuffer输出队列,随后网卡驱动调用DMAengine将数据发送到网络链路上 。
同样我们逐层来梳理队列缓冲有关的参数 。
1、sendBuffer
同recvBuffer类似,和sendBuffer有关的参数如下: net.ipv4.tcp_wmem =
net.core.wmem_defaultnet.core.wmem_max 发送端缓冲的自动调节机制很早就已经实现,并且是无条件开启,没有参数去设置 。如果指定了tcp_wmem,则net.core.wmem_default被tcp_wmem的覆盖 。sendBuffer在tcp_wmem的最小值和最大值之间自动调节 。如果调用setsockopt()设置了socket选项SO_SNDBUF,将关闭发送端缓冲的自动调节机制,tcp_wmem将被忽略,SO_SNDBUF的最大值由net.core.wmem_max限制 。
2、QDisc
QDisc(queueing discipline )位于IP层和网卡的ringbuffer之间 。我们已经知道,ringbuffer是一个简单的FIFO队列,这种设计使网卡的驱动层保持简单和快速 。而QDisc实现了流量管理的高级功能,包括流量分类,优先级和流量整形(rate-shaping) 。可以使用tc命令配置QDisc 。
QDisc的队列长度由txqueuelen设置,和接收数据包的队列长度由内核参数
net.core.netdev_max_backlog控制所不同,txqueuelen是和网卡关联,可以用ifconfig命令查看当前的大小:

文章插图
使用ifconfig调整txqueuelen的大小:
ifconfig eth0 txqueuelen 2000
3、RingBuffer
和数据包的接收一样,发送数据包也要经过RingBuffer,使用ethtool-g eth0查看:

文章插图
其中TX项是RingBuffer的传输队列,也就是发送队列的长度 。设置也是使用命令ethtool-G 。
4、TCPSegmentation和Checksum Offloading
操作系统可以把一些TCP/IP的功能转交给网卡去完成,特别是Segmentation(分片)和checksum的计算,这样可以节省CPU资源,并且由硬件代替OS执行这些操作会带来性能的提升 。一般以太网的MTU(MaximumTransmission Unit)为1500 bytes,假设应用要发送数据包的大小为7300bytes,MTU1500字节- IP头部20字节 -TCP头部20字节=有效负载为1460字节,因此7300字节需要拆分成5个segment:

文章插图
Segmentation(分片)操作可以由操作系统移交给网卡完成,虽然最终线路上仍然是传输5个包,但这样节省了CPU资源并带来性能的提升:

文章插图
可以使用ethtool-k eth0查看网卡当前的offloading情况:

文章插图
上面这个例子checksum和tcpsegmentation的offloading都是打开的 。如果想设置网卡的offloading开关,可以使用ethtool-K(注意K是大写)命令,例如下面的命令关闭了tcp segmentation offload: sudo ethtool -K eth0 tso off
5、网卡多队列和网卡Bonding模式
在数据包的接收过程中已经介绍过了 。
至此,终于梳理完毕 。
【Linux TCP队列相关参数的总结】
推荐阅读
- Linux 环境下 DNS 域名解析服务
- Linux的系统启动卡制作及系统固化
- 通过十个问题助你彻底理解linux epoll工作原理
- 动图图解!既然IP层会分片,为什么TCP层也还要分段?
- linux内核协议栈 UDP之数据报接收过程
- Linux系统目录结构介绍
- Linux的sz和rz命令
- linux系统上查看载体为实体机还是虚拟机
- Linux上,最常用的十条命令
- Linux内核快速处理路径尽量多用kmem_cache而慎用kmalloc
