5.1K Views
April 14, 23
スライド概要
詳解システムパフォーマンス第2版からネットワークチューニングの一部を紹介しました
LIFULL HOME'Sを運営する株式会社LIFULLのアカウントです。 LIFULLが主催するエンジニア向けイベント「Ltech」等で公開されたスライド等をこちらで共有しております。
詳解システム・パフォーマンス紹介 LIFULL社内技術勉強会 秀野 亮
感想文 詳解システム・パフォーマンス第2版は全体で900ページ ざっと見た感じ、ほぼ全ての基礎知識が網羅されてそう 1つ1つの項目は数行〜数十行程度で、これだけだと役に立たない 第2章 メソドロジ(方法論)から読んでいくのがよさそう(↓学習目的抜粋 ) ● レイテンシ、使用率、飽和度などの主要な指標を理解する ● ナノ秒までの計測時間の単位を感覚として理解する ● チューニングのトレードオフ、ターゲット、分析を中止すべきタイミングについて学ぶ ● ワークロードの問題かアーキテクチャの問題かを見分けられるようにする ● リソース分析かワークロード分析かを考えられるようにする ● USEメソッド、ワークロードの特性の把握、レイテンシ分析、静的パフォーマンスチューニング、パフォーマンスマント ラなどのさまざまなパフォーマンスメソドロジの筋道をたどる
今回 今回は、第10章ネットワークから10.8チューニングについて紹介 ● ネットワークスタック ● sysctl.conf ○ net.core.netdev_max_backlog, net.core.somaxconnなど ※AmazonLinux2のインスタンスタイプごとに違ったらごめん ※ 現行AmazonLinux2のカーネルは4.14 sh-4.2$ uname -r 4.14.305-227.531.amzn2.x86_64
ネットワーク構成 参考:詳解システム・パフォーマンス TCPバッファリング:ソケット送受信バッファ TCP接続キュー:SYN backlog、Listen backlog 輻輳制御:CUBIC、Reno、BBR キューイング規則:パケット順序変更、遅延、破棄 ドライバキュー: EC2のENA、割り込み一体化モード CPUスケーリング: RSS、RPS、RFS、ARFS、XPS
CPUスケーリング prod tlog$ mpstat -P ALL Linux 4.14.309-231.529.amzn2.x86_64 04/06/2023 _x86_64_ (16 CPU) 01:17:48 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 01:17:48 PM all 2.53 0.03 0.65 0.04 0.00 0.03 0.00 0.00 0.00 96.73 01:17:48 PM 0 1.07 0.02 0.24 0.32 0.00 0.00 0.00 0.00 0.00 98.35 01:17:48 PM 1 1.14 0.05 0.21 0.00 0.00 0.00 0.00 0.00 0.00 98.59 01:17:48 PM 2 1.15 0.04 0.21 0.00 0.00 0.00 0.00 0.00 0.00 98.60 01:17:48 PM 3 3.29 0.02 0.98 0.00 0.00 0.07 0.00 0.00 0.00 95.64 01:17:48 PM 4 2.04 0.02 0.30 0.28 0.00 0.00 0.00 0.00 0.00 97.36 01:17:48 PM 5 3.78 0.05 1.06 0.00 0.00 0.07 0.00 0.00 0.00 95.03 01:17:48 PM 6 1.88 0.04 0.28 0.00 0.00 0.00 0.00 0.00 0.00 97.80 01:17:48 PM 7 3.87 0.02 1.01 0.00 0.00 0.06 0.00 0.00 0.00 95.02 01:17:48 PM 8 3.83 0.02 1.02 0.00 0.00 0.07 0.00 0.00 0.00 95.06 01:17:48 PM 9 3.74 0.02 1.06 0.00 0.00 0.07 0.00 0.00 0.00 95.10 01:17:48 PM 10 3.77 0.02 1.09 0.00 0.00 0.07 0.00 0.00 0.00 95.05 01:17:48 PM 11 3.38 0.02 1.04 0.00 0.00 0.07 0.00 0.00 0.00 95.49 01:17:48 PM 12 1.77 0.02 0.33 0.00 0.00 0.00 0.00 0.00 0.00 97.87 01:17:48 PM 13 1.26 0.02 0.24 0.00 0.00 0.00 0.00 0.00 0.00 98.48 01:17:48 PM 14 3.08 0.02 1.00 0.00 0.00 0.07 0.00 0.00 0.00 95.82 01:17:48 PM 15 1.36 0.02 0.24 0.00 0.00 0.00 0.00 0.00 0.00 98.38
CPUスケーリング TCP/IPのパケット処理に複数CPUを使って効率を上げる EC2の拡張ネットワーキングで複数キューになる mpstat -P ALL で特定コアに負荷が偏ってないか確認 ● RSS(Receive Side Scaling) ○ ● RPS(Receive Packet Steering) ○ ● 複数のキューを持つNICでパケットを複数のCPUに割り当てる 複数のキューを持たないNICのためにソフトウェアでRSSを実装 RFS(Receive Flow Steering) ○ RPSに似てる、CPUのキャッシュヒット、メモリの局所性が高まる ● ARFS(Accelerated Receive Flow Steering) ● XPS(Transmit Packet Steering)
キューイング規則 前に誰かが言ってたtc(Traffice Control)コマンドで操作するやつ AmazonLinux2で使えなかったので↓ $ sudo yum install iproute-tc qdisc(Queueing discipline)やSchedulerと呼ばれる機能で、パケットの順序 変更、遅延、破棄を行う 帯域制限にも使える
キューイング規則 qdiscアルゴリズムは選択できる AmazonLinux2はデフォルト pfifo_fast だった sh-4.2$ sysctl net.core.default_qdisc net.core.default_qdisc = pfifo_fast fq_codelをデフォルトにするディストリビューションが増えてる ● pfifo_fast ○ 優先度キュー付きFIFO ● fq_codel(Fair-Queueing with Controlled Delay) ○ ○ 低速環境等でペーシングするとBufferbloatが発生するのを回避 fqでnet.ipv4.tcp_notsent_lowatを下げると解決する場合もある模様
輻輳制御 ネットワークの負荷を慮って送信する技術 ゆっくり送り始めたり、パケットロスを検知してみたり フロー制御(受信者の容量を聞いて送信量を気遣う)とは違う AmazonLinux2だとCUBICがデフォルトだった sh-4.2$ sudo sysctl net.ipv4 | grep conges net.ipv4.tcp_allowed_congestion_control = cubic reno net.ipv4.tcp_available_congestion_control = cubic reno net.ipv4.tcp_congestion_control = cubic
輻輳制御 ● Reno ○ ● CUBIC ○ ● 重複する3個のACK検出によって輻輳ウィンドウが半分になり、スロースタート閾値が半分になり、高速再 送、高速回復??? ウィンドウのスケーリングのため三次関数を使い、スロースタートからの脱出のためにハイブリッドスタート関 数を使う???。Renoよりアグレッシブ。Linuxのデフォルト。 BBR ○ ウィンドウベースでなくプロービングフェーズを使ってネットワークパス特性 (RTTと帯域幅)の明示的なモデル を構築する。劇的にパフォーマンスが上がるか、下がる???。 BBRv2が開発中。 ● BBRv2(参考: https://jglobal.jst.go.jp/detail?JGLOBAL_ID=202102217224967865) ● (略)1BDP未満の小さいバッファにおける不公平性と攻撃性を改善する。多重 BBRv2フローは帯域幅共有に おいてより良い公平性を示すだけでなく,パケット再送信の量も低減する。 ○ しかし、RTT不公平性,損失ベースアルゴリズムの共存,およびBBRv2フロー間の同期のような挑戦的課題が なお存在する。 DCTCP(DataCenter TCP) ○ ○ ○ キューが非常に浅い段階でECNを生成するよう設定されたスイッチを前提として利用可能帯域幅まで急上 昇させる??? 制御されたローカルネットワークなどで大幅に性能向上。インターネット向けではない。
輻輳制御 参考:第4回 BBRの出現 | gihyo.jp sh-4.2$ find /lib/modules -name tcp_* /lib/modules/4.14.305-227.531.amzn2.x86_64/extra/net/ipv4/tcp_bic.ko /lib/modules/4.14.305-227.531.amzn2.x86_64/extra/net/ipv4/tcp_highspeed.ko /lib/modules/4.14.305-227.531.amzn2.x86_64/extra/net/ipv4/tcp_htcp.ko /lib/modules/4.14.305-227.531.amzn2.x86_64/extra/net/ipv4/tcp_hybla.ko /lib/modules/4.14.305-227.531.amzn2.x86_64/extra/net/ipv4/tcp_illinois.ko /lib/modules/4.14.305-227.531.amzn2.x86_64/extra/net/ipv4/tcp_lp.ko /lib/modules/4.14.305-227.531.amzn2.x86_64/extra/net/ipv4/tcp_scalable.ko /lib/modules/4.14.305-227.531.amzn2.x86_64/extra/net/ipv4/tcp_vegas.ko /lib/modules/4.14.305-227.531.amzn2.x86_64/extra/net/ipv4/tcp_veno.ko /lib/modules/4.14.305-227.531.amzn2.x86_64/extra/net/ipv4/tcp_westwood.ko /lib/modules/4.14.305-227.531.amzn2.x86_64/extra/net/ipv4/tcp_yeah.ko /lib/modules/4.14.305-227.531.amzn2.x86_64/kernel/net/ipv4/tcp_bbr.ko /lib/modules/4.14.305-227.531.amzn2.x86_64/kernel/net/ipv4/tcp_dctcp.ko /lib/modules/4.14.305-227.531.amzn2.x86_64/kernel/net/ipv4/tcp_diag.ko sh-4.2$ modprobe tcp_bbr sh-4.2$ sudo sysctl net.ipv4.tcp_congestion_control=bbr ※カーネル 4.13からsudo sysctl net.core.default_qdisc=fqはいらないっぽい
TCP接続キュー TCPの3WAYハンドシェイク時に 2つのキューが使われる 昔はキューが 1つしかなくてSYN Flood攻撃を食らって死んだ ↓ SYNクッキーを使ってクライアントがすでに認可済みである場合、 SYNバックログをバイパスさせる 参考: 未知の領域でのSYNパケット処理
sysctl /proc/sys/net にシステム全体のネットワーク関連設定がある cat で参照、echo で設定 詳細はもうここ↓を見ればいいと思う https://linuxjf.osdn.jp/JFdocs/Adv-Routing-HOWTO/lartc.kernel.obscure.html サーバーを再起動すると設定は消える /etc/sysctl.conf で永続化する
sysctl net.core.default.qdisc = fq net.core.netdev_max_backlog = 5000 Netflixの例 net.core.rmem_max = 16777216 net.core.netdev_max_backlog=1000 net.core.somaxconn = 1024 net.core.somaxconn=4096 net.core.wmem_max = 16777216 net.ipv4.ip_local_port_range = 10240 65535 net.ipv4.tcp_abort_on_overflow = 1 に変更する検討をしていたとか何とか(2020年 当時) net.ipv4.tcp_congestion_control = bbr net.ipv4.tcp_max_syn_backlog = 8192 net.ipv4.tcp_rmem = 4096 12582912 16777216 意外に小さい… net.ipv4.tcp_slow_start_after_idle = 0 とにかくでかくすればいいと思ってました net.ipv4.tcp_syn_retries = 2 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_wmem = 4096 12582912 16777216
sysctl TCPバッファのサイズは読み (rmem)書き(wmem)の設定ができる net.core.rmem_max = 16777216 (最大16MB) net.core.wmem_max = 16777216 (最大16MB) これで受信バッファサイズの自動調整 (AmazonLinux2デフォルト) net.ipv4.tcp_moderate_rcvbuf = 1 3つの数値はそれぞれ、下限・デフォルト・上限、を表す (AmazonLinux2デフォルト) フルスピードの 10GbE接続では16MB以上にするって書いてあるけど …これ小さくない? net.ipv4.tcp_rmem = 4096 87380 6291456 (4KB 85KB? 6MB) net.ipv4.tcp_wmem = 4096 20480 4194304 (4KB 20KB 4MB)
sysctl TCPバックログ 1つ目のSYNバックログは大きく設定している(AmazonLinux2デフォルトは128) 大きい数値を設定するとSYN受け入れたはいいけどACKを受け取るまでのクライアントの待機時間は長くなる net.ipv4.tcp_max_syn_backlog = 65536 2つ目のListenバックログも大きく設定している(AmazonLinux2デフォルトは128) ハードリミットなので大きな数値を設定しても実際はlisten()の引数次第らしい net.core.somaxconn = 65536 負荷のバーストに対応するため、デフォルトより増やしたほうがいいとは書いてある net.ipv4.tcp_max_syn_backlog = 4096〜 net.core.somaxconn = 1024〜
sysctl CPUごとのNICのバックログ(AmazonLinux2デフォルトは1000) 10GbEなら10000以上がいいかもね、とのこと net.core.netdev_max_backlog = 65536
今後 ほぼ素の設定なのでチューニングの余地がある やたらキューサイズがでかいがデメリットはないのか 設定変更後の計測には、ツールやメソドロジを知っている必要がある