IoTデバイスのスループットがサクッと上がるかも

「データが上がって来るの遅いけど、電波悪いからしょうがないな〜」なんてアッサリ諦めてないでしょうか?

そんな方に「BBRを有効にすればスループットが上がるかも!」という話を、aptpod Advent Calendar 2019の9日目ではお送りします。担当のサーバーサイドエンジニアに憧れるエンベデッドエンジニア ochiai です。

はじめに

この記事では、BBRを有効にする方法と、スループットの実測にフォーカスしています。

なので、「BBRのアルゴリズムが知りたいんだよ!」とか、「輻輳制御アルゴリズムって何なのさ?」って方は、他の資料を参考にしてください。オススメを記載しておきます。

キーワード オススメ資料
BBRとは 本家Googleの資料
TCPの輻輳制御アルゴリズムの歴史 n月刊ラムダノート

BBRって

とはいっても、「いきなりBBRと言われても」と感じるかもしれませんので、簡単な紹介だけしたいと思います。

そもそも、電波が悪くてデータが届かない場合にはどうなっているのでしょうか?

もちろん、届かなければ、もう一度送って届くようにして欲しいですよね。とは言っても闇雲に何度も送ったのでは、それはそれでネットワークに無駄な負荷がかかってしまいます。

このあたりを賢く制御してくれているのが、TCPの輻輳制御です。

そして輻輳制御アルゴリズムで今注目をあびているのがBBR(Bottleneck Bandwidth and Round-trip propagation time)になります。

BBRを有効にする

では、BBRを動かすための準備をしていきましょう。

LinuxでBBRを使用するためには、カーネル4.9以降である必要があります。

ここでは、弊社で使用しているYoctoでの設定方法を紹介させて頂きます。

YoctoでBBRを有効にする

カーネルコンフィグを変更する必要があるので、menuconfigで変更を行います。
Yoctoでmenuconfigをするには、下記のコマンドを実行します。

$ cd <Yoctoのpokyディレクトリ>
$ source oe-init-build-env
$ bitbake linux-yocto -c kernel_configme -f
$ bitbake linux-yocto -c menuconfig

下図のようにGUIっぽい表示がされるので、方向キーと、スペースキーを使用して操作します。

f:id:aptpod_tech-writer:20191206140941p:plain

BBRと、BBRで必要なFQを設定するためには、下記の箇所を変更します。

- Networking support
  - Networking options                   <=== Spaceキーで有効化
    - TCP: Advanced Congestion Control
      -  BBR TCP                         <=== * にする
      -  Default TCP congestion control  <=== BBRにする
    - QoS and/or fair queueing
      - Fair Queue                       <=== * にする

完了したらsaveしてmenuconfigを終了します。

出来上がった.configをdefconfigとして登録したら、いつも通りにYcotoのイメージを焼き上げて完了です。

BBRが使用されていることを確認する

作成したイメージをデバイスにインストールしたら、BBRが動作しているかを確認します。

確認は、sysctl、ss、tcコマンドで行えます。

変更前
# 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

# sysctl net.core.default_qdisc
net.core.default_qdisc = pfifo_fast

# ss -tni
State       Recv-Q Send-Q                                                         Local Address:Port                                                                        Peer Address:Port              
ESTAB       0      280                                                       [::ffff:10.0.1.11]:22                                                                   [::ffff:10.0.2.127]:61981              
     cubic wscale:5,7 rto:204 rtt:3.117/0.808 ato:64 mss:1448 rcvmss:1392 advmss:1448 cwnd:10 bytes_acked:4441 bytes_received:4249 segs_out:52 segs_in:87 data_segs_out:47 data_segs_in:40 send 37.2Mbps lastrcv:8 lastack:4 pacing_rate 74.3Mbps delivery_rate 10.8Mbps app_limited unacked:2 rcv_rtt:7 rcv_space:28960 minrtt:1.282

