フロー制御

読み:ふろーせいぎょ / 英語表記:Flow Control

受信側の処理能力やバッファの空きに合わせて、送信側が送るデータの量や速さを調整する通信制御。受信側があふれてデータを失うことを防ぐもので、ネットワーク全体の混雑を抑える輻輳制御とは目的が異なる。

イマシルちゃんの解説

送る側のコンピュータが速くて、受け取る側がゆっくりしか処理できないと、届いたデータを置いておく場所がいっぱいになっちゃう。
あふれたデータは捨てられて、送り直しが必要になるんだ。
そこで受け取る側が「今はここまでなら受け取れるよ」「少し待って」と送る側に伝えるの。
こうして送る量を相手に合わせて調整する通信制御をフロー制御というよ。
TCPでは受け取れる量を「ウィンドウ」として知らせ、イーサネットでは一時停止を頼むPAUSEフレームを送るんだ。
相手のペースに合わせて送るから、むだな送り直しを減らせるんだね。

より深い解説

目的と位置付け

通信では、送信側と受信側の処理速度が同じとは限らない。高性能なサーバが低速な端末へ送る場合や、受信側のアプリケーションが一時的に忙しい場合には、受信側の一時記憶領域がいっぱいになる。そのまま送り続けると、あふれたデータは捨てられ、再送が必要になる。フロー制御は、受信側の状態を送信側へ伝え、送る量を受信側が処理できる範囲に抑える仕組みである。

フロー制御は特定の一つのプロトコルの名前ではない。さまざまな層で、それぞれの方法によって実現されている。

層・場面代表的な方法制御する範囲
シリアル通信RTS/CTS信号、XON/XOFF文字直接つながった2台の機器間
データリンク層HDLCのRNR、イーサネットのPAUSEフレーム隣接する機器間(ホップごと)
トランスポート層TCPの受信ウィンドウ、QUICのフロー制御通信する端末どうし(エンドツーエンド)
アプリケーション層HTTP/2のウィンドウ更新ストリームやコネクションごと

データリンク層のフロー制御は、隣り合う機器の間だけで働く。経路の途中にある各機器が、自分の受信側の状態を手前の機器に伝える。トランスポート層のフロー制御は、途中の機器に関係なく、最終的にデータを受け取る端末の状態を送信元に伝える。

基本となる方式

フロー制御の方式は、大きく分けると次のとおりである。

方式動作特徴
ストップアンドウェイト1つ送るたびに確認応答を待つ単純だが、遅延が大きいと効率が悪い
スライディングウィンドウ確認応答を待たずに一定量まで続けて送る確認応答が届いた分だけ送信可能な範囲をずらす
オン・オフ制御受信側が停止と再開を指示するXON/XOFFやPAUSEフレームが該当する
クレジット方式受信側が受け入れ可能な量(クレジット)を与える送信側はクレジットの範囲で送る

表の2行目の方式では、確認応答を受け取った分だけ送信可能な範囲を前にずらし、続きを送る。複数のデータをまとめて送れるため、一つずつ確認する方式より回線を効率よく使える。

計算例:待ち時間と効率

10Mbit/sの回線で、1,000オクテットのフレームを送る場合を考える。1フレームの送信時間は次のとおりである。

1,000 × 8 ÷ 10,000,000 = 0.0008秒 = 0.8ms

フレームを送り終えてから確認応答が戻るまでに9.2msかかるとする。ストップアンドウェイトでは、1フレームあたり0.8 + 9.2 = 10msの周期になる。

実効速度 = 8,000ビット ÷ 0.01秒 = 800kbit/s
回線の使用効率 = 0.8ms ÷ 10ms = 8%

ウィンドウを5フレームにすると、1周期で5フレーム送れるので実効速度は4Mbit/sになる。回線を休みなく使うには、10ms ÷ 0.8ms = 12.5なので、13フレーム以上のウィンドウが必要になる。遅延が大きい経路ほど、大きなウィンドウが必要になるわけである。

TCPのフロー制御

TCPでは、受信側が受け入れ可能なデータ量を、TCPヘッダーのウィンドウサイズ欄に入れて通知する。この値を受信ウィンドウ(rwnd)という。送信側は、確認応答を待っているデータの量が受信ウィンドウを超えないように送る。仕様はRFC 9293で定められている。

実際に送れる量は、受信側が通知する受信ウィンドウと、送信側が輻輳を推定して決める輻輳ウィンドウ(cwnd)の小さいほうで決まる。次の独自例で確認する。

項目値
受信ウィンドウ32,000オクテット
輻輳ウィンドウ48,000オクテット
送信済みで確認応答待ちのデータ20,000オクテット

送信の上限は32,000オクテットになり、追加で送れるのは32,000 − 20,000 = 12,000オクテットである。

受信側のアプリケーションがデータを読み出さないと、受信バッファが埋まり、ウィンドウサイズ0が通知される。これをゼロウィンドウという。送信側は送信を止めるが、ウィンドウが開いたことを知らせる通知が失われると、互いに待ち続けてしまう。そこで送信側は持続タイマーを使い、定期的に小さなセグメント(ウィンドウプローブ)を送って状態を確かめる。

