輻輳制御
ネットワークが混雑(輻輳)しないように、送信側が送るデータの量を調整する仕組み。TCPでは、輻輳ウィンドウの大きさを増減させて制御する。
イマシルちゃんの解説
道路が渋滞しているのに、みんなが車をどんどん出したら、ますます動かなくなっちゃうよね。
輻輳制御は、「道が空いてそうなら少しずつ車を増やして、混んできたらぐっと減らす」っていう、送る側の思いやりなんだ。
ネットワークを使うみんながこれを守るから、インターネット全体が渋滞で止まらずに済んでいるんだよ!
より深い解説
定義
輻輳制御は、ネットワークの途中(ルータのキューや回線)が混雑してパケットが失われたり、遅延が大きくなったりすることを防ぐため、送信側が送信量を調整する仕組みである。TCPでは、送信側が輻輳ウィンドウ(cwnd)を持ち、確認応答を待たずに送れる量を、受信側が通知するウィンドウ(rwnd)と輻輳ウィンドウの小さいほうに制限する。
フロー制御との違い
| フロー制御 | 輻輳制御 | |
|---|---|---|
| 守る対象 | 受信側のバッファ | ネットワーク(途中のルータや回線) |
| 量を決める情報 | 受信側が通知するウィンドウサイズ | 送信側が推測するネットワークの状態 |
| 使うウィンドウ | 受信ウィンドウ(rwnd) | 輻輳ウィンドウ(cwnd) |
基本的な動作(TCP Reno)
| 段階 | 動作 |
|---|---|
| スロースタート | 小さな輻輳ウィンドウから始め、確認応答を受け取るたびに増やす。1往復(RTT)ごとに、ほぼ2倍になる(指数関数的な増加) |
| 輻輳回避 | 輻輳ウィンドウがしきい値(ssthresh)に達したら、1往復ごとに1セグメントずつ増やす(線形の増加) |
| 高速再送・高速リカバリ | 重複ACKを3つ受け取ったら、損失したセグメントをすぐに再送し、輻輳ウィンドウを半分程度に減らして、輻輳回避から再開する |
| タイムアウト | 再送タイマーが切れたら、輻輳がひどいと判断し、輻輳ウィンドウを最小に戻してスロースタートからやり直す |
「スロースタート」という名前だが、実際の増え方は指数関数的で、速い。名前は「いきなり大量に送らず、小さく始める」ことに由来する。
このような増え方をする理由
| 方式の考え方 | 名前 | 意味 |
|---|---|---|
| 加算的に増やし、乗算的に減らす | AIMD(Additive Increase / Multiplicative Decrease) | 少しずつ増やし、混雑したら大きく減らすことで、複数の通信が公平に帯域を分け合うようになる |
主な輻輳制御アルゴリズム
| アルゴリズム | 混雑の判断 | 特徴 |
|---|---|---|
| Reno / NewReno | パケット損失 | 古典的な方式 |
| CUBIC | パケット損失 | 輻輳ウィンドウを3次関数で増やす。高速で遅延の大きい回線でも速度を出しやすい。LinuxやWindowsの標準 |
| Vegas | 遅延の増加 | RTTが増え始めたら、損失の前に送信量を減らす |
| BBR | 帯域とRTTの推定 | 損失ではなく、ボトルネックの帯域と最小RTTから、最適な送信の速さを決める |
ネットワーク側の仕組み
| 仕組み | 内容 |
|---|---|
| RED(ランダム早期検出) | キューがいっぱいになる前から、確率的にパケットを捨てて、送信側に早めに減速を促す |
| ECN(明示的輻輳通知) | パケットを捨てる代わりに、IPヘッダーに「混雑している」という印を付けて送信側に伝える |