LinuxでBufferbloatを解消する:低遅延ネットワークのためのSQMとCAKE設定ガイド

Networking tutorial - IT technology blog
Networking tutorial - IT technology blog

午前2時のレイテンシの悪夢

深夜2時、私は心臓発作のような波形を描くモニタリングダッシュボードを凝視していました。リモートチームが100Mbpsの光回線で巨大なデータベースのバックアップを転送しようとしており、同時にVoIPシステムの通話が途切れ始めたのです。帯域幅は完全に飽和しているわけではなく、使用率は85%程度でしたが、ピング(ping)応答時間は20msから600msへと跳ね上がりました。これこそが、典型的なBufferbloat(バッファブロート)の兆候です。

私の実務経験から言えば、これは習得すべき不可欠なスキルの一つです。世界最速の光回線を持っていても、ルーターやLinuxサーバーのバッファ管理が不適切であれば、誰かがダウンロードやYouTubeのストリーミングを開始した瞬間にネットワークは重くなります。その晩、私はトラフィック制御(tc)のマニュアルを読み漁り、従来のQuality of Service(QoS)の手法ではもはや不十分であることに気づきました。よりスマートな解決策が必要だったのです。

敵を知る:Bufferbloatとは何か?

Bufferbloatは、ネットワーク機器に過剰に大きなバッファが設計されている場合に発生します。回線が混雑すると、これらのバッファがパケットで埋め尽くされます。ルーターは、送信元(TCP)に減速を促すためにパケットを早期に破棄するのではなく、すべてを保持しようとします。これらのパケットは長いキューの中で順番待ちをすることになり、その結果、他のすべての通信に膨大な遅延(レイテンシ)が発生します。

スーパーのレジを想像してみてください。もし店側が1つのレジに100人の行列を作ることを許してしまったら、たとえあなたがキャンディ1個しか持っていなくても、カートいっぱいに買い物した人たちの後ろで延々と待たされることになります。Smart Queue Management(SQM)は、少量のアイテムを持つ人のための専用レーンを開設し、誰も長く待ちすぎないようにする店長のような役割を果たします。

なぜCAKEが解決策になるのか

長年、Bufferbloat対策のゴールドスタンダードは fq_codel でした。しかし現在では、CAKE (Common Applications Kept Enhanced) が登場しています。CAKEは、いくつかの高度な技術を組み合わせたLinuxカーネル用の包括的なキューイング規則(qdisc)です。

  • 帯域幅シェーパー: 実際の回線速度よりわずかに低く制限することで、ボトルネックをISPの性能の低いモデムではなく、キューを制御できるLinuxマシン側で発生させます。
  • フローの分離: 重いダウンロードが、オンラインゲームの通信やDNSクエリを妨げないようにします。
  • DiffServへの対応: VoIPなどで使用されるトラフィックの優先度マーキングを尊重します。
  • ゼロ構成: 多くのクラスを持つ複雑な「tc」スクリプトを必要とした従来の手法とは異なり、CAKEはほとんど「設定したらあとはお任せ」で動作します。

前提条件とインストール

手順を進めるには、ゲートウェイとして動作しているか、大量のトラフィックを処理している Linuxマシンが必要です。最近のカーネル(4.19以降)のほとんどには、CAKEが組み込まれています。また、tcコマンドを提供する iproute2 パッケージが必要です。

まず、システムがCAKEをサポートしているか確認します:

modinfo sch_cake

モジュールの説明が表示されれば準備完了です。表示されない場合は、ディストリビューションに応じてカーネルを更新するか、iproute2-next パッケージをインストールする必要があるかもしれません。

Debian/Ubuntuの場合:

sudo apt update
sudo apt install iproute2

CAKEによるSQMの実装

戦略はシンプルです。Linuxの送信・受信速度を実際のISP帯域幅の約90〜95%に制限します。これにより、ISP側の管理不全なバッファが満杯になるのを防ぎます。

ステップ1:インターフェースと速度の特定

ネットワークインターフェース名(例:eth0wan0enp1s0)を確認します:

ip link show

スピードテストを実行して基準値を測定します。ここでは、下り100Mbps / 上り20Mbpsの回線を使用していると仮定します。

