GoogleのTCP BBRでLinuxサーバーの高速化を試す
GoogleさんがLinuxに実装したTCPの輻輳制御モジュールでTCP通信がどのくらい高速化されるのか試してみる。環境はVirtualBox上にインストールしたCentOS7(64bit)。
具体的にはVMを2つ作成しiperfを使ってVM間のTCP通信性能がどのくらい変わるのか見てみる。
[rtoc_mokuji title=”” title_display=”” heading=”h3″ list_h2_type=”” list_h3_type=”” display=”” frame_design=”” animation=””]
BBRとは
BBRはGoogleが開発したTCP輻輳制御アルゴリズムおよびぞれを実装したプログラムであり従来より高速に通信ができますよ!という事らしい。
BBRの導入
BBRを使うためにはまずBBRに対応したカーネルにバージョンを上げる必要がある。
事前準備
カーネルのコンパイルに下記パッケージが必要になるのでインストールしておく。
$ sudo yum install bc ncurses-devel openssl-devel
カーネルのダウンロード
まずは公式のThe Linux Kernel Archivesからソースコードを持ってくる。
下記stable版のURLを確認してLinuxマシンにダウンロードする。

$ wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.12.4.tar.xz
ダウンロードが出来たらファイルを解凍し展開する。
$ xz -dv linux-4.12.4.tar.xz
$ tar xvf linux-4.12.4.tar
カーネルのコンフィグ
展開したディレクトに入り現在のカーネルコンフィグをコピーする。
$ cd linux-4.12.4
$ uname -a
Linux localhost.localdomain 3.10.0-327.el7.x86_64 #1 SMP Thu Nov 19 22:10:57 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
$
$cp /boot/config-3.10.0-327.el7.x86_64 .config
旧コンフィグを引き継ぐためにmake oldconfigを実行する。コンフィグ設定内容についての大量の質問が対話形式で行われるが面倒なのですべてdefault(すべてEnterキー)にする。
$ make oldconfig
scripts/kconfig/conf --oldconfig Kconfig
.config:600:warning: symbol value 'm' invalid for CPU_FREQ_STAT
.config:837:warning: symbol value 'm' invalid for NF_CT_PROTO_DCCP
.config:839:warning: symbol value 'm' invalid for NF_CT_PROTO_SCTP
.config:840:warning: symbol value 'm' invalid for NF_CT_PROTO_UDPLITE
.config:858:warning: symbol value 'm' invalid for NF_NAT_PROTO_DCCP
.config:859:warning: symbol value 'm' invalid for NF_NAT_PROTO_UDPLITE
.config:860:warning: symbol value 'm' invalid for NF_NAT_PROTO_SCTP
*
* Restart config...
*
*
* General setup
*
...(以降、ひたすらEnterキーを連打)
旧コンフィグを引き継いだらBBRのコンフィグ(defaultでは無効になっている)を有効にして.configを上書きする。
$ make menuconfig
ネットワークの項目から辿りBBRの項目を探して有効化する。






コンパイル~インストール
コンフィグ設定が完了したのでコンパイルしインストールする。
$ make
$ sudo make modules_install
$ sudo make install
インストールまで終わったらgrubのメニューにインストールしたカーネルが存在するか確認する。
$ sudo cat /etc/grub2.cfg
...(途中略)
menuentry 'CentOS Linux (4.12.4) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-327.el7.x86_64-advanced-e99ba373-abbc-4e11-a579-60f426ebcbb2' {
...(途中略)
linux16 /vmlinuz-4.12.4 root=/dev/mapper/centos-root ro crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet LANG=en_US.UTF-8
initrd16 /initramfs-4.12.4.img
}
...(途中略)
起動確認
Linuxマシン(VM)を再起動してgrubの画面でインストールしたカーネルを選択し起動する。

ログイン後に起動中のカーネルを確認して一致していればOK。
$ uname -a
Linux localhost.localdomain 4.12.4 #1 SMP Fri Jul 28 23:58:47 EDT 2017 x86_64 x86_64 x86_64 GNU/Linux
TCP輻輳制御の変更
BBRを有効にするにはカーネルパラメータを変更してBBRを有効にする必要がある。
net.ipv4.tcp_congestion_controlをbbrに設定して再起動すると有効になる。
$ cat /proc/sys/net/ipv4/tcp_congestion_control
cubic
$ sudo cp /etc/sysctl.d/99-sysctl.conf /etc/sysctl.d/99-sysctl.conf.orig
$ sudo vi /etc/sysctl.d/99-sysctl.conf
$ diff /etc/sysctl.d/99-sysctl.conf.orig /etc/sysctl.d/99-sysctl.con
+net.ipv4.tcp_congestion_control = bbr
$ sudo reboot
再起動後にbbrが有効になっていればOK。
$ cat /proc/sys/net/ipv4/tcp_congestion_control
bbr
$ lsmod |grep bbr
tcp_bbr 16384 0
性能測定環境の構築
iperfのインストール
性能測定用のツールは下記を使用する。
https://iperf.fr/iperf-download.php#fedora

URLを確認したらwgetでダウンロードしインストールする。
$ wget https://iperf.fr/download/fedora/iperf3-3.1.3-1.fc24.x86_64.rpm
$ sudo rpm -ivh iperf3-3.1.3-1.fc24.x86_64.rpm
VMのクローン作製
カーネルのアップデート、iperfのインストールまで完了したらVMを複製する。




性能測定
BBR対応のカーネルと測定ツールが用意できたので実際に通信性能を計測してみる。測定は下記パターンで実施して比較してみる。
測定パターン
(1) CentOS7デフォルトのカーネル
(2) アップデート後のカーネル(BBR無し)
(3) アップデート後のカーネル(BBR有り)
構成図
測定は下記のVM間で行う。

内部ネットワークの設定
用意した2つのVMで通信するために両VM共に内部ネットワークのアダプターを作成する。

それぞれ下記の固定IPを設定する。
VM1(クライアント側)
$ ip address show dev enp0s9
4: enp0s9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 08:00:27:1d:b8:43 brd ff:ff:ff:ff:ff:ff
inet 172.16.0.1/16 brd 172.16.255.255 scope global enp0s9
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe1d:b843/64 scope link
valid_lft forever preferred_lft forever
VM2(サーバ側)
$ ip address show dev enp0s9
4: enp0s9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 08:00:27:ff:86:a7 brd ff:ff:ff:ff:ff:ff
inet 172.16.0.2/16 brd 172.16.255.255 scope global enp0s9
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:feff:86a7/64 scope link
valid_lft forever preferred_lft forever
測定結果
iperfをオプション指定はせずに各パターンで実行した。
$ iperf -s #サーバ側
$ iperf -c 172.16.0.2 #クライアント側
結果サマリ
CentOS7デフォルトのカーネル
$iper3 -c 172.16.0.2
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 2.14 GBytes 1.84 Gbits/sec 4680 sender
[ 4] 0.00-10.00 sec 2.14 GBytes 1.84 Gbits/sec receiver
アップデート後のカーネル(BBR無し)
$iper3 -c 172.16.0.2
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 2.41 GBytes 2.07 Gbits/sec 3967 sender
[ 4] 0.00-10.00 sec 2.40 GBytes 2.07 Gbits/sec receiver
アップデート後のカーネル(BBR有り)
$iper3 -c 172.16.0.2
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 3.09 GBytes 2.65 Gbits/sec 120610 sender
[ 4] 0.00-10.00 sec 3.08 GBytes 2.65 Gbits/sec receiver
結果まとめ
# | 計測パターン | 帯域(Gbits/sec) | TCP再送数 |
---|---|---|---|
1 | CentOS7デフォルトのカーネル | 1.84 | 4680 |
2 | アップデート後のカーネル(BBR無し) | 2.07 | 3970 |
3 | アップデート後のカーネル(BBR有り) | 2.65 | 120610 |
BBR無しでも最新のカーネルではTCPの通信性能は上がってるぽい(?)
BBR有りの場合は帯域は向上して見えるがTCPの再送が30倍になっているのが少し気になるところ。
まとめ
確かにBBRによってTCP通信の高速化が期待できそうな結果となった。
TCPという昔から存在する技術(いい意味で枯れた技術)に性能向上のアプローチをしていること、実装が600行程のソースコードで書かれたモジュールによって実現している点が面白い。
ソースコードをじっくり読んでもっと理解を深めたい。
【参考】
CentOS6.3をLinuxカーネル3.6にアップデートしてみました(カーネル再構築) (linuxmaster.jp)
コメント