# tc qdisc show
qdisc noqueue 0: dev lo root refcnt 2 
qdisc mq 0: dev enp1s0 root 
qdisc pfifo_fast 0: dev enp1s0 parent :1 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
変更後
# sysctl net.ipv4.tcp_available_congestion_control
net.ipv4.tcp_available_congestion_control = cubic bbr reno

# sysctl net.ipv4.tcp_congestion_control
net.ipv4.tcp_congestion_control = bbr

# sysctl net.core.default_qdisc
net.core.default_qdisc = fq

# ss -tni
State       Recv-Q Send-Q                                                         Local Address:Port                                                                        Peer Address:Port              
ESTAB       0      280                                                       [::ffff:10.0.1.11]:22                                                                   [::ffff:10.0.2.127]:61390              
     bbr wscale:5,7 rto:203 rtt:2.364/0.44 ato:40 mss:1448 rcvmss:1392 advmss:1448 cwnd:11 bytes_acked:4633 bytes_received:4205 segs_out:54 segs_in:88 data_segs_out:49 data_segs_in:39 bbr:(bw:14.0Mbps,mrtt:1.317,pacing_gain:2.88672,cwnd_gain:2.88672) send 53.9Mbps lastrcv:6 lastack:2 pacing_rate 41.7Mbps delivery_rate 14.0Mbps app_limited unacked:2 rcv_rtt:5 rcv_space:28960 minrtt:1.317

# tc qdisc show
qdisc noqueue 0: dev lo root refcnt 2 
qdisc mq 0: dev enp1s0 root 
qdisc fq 0: dev enp1s0 parent :1 limit 10000p flow_limit 100p buckets 1024 orphan_mask 1023 quantum 3028 initial_quantum 15140 low_rate_threshold 550Kbit refill_delay 40.0ms 

測定

測定方法

測定は下記のパターンで行いました。

  • ネットワーク環境
    • LTE
    • LTE(アッテネータ 10db1
    • LTE(アッテネータ 20db)
    • LAN
    • LAN(パケットロス 1%2
    • LAN(パケットロス 2%)
    • LAN(パケットロス 4%)
    • LAN(パケットロス 8%)
  • 輻輳制御アルゴリズム
    • BBR
    • CUBIC(元々使用していたアルゴリズム)

送信データは、IoTデバイス内で動作する弊社のintdash Edge Moduleから、秒間一定量のデータを送信して計測を行いました。

測定結果

Network CUBIC [KByte/sec] BBR [KByte/sec]
LTE (attenuation 0db) 674 631
LTE (attenuation 10db) 572 616
LTE (attenuation 20db) 261 559
LAN (loss 0%) 1126 1105
LAN (loss 1%) 1112 1138
LAN (loss 2%) 1078 1102
LAN (loss 4%) 779 1063
LAN (loss 8%) 381 1051

測定の結果、CUBICは、パケットロスする環境と、しない環境で、あきらかな差が出ました。
しかし、BBRは、パケットロスする環境と、しない環境で、あきらかな差が出ませんでした。

まとめ

BBRとCUBIC(元々使用していたアルゴリズム)で、データのスループットを比較した結果、下記グラフのようになりました。

f:id:aptpod_tech-writer:20191205142434p:plain

  • 一般的に言われている通り、パケットロスが多い時ほど効果を発揮する

事がわかりました。

このことから、通信環境が悪くパケットロスするような環境で、今までより早く送信できることが期待できます。

おわりに

最後まで読んでいただき、ありがとうございます。

はじめに書いた「BBRを有効にすればスループットが上がるかも!」が記事の趣旨の8割といっても過言ではないのですが、Yoctoで有効にする方法や、動作確認方法も参考になったようでしたら幸いです。

弊社のシステムでも、ここで紹介させて頂いた方法でBBRを有効にしたデバイスを順次出荷していく予定です!

以上、aptpod Advent Calendar 2019 9日目担当の ochiai でした。

明日は、先端技術調査グループ期待の新星、 okubo さんです!


  1. アッテネータはLTEのアンテナに接続して信号を減衰させる装置

  2. パケットロスはtcコマンドにより擬似的に発生させた