BBR の帯域・RTT推定モデル
ロスを待たずに回線の実力を測りきる輻輳制御がBBR。ボトルネック帯域と最小RTTを直接推定し、高遅延・軽微ロス回線でも詰まらず速く流す原理を押さえます。
- 1.BBRはボトルネック帯域BtlBwと最小RTT(RTprop)を別々に測り、その積BDPを満たすだけ送る。ロス率は信号に使わない。
- 2.BtlBwは直近約10RTTの配送レート最大値、RTpropは約10秒窓のRTT最小値で推定し、両者の積で適正なin-flight量を決める。
- 3.ProbeBW(8段ペーシングゲインのサイクル)で帯域を探り、ProbeRTTで定期的にin-flightを絞ってRTpropを測り直す状態機械で動く。
BBR が解こうとした問題
CUBIC や Reno などのロスベース輻輳制御は、パケットロスを輻輳の合図に使います。だが現代の回線では前提が崩れる。バッファが深いボトルネックではロス前にキューが溜まり遅延だけ膨らみ(bufferbloat)、浅いボトルネックでは輻輳でないランダムロスで速度が落ちます。
BBR(Bottleneck Bandwidth and Round-trip propagation time)はロスを信号にしません。代わりに経路の実力そのもの、ボトルネック帯域と伝搬遅延を直接推定し、それを満たすだけ送ってキューを作らずに帯域を埋めます。
BBRの動作点は、in-flight(送信済み・未ACK)のデータ量を帯域遅延積(BDP)に保つこと。少なすぎれば帯域が余り、多すぎればキューに溜まって遅延が増えるだけ。BDPちょうどが帯域100%・キュー最小の理想点です。
2つの量を別々に測る
BBRが推定する量は次の2つで、同時には正確に測れないという制約が設計を決めています。
- BtlBw(Bottleneck Bandwidth): 経路上で最も狭い区間の配送レート。各ACKから得る配送レート(delivered量 ÷ 経過時間)の、直近およそ 10RTTぶんの最大値を採用する。最大値を取るのは、キューが空でボトルネックを完全に使えた瞬間こそ真の帯域だから。
- RTprop(Round-trip propagation time): キュー遅延を含まない純粋な往復伝搬遅延。観測RTTの、およそ 10秒窓の最小値を採用する。最小値を取るのは、キューが空のときのRTTだけが伝搬遅延に等しいから。
ここに本質的なジレンマがあります。帯域を測るにはキューを満たすほど送る必要があり、伝搬遅延を測るには逆に絞ってキューを空ける必要がある。片方を測ると他方が測れないため、BBRは両者を時間的に分離して交互に推定します。これが状態機械の動機です。
推定した2量から、送るべき量を決めます。
BDP = BtlBw * RTprop # 適正なin-flightの基準量
in-flight ≈ cwnd_gain * BDP # cwnd_gainは約2(後述)
ペーシング速度 = pacing_gain * BtlBw # ACKを待たず時間軸で送出を整形
cwnd(ウィンドウ上限)は通常 2 * BDP 程度に置きます。係数2は、ACK返しの遅延やデバイスのバースト的なACK集約(aggregation)があっても帯域を100%使い切るための余裕です。
BBRはウィンドウだけでなくペーシングでレートを直接制御します。一度にバースト送信せず、pacing_gain * BtlBw の速度で時間的に均して送出するため、ボトルネックに瞬間的なキューを作りにくい。これがロスベース方式との実装上の大きな違いです。
状態機械:Startup → Drain → ProbeBW → ProbeRTT
BBRは4つの状態を遷移しながら、上記2量を測り続けます。
- Startup: 接続開始直後。
pacing_gain ≈ 2/ln2 ≈ 2.89で指数的に増速し、帯域を素早く探る。配送レートが3RTT連続でほぼ頭打ちになったら、ボトルネックに達したと判断して次へ。 - Drain: Startupで作りすぎたキューを吐き出す。
pacing_gainを逆数にしてin-flightをBDPまで落とす。 - ProbeBW: 定常状態。
pacing_gainを[1.25, 0.75, 1, 1, 1, 1, 1, 1]の8段で巡回させる(各段はおよそRTprop長)。1.25でわずかに増速して空いた帯域を探り、もし帯域が増えていればBtlBwの最大値が更新される。続く0.75で、増速中に作ったキューを吐き出して遅延を戻す。残り6段の1.0で安定して流す。 - ProbeRTT: RTpropを測り直すための状態。約10秒間RTprop最小値が更新されないと突入し、in-flightを 4パケットまで絞って最低200ms維持する。キューが空くので、ここで観測した最小RTTを新しいRTpropとして採用する。
startup_done queue_drained
Startup ───────────▶ Drain ───────────────▶ ProbeBW ◀─┐
│ │ RTprop更新
RTprop未更新 │ │(ProbeRTT完了)
約10秒経過 ▼ │
ProbeRTT ──┘
ProbeRTTでin-flightを数パケットまで絞るため、その約200msは瞬間スループットが落ちます。多数のフローが同期して同時にProbeRTTへ入ると全体効率が一時的に下がるので、短時間・低頻度(最短10秒に1回)に抑える設計です。
ロスベース制御との違い
同じ「速く・公平に流す」目的でも、何を信号にするかが根本的に異なります。
| 観点 | BBR | ロスベース(CUBIC/Reno) |
|---|---|---|
| 輻輳の信号 | BtlBwとRTpropの推定値 | パケットロス(ACK欠落・重複ACK) |
| 動作点 | BDPちょうど(キュー最小) | バッファを満たしてロス直前まで |
| 深いバッファ | 遅延を膨らませない | bufferbloatで遅延が増大 |
| 軽微なランダムロス | ほぼ影響を受けない | ロスを輻輳と誤認し速度低下 |
| 送出制御 | ペーシング(レート直接制御) | 主にウィンドウ増減(AIMD等) |
高遅延で軽微なロスがある**長く太い管(BDPの大きい経路)**ほどBBRの優位が出ます。ロスベースはBDPが大きいほどウィンドウを大きく育てる必要があるのに、途中のロスで頻繁に縮むため帯域を埋めきれないからです。BDPの基礎は帯域・レイテンシ・スループットも参照。
「BBRはロス率を輻輳の指標に使わない」「BtlBwは配送レートの最大値、RTpropはRTTの最小値で推定」「動作点はBDPちょうど」「ProbeBWの増速ゲインは1.25、ProbeRTTでin-flightを4パケットに絞る」——この4点を区別できれば原理は説明できます。
公平性と注意点
初版BBRv1は万能ではありません。BtlBwを最大値で測るため、複数BBRフローが同居すると帯域配分が偏ることがあり、深いバッファでCUBICと競合するとロスを待つCUBIC側が不利になりがちです。これらを直すため、ロス率やECNも補助信号に取り込むBBRv2/v3が開発されています。
実務ではQUIC(HTTP/3)やLinuxサーバーの送信側で採用が進みます。前提となるTCP と UDP、品質制御の全体像QoSと合わせると位置づけが見えてきます。
ネットワーク Article
BBR の帯域・RTT推定モデルを実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
BBR
比較で見る軸
難易度: advanced / カテゴリ: ネットワーク / タグ数: 5
導入後に効く点
BtlBwは直近約10RTTの配送レート最大値、RTpropは約10秒窓のRTT最小値で推定し、両者の積で適正なin-flight量を決める。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- ネットワーク
- タグ数
- 5
判断チェックリスト
- 自社の用途が「BBR / 輻輳制御」に近いか確認する。
- 強みである「BBRはボトルネック帯域BtlBwと最小RTT(RTprop)を別々に測り、その積BDPを満たすだけ送る。ロス率は信号に使わない。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。