🙋
10 Gbps の専用線を引いたのに、東京〜サンノゼ間でファイル転送したら 100 Mbps しか出ないんです。回線が壊れてるんでしょうか…?
🎓
回線は壊れてないよ、典型的な「BDP 不足」だね。BDP=帯域遅延積っていうんだけど、TCP は ACK が返ってこないと次のパケットを送れないから、回線にどれだけ「飛ばし続けられるデータがあるか」がスループットの上限を決めるんだ。10 Gbps × 80 ms ≈ 100 MB が BDP。これに対して Linux 既定の送信バッファは 4 MB くらいしかないから、100 MB に対して 4 %、つまり理論上 400 Mbps が頭打ち。100 Mbps しか出てないなら他の要因もあるけど、まずはここを潰そう。
🙋
なるほど!じゃあ送信バッファを 100 MB に増やせば 10 Gbps 出るんですか?左の「ウィンドウサイズ」を 65535 KB まで上げてみたら、確かに「ウィンドウ使用率」が 64 % まで上がりました。
🎓
いい感じだね。でも 65535 KB=64 MB は実は TCP の生のウィンドウサイズ上限なんだ。それ以上はウィンドウスケーリングオプション (RFC 1323) が必要になる。Linux なら net.ipv4.tcp_window_scaling=1 が既定で入ってるから、sysctl で rmem_max / wmem_max を 134217728 (128 MB) に増やせば 100 MB の BDP も埋められる。本ツールの「OS チューニング=最適化済」を選ぶと、その効果を 1.3 倍として概算してるよ。
🙋
パケット損失率も気になります。0.01 % から 0.1 % に上げただけで、Mathis 上限がガクッと下がりました。たった 0.1 % でこんなに効くんですか?
🎓
Mathis 公式は損失率の平方根の逆数で効くから、p が 10 倍になると上限は約 1/√10≈1/3.16 になる。これが「長距離回線で速度が出ない」現象の最大の犯人なんだ。WiFi で 1〜5 % の損失があると、CUBIC でも数 Mbps しか出ない。だから Google が BBR を作った。BBR は損失じゃなくて帯域と RTT を直接測るから、損失耐性が桁違いに高い。本ツールで「BBR」を選ぶと係数 1.5 倍になるよ。
🙋
CUBIC・Reno・BBR・Vegas って、どう使い分けるんですか?グラフを見ると BBR が一番速そうですが…
🎓
基本は「広域・高帯域なら BBR、社内 LAN なら CUBIC、低遅延が命なら Vegas」だね。BBR は速いけど、CUBIC と共存させると CUBIC の帯域を食い潰す「アンフェアネス」問題があるから、ISP のバックボーンや CDN では BBRv2/v3 への移行が進んでる。Reno は教科書には残ってるけど実運用ではもう使わない。Vegas は遅延を見て減速するから、ゲームや音声みたいにジッタが命の用途で意味がある。スループット最優先なら BBR、安定性なら CUBIC、低遅延なら Vegas、って覚えとくといいよ。
🙋
最後に、輻輳ウィンドウ (cwnd) って表示されてますけど、これって何ですか?ウィンドウサイズと違うんですか?
🎓
いい質問!TCP には「受信ウィンドウ rwnd」(受信側が告知する空きバッファ)と「輻輳ウィンドウ cwnd」(送信側が推定する回線の余裕)の 2 つがあって、実際に飛ばせるのは min(rwnd, cwnd) なんだ。本ツールで表示してる「輻輳ウィンドウ (packets)」は、ウィンドウサイズを MSS で割った「同時に飛ばせるパケット数」。例えば 64 KB ÷ 1460 B = 44 パケット。これが BDP=100 MB に対する 44 パケットだと回線がスカスカ。逆に 100 MB ÷ 1460 B ≈ 71800 パケット飛ばせれば 10 Gbps を埋め切れる、ってわけ。
BDP (Bandwidth-Delay Product) は「リンク帯域 × 往復遅延 (RTT)」で求めるネットワーク上を同時に飛んでいられるデータ量の上限です。例えば 10 Gbps の回線で RTT が 80 ms なら BDP は 10000 Mbps × 0.08 s = 800 Mbit ≈ 100,000 KB ≈ 97.66 MB になります。TCP の送信ウィンドウがこの BDP より小さいと、ACK 待ちで回線が遊んでしまい、太い回線を契約しても実効スループットが頭打ちになります。広域・高帯域ネットワークでは BDP を意識したウィンドウ設計が最重要です。
Mathis 公式は MSS と RTT、パケット損失率 p からスループット上限を概算する古典的な式で、Throughput ≈ MSS · 8 / RTT / sqrt(p) で書けます。損失率の平方根の逆数で効くため、p が 0.01 % から 0.1 % に増えると上限はおよそ 1/3 になります。広域ネットワークで「BDP は十分なのに速度が出ない」現象は、たいてい微小な損失が原因です。本シミュレーターはこの Mathis 上限と BDP 制約・OS チューニング・TCP 変種を組み合わせて、実効スループットを推定します。
Reno は最古典の AIMD(増加 1/RTT、損失時に半減)で、損失耐性が低く高帯域広域では性能が出ません。CUBIC(Linux のデフォルト)は時間の 3 乗関数で輻輳ウィンドウを増やすため、Reno より広域回線に強いのが特徴です。BBR(Google 開発)は損失ではなく帯域と RTT を直接推定するため、わずかな損失でも速度が落ちにくく、CUBIC の 1.5 倍程度の実効スループットが出やすい一方、共存性に課題があります。Vegas は遅延の増加を輻輳の前兆と見る低遅延向けで、損失前に減速します。本ツールでは各変種の係数を比較できます。
代表的な sysctl パラメータは net.core.rmem_max / wmem_max(ソケットバッファの上限)、net.ipv4.tcp_rmem / tcp_wmem(自動チューニング範囲)、net.ipv4.tcp_window_scaling(必須で 1)、net.ipv4.tcp_congestion_control(cubic / bbr)です。10 Gbps × 80 ms のような BDP=100 MB のリンクでは、デフォルトの 4 MB バッファでは全く足りないため、16〜128 MB に拡大する必要があります。BBR を使う場合は net.core.default_qdisc=fq とセットで有効化します。本ツールの「OS チューニング」で効果のオーダーを確認してから実機を触ると失敗が減ります。
長距離データセンター間バックアップ:東京〜シンガポール (RTT 70 ms)、東京〜ロンドン (RTT 240 ms) のような国際線で 1 TB クラスのデータをコピーする場面では、BDP が 100 MB〜2 GB に達します。既定のソケットバッファでは 1 Gbps の回線でも 50 Mbps 程度しか出ません。rmem_max/wmem_max を BDP の 2〜3 倍に設定し、CUBIC または BBR を選び、aspera / scp の代わりに UDT / FASP / Multipath TCP を使うと、実効スループットが 10〜20 倍に改善します。
クラウドへのアップロード/CDN オリジン同期:S3 / Cloud Storage / Azure Blob への大容量アップロードは、内部的に並列 TCP セッションを張ることで BDP 制約を回避しています。AWS の「マルチパートアップロード」が 8〜16 並列を推奨するのは、1 セッションあたりのウィンドウ上限を並列化で乗り越えるためです。CDN のオリジン同期でも同様で、HTTP/2 のストリーム多重化や QUIC の採用は BDP 不足の根本対策になります。
衛星・無線リンク(Starlink・LEO・5G):衛星リンクは RTT が 500〜800 ms と長く、Starlink (LEO) でも 30〜50 ms あります。地上の 4G/5G より RTT が桁違いに大きいため、CUBIC では帯域の半分も使い切れないことが多いです。Starlink が BBR を採用しているのはこの理由で、損失率が変動しても帯域を維持できます。船舶・航空機通信や災害対応ネットワークでは BBR + 大バッファが標準的な構成になりつつあります。
金融取引・低遅延 HPC:逆に取引所への発注やインターコネクトでは「スループットより RTT を 1 μs でも縮める」のが目的です。ここでは BBR / CUBIC のような帯域追求型ではなく、Vegas や DCTCP のような遅延追求型を使い、バッファをあえて小さく保ちます。Cisco / Mellanox の HFT 向け NIC では TCP オフロード + カーネルバイパス (DPDK / Solarflare OpenOnload) で μs オーダーの遅延を実現します。
最大の落とし穴は「ウィンドウサイズを大きくすれば速くなる」と思い込むことです。確かに BDP より小さいウィンドウはボトルネックですが、BDP を超えてウィンドウを増やすと今度は「バッファブロート (Bufferbloat)」が発生します。ルータのキューに過剰なパケットが溜まり、RTT が数倍に膨らみ、結果として VoIP やゲーム、双方向通信の品質が大きく劣化します。CoDel / FQ-CoDel / FQ といった AQM (Active Queue Management) を併用しないと、本ツールの「最適化済」設定でも逆効果になることがあります。BBR が損失より RTT を見るのは、まさにこのバッファブロートを回避するためです。
次に多いのが「Mathis 上限を絶対視する」こと。Mathis 公式は Reno の数学モデルで、CUBIC や BBR には正確には当てはまりません。CUBIC は損失耐性が Reno の 2〜3 倍、BBR はそもそも損失をシグナルにしないため、Mathis 公式で計算した上限を大きく超えるスループットが出ます。本ツールでは TCP 変種ごとに係数を乗じて補正していますが、これも一次近似です。実機での測定 (iperf3 -P 8 / TCP_INFO) と必ず突き合わせてください。
最後に「片方向だけチューニングすれば良い」という誤解。TCP は送信側 (sndbuf) と受信側 (rcvbuf) の両方のバッファサイズが効きます。AWS EC2 のような片側だけ rmem_max を上げても、相手側 (オンプレ) の wmem_max が小さければそちらが上限になります。BDP の半分以下のウィンドウしか張れず、スループットが頭打ちになります。両端で sysctl を揃えるか、可能なら自動チューニング (tcp_rmem / tcp_wmem) の上限を BDP の 2 倍以上に設定しましょう。さらに、ジャンボフレーム (MSS=9000) は L2 区間が全部対応していないと PMTUD 失敗で逆に遅くなるので、社内 LAN 限定で使ってください。