TCP缓存设置及自调节

工作的原因,同事在单条流的性能测试中出现性能值低的问题,最后的问题点确认为缓存设置不合理。为什么要设置缓存?如何设置缓存?

缓存和带宽时延积

读缓存的上限应该由TCP接收窗口的最大值确定,过大或过小的接收窗口(通告窗口),都会造成网络问题。发送端可以发送的一窗数据大小,由拥塞窗口(cwmd)和通告窗口的最小值决定,如果接收窗口过小,将使发送端发送速度缓慢,即使再理想的带宽和网络状况,也无法增加连接的吞吐。而如果接收窗口设置过大(试想节假日的高速公路上车辆无限制的涌入的情形),超过了网络所能承载的上限,将造成网络网络的拥塞和丢包,最后通过发送端的拥塞控制,将连接流量控制在一个合理范围内。

linux协议栈默认的缓存大小设置可以应对普遍情况,但在特殊环境下,例如希望在一条延迟很大的连接上跑出线速,缓存可能就需要被修改。先说一下BDP的概念,出自百度百科,带宽时延积是一种网络性能指标。在数据通信中,带宽时延乘积指的是一个数据链路的能力(每秒比特)与来回通信延迟(单位秒)的乘积。带宽时延积很大的一条连接,称为“长肥管道”。对于一个时延10ms、带宽万兆的网络环境,那么BDP = 10000Mb / 8 * 0.01 = 12.5MB,那么读缓存的理论值为 12.5MB(不考虑tcp_adv_win_scale)

TCP缓存设置

net.core.rmem_default:全协议默认接收缓存大小,对于tcp而言,会被tcp_rmem[1]覆盖;
net.core.wmem_default:全协议默认发送缓存大小,对于tcp而言,会被tcp_wmem[1]覆盖;
net.core.rmem_max:全协议接收缓存最大值;
net.core.wmem_max:全协议发送缓存最大值。

在不使用SO_SNDBUF、SO_RCVBUF套接字选项情况下,系统将使用上面的默认缓存大小,对于tcp而言,默认的缓存大小会被tcp_rmem[1]和tcp_wmem[1]覆盖。

sk->sk_sndbuf = sysctl_tcp_wmem[1];
sk->sk_rcvbuf = sysctl_tcp_rmem[1];

通过套接字选项修改缓存大小的行为如下:

val = min_t(u32, val, sysctl_rmem_max);
sk->sk_rcvbuf = max_t(u32, val * 2, SOCK_MIN_RCVBUF);

可以看到,如果缓存设置大于rmem_max,则缓存被修改为rmem_max;如果缓存设置小于SOCK_MIN_RCVBUF,缓存被修改为SOCK_MIN_RCVBUF(2KB)。另外,我们所设置的缓存值被乘以2后设置,这里猜想可能是因为这个缓存值并不完全用于缓存,它需要包含了数据结构大小。

TCP缓存自调节

linux通过net.ipv4.tcp_moderate_rcvbuf使能缓存自调节功能,当系统tcp内存使用少的情况下,为连接分配更大的缓存,而当系统tcp内存使用多的情况下,减少连接缓存的分配大小。

  • tcp_mem:
    tcp_mem[3]被用来追踪TCP的内存使用情况,需要注意这里的单位是页大小而不是字节,它们的默认值在系统启动时根据总的可用内存大小来计算。
    tcp_mem[0]:当TCP分配的总内存大小小于该值时,TCP并不控制它的内存分配;
    tcp_mem[1]:当TCP使用的总内存大小超过该值时,TCP进入压力状态,并开始减缓它的内存消耗。一旦TCP使用的总内存低于tcp_mem[0],将退出压力状态;
    tcp_mem[2]:TCP使用内存的最大值,当其使用的总内存超过该值时,TCP的所有缓存分配都将失败。

  • tcp_rmem:
    tcp_rmem[3]被用来控制TCP接受缓存大小,TCP根据系统的内存使用状况和tcp_rmem配置,动态的调整接收缓存大小。
    tcp_rmem[0]:缺省值为页大小,当TCP内存使用处于压力状态时,低于该值的读缓存分配都会成功。当使用SO_RCVBUF对socket缓存大小进行设置后,tcp_rmem对读缓存的限制不再生效;
    tcp_rmem[1]:TCP接收缓存的缺省大小,该值将覆盖net.core.rmem_default对所有协议设置的接收缓存默认值。如果期望更大的接收缓存,可以增大该值;
    tcp_rmem[2]:TCP套接字接收缓存最大值,该值将不会覆盖全局的net.core.rmem_max,该值不会限制SO_RCVBUF对接收缓存大小的设置。

  • tcp_wmem:基本与tcp_rmem一致。
    在这里插入图片描述

总结如下:
1.当TCP内存使用低于tcp_mem[0],不超过连接缓存上限的内存分配都会成功;
2.当TCP内存使用高于tcp_mem[2],连接缓存的分配都会失败;
3.当TCP内存使用高于tcp_mem[0]且低于tcp_mem[2]时,系统可能处于压力状态也可能处于非压力状态,压力状态下连接缓存上限减少,非压力状态下连接缓存上限增加,但保证低于tcp_rmem[0]或tcp_wmem[0]的缓存成功。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值