09月03, 2017

Google BBR拥塞控制算法模型初探

Kernel 4.9 正式版本的发布带来了一些令人激动的特性以及一些驱动的更新。 其中来自 Google 的 TCP BBR (Bottleneck Bandwidth and RTT) 拥塞控制算法也在这个版本并入了主线。

0x00 Background

几个月前就在Github上fork了Google开源的神器BBR算法,但是一直都没有深入去分析研究。最近看Kubernetes相关的文档突然想起了这个神器,于是我大晚上的搭了一台测试机对TCP BBR进行了测试。

根据以往的传统,G家总是先在自家的生产环境上线运用后,才会将代码开源,此次也不例外。我在一台代理服务器节点上部署了TCP BBR 拥塞控制算法。从电信出口到日本Vultr的实测下载速度从381KB/s提高到了4.26MB/s.

补充测试环境说明:是在日本的Vultr服务器上配置了 BBR,日本的服务器是数据的发送方。这个服务器是访问墙外资源的 HTTP 代理。我本地的电信出口到代理服务器之间不是dedicated专线,走的是公网,电信出口这边是 10Mbps 无限速(但是要跟其他人share),代理服务器实测是限速1Mbps。RTT 是 96 ms。实测结果这么好,也是因为大多数人用的是 TCP Cubic (Linux) / Compound TCP (Windows),在有一定丢包率的情况下,TCP BBR 更加激进,抢占了更多的公网带宽。因此也是有些不道德的感觉。

0X01 Contrastive Analysis

人类的公式都太依赖时间t了,人们总是希望在我们生存的三维空间里尽量压缩时间来提高效率。谈到效率,那么决定效率的一定是分母时间t吗?不然,这个哲学问题有太多其他的答案了。

而之前的Reno/CUBIC之所以蒙蔽了人类这么久,正是因为程序员和CS科学家都是一群事件驱动的群体。他们在为TCP建立性能模型的时候,总是希望通过用Time-series/RTT-series analysis来查到一个连接最快能跑多少数据。

但是这些都是错的,我们奉为神明的时间t的产物时间轴,具有滞后性这一致命的缺点。自从1973年TCP/IP被Prof. Vinton G. Cerf提出之后,诸如Reno/CUBIC等经典TCP拥塞算法的目标都是收敛于一个逻辑滞后的收敛点,不断地增加数据的传输,试图填满整个网络以及网络上的所有缓存,以为这样就会达到比较高的带宽利用率,直到发现丢包,然后迅速降低数据发送量,之后重新向那个错误的收敛点前进,如此反复。这就是锯齿的根源。而BBR则在一个不随时间滑动的大概10秒的时间窗口中采集最小RTT,如果有更多的带宽,那么就利用它,如果没有,就退回到之前的状态。

以上就是Reno/CUBIC和BBR的区别,它们同样完成了"To find current bandwidth", "To avoid congestion", "To probe more bandwidth"的逻辑,只是一个是事件驱动的被动实现,一个是反馈驱动的主动实现。

关于TCP BBR算法分析,MSRA的李博杰博士在知乎上给出了这样的解释:

TCP BBR 致力于解决两个问题:

  1. 在有一定丢包率的网络链路上充分利用带宽。
  2. 降低网络链路上的 buffer占用率,从而降低延迟。

0x02 Quck Start Guide

如果你也想感受神器的强大,首先需要一台linux 4.9内核版本以上的机器(现在居然已经出到4.10了,不过gregkh已经宣布4.9将是LTS版本),为了不影响线上机器的正常运行,我在Vultr上买了一台新的CentOS来测试=. =

要在 CentOS 上安装最新的内核版本,我们需要增加一个 ELRepo 源。首先,让我们添加 ELRepo GPG key:

rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org

之后添加 CentOS-7的 源:

rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm

安装fastestmirror (Vultr的镜像已经自带了,保险起见,可以确定一下)

yum install yum-plugin-fastestmirror

最后,安装 kernel 主线版本

yum --enablerepo=elrepo-kernel install kernel-ml

当然,将 kernel-ml 选为第一启动

grub2-set-default 0

重启后,通过 uname -a 查看内核是否已经切换到最新版

$ uname -a

在确定安装好了4.9以上版本内核之后,我们就可以开启TCP BBR了。

sudo echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
sudo echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf

重启后,首先 uname -a 看下内核是否切换,然后执行下面明亮查看内核是否开启 TCP BBR

sudo sysctl net.ipv4.tcp_available_congestion_control
sudo sysctl net.ipv4.tcp_congestion_control

查看 tcp_bbr 模块是否加载

lsmod | grep tcp_bbr

如果已经加载成功,就可以愉快地开始测试了。

0x03 More Info

最后需要提示一点,TCP 拥塞控制算法是数据的发送端决定发送窗口,因此在哪边部署,就对哪边发出的数据有效。如果是下载,就应在server部署;如果是上传,就应在client部署。

关于TCP BBR与标准TCP的公平性问题,我的观点是如果服务器都采用BBR,实际效果就归于平均了,但总体资源利用率会有所提升,好在Google把BBR算法并入内核mainline了。

如果你想用更加优雅的姿势升级Kernel,请移步如何优雅的升级内核

本文链接:https://www.opsdev.cn/post/tcp-bbr.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。