web-dev-qa-db-ja.com

ブロッキングストリームをTCP接続に多重化することは良い考えですか?

2つのホスト間にいくつかの二重チャネルが必要です。 TCP接続を1つだけ確立することには多くの利点があります。しかし、多重化がいくつかの不可避の問題を引き起こすとは思えません。パフォーマンスに悪影響を与えるか、レイテンシを大幅に増加させますか?メモリ使用量とCPU使用量はどうですか?何か提案や注意点はありますか?

13
Sherwood Wang

TLDR:TCPの上に複数のチャネルを多重化するときに気づくかもしれない主な欠点は、 行頭ブロッキングにより遅延が増加 チャンネル間。

当然の結果:レイテンシを気にしない場合は、問題ありません。

一方、単一のTCP接続を使用する 「他のフローとの競争が少なくなり、接続の寿命が長くなるため、使用可能なネットワーク容量の使用率が向上します」

TCPを介したヘッドオブラインブロッキング

同じTCPストリーム上で複数のチャネルを多重化する場合、チャネルは 行頭ブロッキング の影響を受ける可能性があります。

トランスポートプロトコルが順序付けられたサービスまたは部分的に順序付けされたサービスを提供する場合、ヘッドオブラインブロッキング(HOL)が発生する可能性があります。セグメントが失われた場合、後続のメッセージは受信キューでの再送信が成功するまで待機する必要があるため、遅延します。

TCPの上に複数のストリームを多重化すると、HOLチャネル間が発生します。

チャネルAがTCP送信バッファをいっぱいにした場合、チャネルBの新しいデータをリモートアプリケーション層に効果的に送信するには、このデータがすべて受信されるまで待機する必要があります。

TCP上のチャネルの多重化と hackernewsに関する議論 の詳細については、 "TCP上の多重化" を参照してください。

TCPを介した多重化の例

SSH経由のチャネル多重化(TCP経由)

この典型的な例はSSHです。 SSHは複数のチャネルを多重化できます(OpenSSHのControlMasterControlPathおよびControlPersistを参照)。これを使用すると、新しいSSHセッション(初期レイテンシ)の初期化のコストが削減されますが、通常、1つのチャネルでの重い転送により、他のチャネルのレイテンシ/対話性が増加します(複数のTCPストリームを使用する場合は発生しません)。インタラクティブセッションを使用していて、同じチャネルを介して重いファイル転送を開始すると、セッションのインタラクティブ性が大幅に低下します。

多重化されたHTTP/2 over TCP

HTTP/2は、HOLブロッキングを修正するために、TCPを介した要求/応答の多重化を使用します。この機能は、HTTP/2に関する多くの記事や論文で宣伝されています。 HTTP/2 RFC の主張:

HTTP/1.1はリクエストのパイプライン化を追加しましたが、これはリクエストの並行性に部分的に対処しただけで、依然として行頭ブロッキングの影響を受けています。

[...]

結果として得られるプロトコルは、HTTP/1.xと比較して使用できるTCP接続が少ないため、ネットワークにより友好的です。これは、他のフローとの競争が少なくなり、接続の寿命が長くなることを意味します。これにより、利用可能なネットワーク容量の利用率が向上します。

ただし、説明されていないのは、HOLブロッキングが完全には解決されないということです。 HTTP/2 over TCPはまだ TCPレベルのHOLブロッキング による の影響を受ける )です。

これは、QUICに関するこの LWNの記事 で説明されています。

HTTP/2は、この問題に対処するために設計されました 単一の接続に組み込まれた複数の「ストリーム」。 [...]新しい問題が発生します。単一のパケットが失われると、すべてのストリームの送信が一度に停止し、新しい遅延の問題が発生します。 行頭ブロッキング問題のこのバリアントは、TCP自体に組み込まれています また、HTTPレベルでさらに調整することで修正することはできません。

その他の多重化戦略

SCTP

