传统 TCP 拥塞控制算法,基于丢包反馈的协议。
基于「丢包反馈」的协议是一种 被动式 的拥塞控制机制,其依据网络中的丢包事件来做网络拥塞判断。即便网络中的负载很高时,只要没有产生拥塞丢包,协议就不会主动降低自己的发送速度。
这种协议可以最大程度的利用网络剩余带宽,提高吞吐量。然而,由于基于丢包反馈协议在网络近饱和状态下所表现出来的侵略性,一方面大大提高了网络的带宽利用率;但另一方面,对于基于丢包反馈的拥塞控制协议来说,大大提高网络利用率同时意味着下一次拥塞丢包事件为期不远了,所以这些协议在提高网络带宽利用率的同时也间接加大了网络的丢包率,造成整个网络的抖动性加剧。
还有谁导致了丢包?丢包并不总是拥塞导致,丢包可能原因是多方面,比如:
- 全球最牛的防火墙 GWF 的随机丢包策略
- 网路中由于多路径衰落(multi-path fading)所造成的信号衰减(signal degradation)
- 通道阻塞造成的丢包(packet drop),再者损坏的封包(corrupted packets)被拒绝通过
- 有缺陷的网路硬件、网路驱动软件发生故障
- 信号的信噪比(SNR)的影响
Google BBR 的出现
我们自然不喜欢 GWF 这种人为的随机丢包策略,当路过 GWF 时,数据被丢包,我们在此时应该立刻重新发包,增大发送的频率,而不希望降低速度,也就是不希望传统的 TCP 拥塞算法去控制。
由此,就出现了基于不丢包的拥塞控制算法 CDG, 以 延迟 作为判断依据,延迟增大说明拥塞, 数据开始在路由器的缓冲中积累. 降低发送 窗口。然而 CDG 算法与基于丢包的算法不兼容, 只有全球的设备都换上 CDG,但这是不可能的,目前市面上的设备不可能一下子都切换到 CDG,因此 Google 就不开心了,Google 的科学家们开发了一种过渡算法来解决这个问题,这个算法的名字就是 BBR(Bottleneck Bandwidth and RTT),它是一种全新的 拥塞控制算法,BBR 同 CDG 一致的思想是不以丢包作为拥塞控制信号,但是和 CDG 不同的是,BBR 能和 cubic 和 reno 共存。
使用BBR前后网络吞吐量对比图:
BBR 由 Google 开发,供 Linux 内核的 TCP 协议栈使用,有了 BBR 算法,Linux 服务器可以显著提高吞吐量并减少连接延迟,简单来说 BBR 能加速网络传输速度。此外,部署 BBR 也很容易,因为该算法只需要发送方,而不需要网络或接收方的支持。
在Linux上检查TCP拥塞控制算法
默认情况下,Linux使用Reno和CUBIC拥塞控制算法,要检查可用的拥塞控制算法
sysctl net.ipv4.tcp_available_congestion_control
输出如下:
net.ipv4.tcp_available_congestion_control = cubic reno
要检查当前使用的拥塞控制算法
sysctl net.ipv4.tcp_congestion_control
输出如下:
net.ipv4.tcp_congestion_control = cubic
没错,就是使用 cubic 这个默认的算法。接下去我们通过最标准的模式来为这台 Ubuntu 16.04 启用 BBR。
为 Ubuntu 16.04 安装 4.10 + 新内核
如果你简单地了解过 BBR,那么就知道 BBR 只能配合 Linux Kernel 4.10 以上内核才能使用。但是在 Ubuntu 16.04 上怎么使用 4.10 呢?难道要手动下载和安装吗?
不能!这会有一个安全隐患,手动下载安装的新内核,无法保证后续能得到及时的安全更新。那么怎么办?这里我推荐使用 HWE 版本的内核,它就在官方源里。
HWE,即:HareWare Enablement,是专门为在老的系统上支持新的硬件而推出的内核。你可以像安装其他软件包一样在 Ubuntu 16.04 里非常容易的安装它:
sudo apt-get install linux-generic-hwe-16.04
只要这样,就 OK 了…是不是超简单?这里还有一个 Tips:假如你想使用更激进的新内核,可以使用 edge 版本,不大推荐
sudo apt-get install linux-generic-hwe-16.04-edge
这两个软件包不同的是,前一个安装的是 4.10 内核,后一个安装的是 4.11,充分满足想追求使用新内核的同学的需求。
安装好以后重启电脑,然后输入:
uname -a
已经变成 4.10 内核了
Unbuntu16.04服务器实例上部署 BBR
1、首先,升级服务器内核版本到4.9以上否则会提示以下问题
2、启用BBR
需要修改sysctl配置,以启用BBR算法
首先运行lsmod |grep bbr 查看是没有BBR的# modprobe tcp_bbr
echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
sysctl -p
如果内核不支持运行modprobe命令时会出错:modprobe: FATAL: Module tcp_bbr not found.
查看下是否启用了BBR
sysctl net.ipv4.tcp_available_congestion_control
sysctl -n net.ipv4.tcp_congestion_control
# lsmod |grep bbr
/etc/sysctl.conf配置信息如下:
#
# /etc/sysctl.conf - Configuration file for setting system variables
# See /etc/sysctl.d/ for additional system variables.
# See sysctl.conf (5) for information.
#
#kernel.domainname = example.com
# Uncomment the following to stop low-level messages on console
#kernel.printk = 3 4 1 3
##############################################################3
# Functions previously found in netbase
#
# Uncomment the next two lines to enable Spoof protection (reverse-path filter)
# Turn on Source Address Verification in all interfaces to
# prevent some spoofing attacks
#net.ipv4.conf.default.rp_filter=1
#net.ipv4.conf.all.rp_filter=1
# Uncomment the next line to enable TCP/IP SYN cookies
# See http://lwn.net/Articles/277146/
# Note: This may impact IPv6 TCP sessions too
#net.ipv4.tcp_syncookies=1
# Uncomment the next line to enable packet forwarding for IPv4
#net.ipv4.ip_forward=1
# Uncomment the next line to enable packet forwarding for IPv6
# Enabling this option disables Stateless Address Autoconfiguration
# based on Router Advertisements for this host
#net.ipv6.conf.all.forwarding=1
###################################################################
# Additional settings - these settings can improve the network
# security of the host and prevent against some network attacks
# including spoofing attacks and man in the middle attacks through
# redirection. Some network environments, however, require that these
# settings are disabled so review and enable them as needed.
#
# Do not accept ICMP redirects (prevent MITM attacks)
#net.ipv4.conf.all.accept_redirects = 0
#net.ipv6.conf.all.accept_redirects = 0
# _or_
# Accept ICMP redirects only for gateways listed in our default
# gateway list (enabled by default)
# net.ipv4.conf.all.secure_redirects = 1
#
# Do not send ICMP redirects (we are not a router)
#net.ipv4.conf.all.send_redirects = 0
#
# Do not accept IP source route packets (we are not a router)
#net.ipv4.conf.all.accept_source_route = 0
#net.ipv6.conf.all.accept_source_route = 0
#
# Log Martian Packets
#net.ipv4.conf.all.log_martians = 1
#
net.ipv4.neigh.default.base_reachable_time_ms = 600000
net.ipv4.neigh.default.mcast_solicit = 20
net.ipv4.neigh.default.retrans_time_ms = 250
net.ipv4.conf.all.rp_filter=0
net.ipv4.conf.eth0.rp_filter=0
net.ipv4.conf.eth1.rp_filter=0
net.ipv4.tcp_fastopen=3
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
参考:https://github.com/google/bbr