[Linux, Network] Congestion Control algorithms in UEK5 preview - try out BBR

原文はこちら
https://blogs.oracle.com/wim/done-cancel-v6

UEK5の新機能の1つに、BBR(bottleneck bandwidth and round-trip propagation time、ボトルネック帯域幅と往復伝搬時間)と呼ばれる、新しいTCP輻輳制御管理アルゴリズムがあります。以下の論文が参考になります。
BBR Congestion Control
https://www.ietf.org/proceedings/97/slides/slides-97-iccrg-bbr-congestion-control-02.pdf
BBR, the new kid on the TCP block
https://blog.apnic.net/2017/05/09/bbr-new-kid-tcp-block/
Linuxはbic、cubic、westwood、hybla、vegas、h-tcp、venoなど、幅広く輻輳制御アルゴリズムをサポートしています。
TCP輻輳制御について(Wikipedia)
https://en.wikipedia.org/wiki/TCP_congestion_control
BBRを含む、重要なTCP輻輳制御の概要
https://blog.apnic.net/2017/05/09/bbr-new-kid-tcp-block/
これまで長く利用されてきたデフォルトアルゴリズムはcubicです(これはUEK5でも引き続きデフォルトです)。しかし、現在はBBRもサポートしています。メインラインのLinuxカーネルバージョン4.9にBBRが追加されました。UEK5ツリーは4.14のメインラインをベースにしていたため、UEK5でBBRを選択しました。UEKはGitHubから簡単にアクセスでき、コードを読むことができます。
Oracle Linux UEK: Unbreakable Enterprise Kernel
https://github.com/oracle/linux-uek
Tarファイルにしていないので、変更履歴を付けて全て取得してください(標準的なアップストリームカーネルの場合はバックポートや修正などを伴うgit)。
大規模なファイルをWAN経由でダウンロードまたはアップロードする場合に、BBRを使用して非常に有望なパフォーマンス改善が見られました。したがって、クラウドコンピューティングの使用や、オンプレミスとクラウド間のデータの移動など、状況によってはパフォーマンスが少し向上する可能性があります。いくつかのテストで10%ほどパフォーマンス向上を測定しましたが、状況はそれぞれ異なります。パケットロスが発生した場合は、確実に役立ちます。

UEKの優位性は、ソース、ターゲットのシステムをどちらもUEK上で実行する必要はない点です。そのため、BBRをテストするには、対向でOL7を実行し、UEK5をインストールした上で、当該システムでBBRを有効にするだけです。SSHやnetperf、wgetで大きなファイルをダウンロードしてみてください。
Oracle Linux 7 UEK5 (Linux kernel 4.14) sneak preview
https://blogs.oracle.com/wim/oracle-linux-7-uek5-linux-kernel-414-sneak-preview
https://orablogs-jp.blogspot.jp/2018/02/oracle-linux-7-uek5-linux-kernel-414.html
以下を実行する必要があります。再起動は不要です。
  • 2ノードのうち1個にOracle Linux 7をインストール
  • UEK5プレビューカーネルをインストールし、起動
  • (rootユーザーで)sysctlを使い設定を変更し、BBRを有効化(オンラインで設定可)
また、(デフォルトの)pfifo_fastの代わりにキュー規律(queue discipline)をfqに設定する必要もあります。
sysctl -w net.ipv4.tcp_congestion_control=bbr
sysctl -w net.core.default_qdisc=fq
デフォルトに戻すには
sysctl -w net.ipv4.tcp_congestion_control=cubic
sysctl -w net.core.default_qdisc=pfifo_fast
pfifo_fast vs fqも切り替えてみてください。

必要に応じて、Linuxの個々のソケットレベルで設定できます。あなたが特定のアプリケーション(Webサーバやデータ転送プログラムのようなもの)を持っている場合には、setsockopt()を使います。以下は設定例です。
sock = socket(AF_INET, SOCK_STREAM, 0);
sockfd = accept(sock, ...);
strcpy(optval, "bbr");
optlen = strlen(optval);
if (setsockopt(sockfd, IPPROTO_TCP, TCP_CONGESTION, optval, optlen) < 0)
   error("setsockopt(TCP_CONGESTION) failed");
Python(Python 3.6以上)でも同じようにできます。
sock.setsockopt(socket.IPPROTO_IP, socket.TCP_CONGESTION,...)
是非楽しんでください。みなさんにもメリットがあるか、どんなときにメリットがあるかお知らせください。

0 件のコメント:

コメントを投稿