これはSCTP(マルチストリーミング)の際立った機能の1つであり、同じSCTPアソシエーションで複数の独立したストリームを持つことができ、各ストリームは他のストリームをブロックしません。

SSHでクロスチャネルHOLブロッキングを回避するためにSCTPを使用する効果については、 SCTP over SCTP —マルチチャネルプロトコルをSCTPに適応させることで最適化する を参照してください。

SCTPは、単一のストリーム内のメッセージの順序のみを保持して、行頭ブロッキングと呼ばれる影響を軽減します。メッセージが失われた場合、順序を維持するために失われたメッセージが再送信されるまで、後続のメッセージを遅らせる必要があります。同じストリームのメッセージのみを遅延させる必要があるため、損失後の影響を受けるメッセージの数が削減されます。

[...]

SSHのチャネルをSCTPのストリームにマッピングすることにより、マルチストリーミングの利点をSSHで利用できるようになります。これは、行頭ブロッキングの軽減です。

SCTPの導入は必ずしも容易ではありません(OSの可用性、ミドルボックスの相互作用などのため)。可能性は、それを実装することです over UDPin userspace

QUIC(UDPを介した多重化)

別の例は、実験的な [〜#〜] quic [〜#〜] プロトコルであり、UDPを介したHTTPの多重化に使用されます( TCP HTTP/2はHOLブロッキングの影響を受けます ):

QUICは、TCPに比べて遅延を減らすの新しいトランスポートです。表面的には、QUICはUDPに実装されたTCP + TLS + HTTP/2によく似ています。

[...]

行頭ブロッキングなしの多重化

GoogleのQUICプロトコル:WebをTCPからUDPに移動する は、TCP上でチャネルを多重化する場合のQUICおよびHOLブロッキングの概要を示しています。

最近のプレゼンテーションでは、 HTTP over QUIC はレイテンシを改善するが、HOLブロッキングの改善は「小さなメリット」であると主張しています。

0-RTT、待ち時間の50%以上の改善

[…]

タイムアウトベースの再送信が少ないほど、テールレイテンシが向上します[…]

その他の小さなメリット、たとえば行頭ブロッキング

QUICは「UDPに実装されたTCP + TLS + HTTP/2と非常によく似ている」と説明されていますが、実際には 汎用トランスポート であり、HTTP/2とは独立して使用でき、ニーズ。

注:HTTP/QUIC siは HTTP/ として標準化されます。

10
ysdx

ZeroMQガイド を読む必要があると思います。理由とデメリットを伴うパターンは重要な読み物です。

それ以外の場合は、アプリケーションデータ配信からネットワークチャネルを切断しても問題はありません。送信されたデータパケットの多重化と逆多重化(および、ここではパケットベースのアーキテクチャをお勧めします。連続フローでデータをストリーミングするのではなく)と、両端でのそれらのバッファリングを行う必要があります。

それ以外の場合はほとんど影響がありません。データをバッファリングするためにメモリが少し必要になりますが、パケットをロックして解析するためのコードを処理するときにCPUが少し必要になりますが、重要なものはありません。 (大規模なスループットとパフォーマンスを必要とする専門家を作成している場合を除きます)。

3
gbjbaanb

はい、私はまさにこの原則を使用してクライアント/サーバーデータベースシステムを構築しました。

1つのTCP接続に多重化されたチャネルは、それぞれデータのパケットを送信します。それは次に、相手側のそれぞれの受信者に分割されます。

TCP接続送信者は、送信準備ができているデータを持つチャネルの中から送信するパケットをラウンドロビンで選択することにより、1つの雑然としたチャネルによる接続の占有を行います。

1つのチャネルが1GBのパケットを送信することを決定し、他の全員をロックアウトするケースを処理するために、送信者はパケットをチャンクに分割し、1つのチャンクのみを送信してから、別のチャネルに順番を渡すことができます。受信側では、受信者がパケットを見る前に、チャンクをパケットに再構成します。

2