CentOS 8 开启 BBR

Posted by 王灿辉 on 2020-03-29

TCP 拥塞控制算法

传统 TCP 拥塞控制算法,基于丢包反馈的协议。

基于「丢包反馈」的协议是一种被动式的拥塞控制机制,其依据网络中的丢包事件来做网络拥塞判断。即便网络中的负载很高时,只要没有产生拥塞丢包,协议就不会主动降低自己的发送速度。

这种协议可以最大程度的利用网络剩余带宽,提高吞吐量。然而,由于基于丢包反馈协议在网络近饱和状态下所表现出来的侵略性,一方面大大提高了网络的带宽利用率;但另一方面,对于基于丢包反馈的拥塞控制协议来说,大大提高网络利用率同时意味着下一次拥塞丢包事件为期不远了,所以这些协议在提高网络带宽利用率的同时也间接加大了网络的丢包率,造成整个网络的抖动性加剧。

到底是谁丢了包?

丢包并不总是拥塞导致,丢包可能原因是多方面,比如:

  • 全球最牛的防火墙 GFW 的随机丢包策略
  • 网路中由于多路径衰落(multi-path fading)所造成的信号衰减(signal degradation)
  • 通道阻塞造成的丢包(packet drop),再者损坏的封包(corrupted packets)被拒绝通过
  • 有缺陷的网路硬件、网路驱动软件发生故障
  • 信号的信噪比(SNR)的影响

Google BBR 的出现

我们自然不喜欢 GFW 这种人为的随机丢包策略,当路过 GFW 时,数据被丢包,我们在此时应该立刻重新发包,增大发送的频率,而不希望降低速度,也就是不希望传统的 TCP 拥塞算法去控制。

由此,就出现了基于不丢包的拥塞控制算法 CDG, 以 延迟 作为判断依据,延迟增大说明拥塞, 数据开始在路由器的缓冲中积累. 降低发送 窗口。然而 CDG 算法与基于丢包的算法不兼容, 只有全球的设备都换上 CDG,但这是不可能的,目前市面上的设备不可能一下子都切换到 CDG,因此 Google 就不开心了,Google 的科学家们开发了一种过渡算法来解决这个问题,这个算法的名字就是 BBR(Bottleneck Bandwidth and RTT),它是一种全新的 拥塞控制算法,BBR 同 CDG 一致的思想是不以丢包作为拥塞控制信号,但是和 CDG 不同的是,BBR 能和 cubic 和 reno 共存。

tcp_bbr

Google 云端平台博客提供,使用 BBR 前后网络吞吐量对比图

CentOS 8 开启 TCP_BBR

Google 开源了其 TCP BBR 拥塞控制算法,并提交到了 Linux 内核,从 4.9.0 开始,Linux 内核已经用上了该算法。

CentOS 8 Linux kernel 版本为 4.18.0,kernel 版本高于 4.9.0,因此同时支持 BBR 和 NV 拥塞算法, 但默认未启动 BBR,启动 BBR 的方法也非常简单。

1. 查看当前拥塞算法

1
2
3
4
$ sysctl net.ipv4.tcp_congestion_control
net.ipv4.tcp_congestion_control = cubic
$ sysctl net.ipv4.tcp_available_congestion_control
net.ipv4.tcp_available_congestion_control = reno cubic

2. 加载 tcp_bbr.ko 模块

1
2
3
$ modprobe tcp_bbr
$ sysctl net.ipv4.tcp_available_congestion_control
net.ipv4.tcp_available_congestion_control = reno cubic bbr

3. 自动加载 tcp_bbr.ko 模块

1
2
3
$ echo "tcp_bbr" >> /etc/modules-load.d/bbr.conf
$ cat /etc/modules-load.d/bbr.conf
tcp_bbr

4. 修改 sysctl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
$ echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
$ sysctl -p
vm.swappiness = 0
kernel.sysrq = 1
net.ipv4.neigh.default.gc_stale_time = 120
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_announce = 2
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 1024
net.ipv4.tcp_synack_retries = 2
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
$ sysctl net.ipv4.tcp_congestion_control
net.ipv4.tcp_congestion_control = bbr


赞赏支持
微信赞赏
微信赞赏
支付宝
支付宝