ウィンドウサイズ欄は16ビットのため、そのままでは65,535オクテットまでしか通知できない。高速で遅延の大きい経路では、RFC 7323のウィンドウスケールオプションで値を拡大する。また、受信側がわずかな空きのたびに小さなウィンドウを通知すると、小さなセグメントばかりが送られて効率が落ちる。これをシリーウィンドウシンドロームといい、送受信の双方で小さな通知や送信を控える対策がとられている。

イーサネットのPAUSEフレーム

イーサネットでは、全二重の接続で受信側が送信側に一時停止を求めるPAUSEフレームが使われる。もとはIEEE 802.3xとして1997年に追加され、現在はIEEE 802.3の本体に統合されている。半二重の接続では使えない。

項目内容
種類MAC制御フレーム(タイプ値0x8808)
宛先MACアドレス予約されたマルチキャストアドレス 01-80-C2-00-00-01
オペコード0x0001
停止時間(pause_time)16ビット。単位は512ビット時間

停止時間は、そのリンクで一定のビット数を送る時間を単位として指定する。1Gbit/sでは1ビットの送信に1nsかかるので、1単位は512nsになる。最大値65,535を指定したときの停止時間は次のとおりである。

65,535 × 512ns = 33,553,920ns ≒ 33.6ms

10Gbit/sでは同じ値でも約3.36msになる。停止時間に0を入れたPAUSEフレームを送ると、待たずに送信の再開を求められる。PAUSEを使うかどうかは、オートネゴシエーションで相手と取り決めることができる。

PAUSEフレームはリンク上のすべての通信を止める。そのため、音声などの急ぎの通信まで巻き添えで待たされる。スイッチが受けた停止を手前へ次々に伝えると、関係のない端末の通信まで止まることがある。一般的なLANでは、通信の損失をTCPの再送と輻輳制御に任せ、PAUSEを使わない設計も多い。

データセンターでは、FCoEなどパケットの損失を許さない通信のために、優先度ごとに停止できるPFC(Priority-based Flow Control)が使われる。IEEE 802.1Qbbで定められ、8つの優先度ごとに停止と再開を制御できる。止めたい優先度の通信だけを止め、ほかの通信は流し続けられる。

なお、半二重のポートで衝突を意図的に起こすなどして相手の送信を抑える機能を、バックプレッシャーと呼ぶ製品がある。これは製品の機能であり、PAUSEフレームとは別の仕組みである。

シリアル通信とHDLCのフロー制御

RS-232Cなどのシリアル通信では、2種類の方法がある。信号線を使うハードウェアフロー制御では、RTS(送信要求)とCTS(送信可)の信号で、送ってよいかを伝える。制御文字を使うソフトウェアフロー制御では、データの中にXOFF(DC3、0x13)を送って停止を求め、XON(DC1、0x11)で再開させる。

ソフトウェアフロー制御は信号線が少なくて済む。ただし、送りたいデータの中に同じ値のバイトが含まれると、停止や再開の指示と誤って解釈される。バイナリデータを送る場合は、信号線を使う方式を選ぶ。

HDLCでは、受信側が受信の準備ができていないことをRNR(Receive Not Ready)で知らせ、準備ができたらRR(Receive Ready)で再開を伝える。

HTTP/2とQUICのフロー制御

HTTP/2は、一つのTCPコネクションの中で複数のストリームを同時に扱う。TCPのフロー制御はコネクション全体にしか効かないため、HTTP/2はストリームごとにも独自のフロー制御を持つ。受信側はWINDOW_UPDATEフレームで受け入れ可能な量を追加する。初期値は65,535オクテットである(RFC 9113)。トランスポート層で動作するQUICでも、コネクション全体とストリームごとの上限をMAX_DATAやMAX_STREAM_DATAで通知する(RFC 9000)。

混雑を抑える制御との違い

フロー制御と輻輳制御は、どちらも送信量を調整する。しかし、何を守るかが異なる。

観点フロー制御輻輳制御
守る対象受信側の端末や機器経路上のネットワーク全体
判断の材料受信側からの明示的な通知パケットの損失や遅延の増加から推定する
TCPでの値受信ウィンドウ(rwnd)輻輳ウィンドウ(cwnd)
値を決める側受信側送信側

受信側が十分に速くても、経路の途中が混雑していれば輻輳制御が送信量を絞る。逆にネットワークが空いていても、受信側のバッファが小さければフロー制御が上限になる。午前問題では、この二つの説明を入れ替えた誤りの選択肢がよく使われる。

設計と障害の切り分け

フロー制御が原因で性能が出ない例は多い。主なものを示す。

症状確認すること
回線は空いているのにTCPのスループットが低い受信バッファとウィンドウスケールの設定、RTT
パケットキャプチャでゼロウィンドウが続く受信側のアプリケーションやディスクの処理が追いついているか
スイッチのPAUSE受信カウンタが増え続ける接続先の機器の処理能力、PAUSE設定の不一致
一部の端末の不調でほかの通信まで遅くなるPAUSEの連鎖、PFCの対象とする優先度の設計

Wiresharkなどのパケットキャプチャでは、ゼロウィンドウやウィンドウの更新が記録される。受信側がウィンドウを0にしている場合、遅い原因はネットワークではなく受信側の処理にある。ネットワーク機器を増強しても改善しない。

午後での問われ方

実際の試験ではここに出る!全4問

ネットワークスペシャリスト

午前Ⅱ

この用語が出てくる記事

↑