ステップ2:送信トラフィック(アウトバウンド)へのCAKEの適用

インターネットに面したインターフェースにCAKEを適用します。アップロード(egress)については、帯域幅を18Mbit(20Mbpsの90%)に設定します。

# 既存のqdiscを削除
sudo tc qdisc del dev eth0 root 2> /dev/null

# アップロード用にCAKEを追加
sudo tc qdisc add dev eth0 root cake bandwidth 18mbit besteffort triple-isolate wash

各フラグの意味は以下の通りです:

  • bandwidth 18mbit: ボトルネックをここで強制的に発生させます。
  • besteffort: ほとんどのインターネットトラフィックのデフォルトモードです。
  • triple-isolate: 送信元/宛先IPとポートに基づいてフローを分離します。これが、ダウンロード中でもゲームのピングを低く保つ秘訣です。
  • wash: シェーパーを混乱させる可能性のある余分なヘッダーをクリーンアップします。

ステップ3:受信トラフィック(インバウンド)の処理

ダウンロードの処理は少し複雑です。技術的に、インターネットから送られてくるものを直接制御することはできないからです。しかし、Intermediate Functional Block (IFB) を使用して、受信トラフィックをシェーピング(制御)可能なキューにリダイレクトすることができます。

まず、IFBモジュールを有効にします:

sudo modprobe ifb
sudo ip link set dev ifb0 up

次に、eth0 からの受信トラフィックを ifb0 にリダイレクトし、そこでCAKEを適用します(100Mbpsの回線に対して90Mbpsに設定):

# 受信トラフィックをリダイレクト
sudo tc qdisc add dev eth0 handle ffff: ingress
sudo tc filter add dev eth0 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0

# IFBデバイスにCAKEを適用
sudo tc qdisc add dev ifb0 root cake bandwidth 90mbit besteffort triple-isolate wash

検証とモニタリング

適用すると、すぐに違いを実感できるはずです。しかし、エンジニアとして感覚だけに頼るのではなく、データで確認しましょう。tc の統計コマンドを使用して、CAKEのパフォーマンスを確認します:

tc -s qdisc show dev eth0
tc -s qdisc show dev ifb0

backlogdropped の統計に注目してください。「dropped」パケットが表示されても、慌てる必要はありません。それはCAKEがその役割を果たしている証拠です。バッファが溢れないようにパケットを破棄し、送信側に減速を伝えているのです。

修正を完全に検証するには、Waveform Bufferbloat TestDSLReports Speedtest の使用をお勧めします。SQMが有効な状態でこれらを実行し、「A」または「A+」の評価を目指してください。これは、回線がフル稼働していてもレイテンシが安定していることを意味します。

微調整

まだレイテンシのスパイク(急上昇)が見られる場合は、帯域幅の制限をさらに5%下げてください。ISPは帯域を過剰に割り当てていたり、速度が変動したりすることがよくあります。100Mbpsの回線がピーク時に80Mbpsまで落ちる場合は、安全のためにCAKEの帯域幅を75Mbpsに設定すべきです。

DSLやPPPoEのような特定のオーバーヘッドがある接続を使用している場合、CAKEはそれらも処理できます。コマンドにキーワードを追加するだけです:

sudo tc qdisc replace dev eth0 root cake bandwidth 18mbit pppoe-vcmux

設定の永続化

tc コマンドによる設定は、再起動すると消えてしまいます。永続化するには、簡単なシェルスクリプトを作成し、systemdサービス、network-dispatcher(Ubuntu)、または if-up.d スクリプト経由で実行するのが最も一般的な方法です。

多くのユーザーにとって、シンプルなsystemdサービスを作成するのが最も確実な方法です:

[Unit]
Description=CAKE SQMを適用
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/apply-sqm.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

これでネットワークのレスポンスが向上したはずです。もう会議やゲームを終わらせるために、家族にダウンロードを止めるよう家中で叫ぶ必要はありません。CAKEが面倒な処理を引き受け、他の誰かのレイテンシを犠牲にすることなく、すべての通信に公平な帯域を割り当ててくれます。

Share: