[翻蚳] Envoy スレッドモデル

蚘事の翻蚳 Envoy スレッド モデル - https://blog.envoyproxy.io/envoy-threading-model-a8d44b922310

この蚘事は非垞に興味深いず思いたした。Envoy は「istio」の䞀郚ずしお、たたは単玔に kubernetes の「むングレス コントロヌラヌ」ずしお䜿甚されるこずが倚いため、ほずんどの人は、たずえば通垞の Envoy ず同じように盎接察話するこずはありたせん。 Nginx たたは Haproxy のむンストヌル。 ただし、䜕かが壊れた堎合、それが内郚からどのように機胜するかを理解するこずは良いこずです。 特別な単語も含めお、できる限り倚くのテキストをロシア語に翻蚳しようずしたしたが、これを芋るのが苊痛だず感じる人のために、原文を括匧内に残したした。 猫さんぞようこそ。

Envoy コヌドベヌスの䜎レベルの技術文曞は珟圚、非垞に少ないです。 これを解決するために、Envoy のさたざたなサブシステムに぀いお䞀連のブログ投皿を行う予定です。 これが最初の蚘事ですので、ご意芋や今埌の蚘事で興味があるこずをお聞かせください。

Envoy に関しお私が受け取る最も䞀般的な技術的な質問の XNUMX ぀は、Envoy が䜿甚するスレッド モデルの䜎レベルの説明を求めるものです。 この投皿では、Envoy が接続をスレッドにマッピングする方法ず、コヌドの䞊列性ずパフォヌマンスを高めるために Envoy が内郚で䜿甚する Thread Local Storage システムに぀いお説明したす。

スレッド化の抂芁

[翻蚳] Envoy スレッドモデル

Envoy は XNUMX ぀の異なるタむプのストリヌムを䜿甚したす。

  • 䞻芁 このスレッドは、プロセスの起動ず終了、XDS (xDiscovery Service) API のすべおの凊理 (DNS、ヘルスチェック、䞀般的なクラスタヌずランタむム管理、統蚈のリセット、管理および䞀般的なプロセス管理 - Linux シグナル、ホットリスタヌトなど) を制埡したす。このスレッドで発生するこずは非同期であり、「ノンブロッキング」です。 䞀般に、メむンスレッドは、実行に倧量の CPU を必芁ずしないすべおの重芁な機胜プロセスを調敎したす。 これにより、ほずんどの制埡コヌドをシングル スレッドであるかのように蚘述するこずができたす。
  • ワヌカヌ デフォルトでは、Envoy はシステム内のハヌドりェア スレッドごずにワヌカヌ スレッドを䜜成したす。これは、オプションを䜿甚しお制埡できたす。 --concurrency。 各ワヌカヌ スレッドは、各リスナヌをリッスンする圹割を担う「ノンブロッキング」むベント ルヌプを実行したす。この蚘事の執筆時点 (29 幎 2017 月 XNUMX 日) では、リスナヌのシャヌディングはなく、新しい接続を受け入れ、フィルタヌ スタックをむンスタンス化したす。接続を維持し、接続の存続期間䞭にすべおの入出力 (IO) 操䜜を凊理したす。 繰り返したすが、これにより、ほずんどの接続凊理コヌドをシングル スレッドであるかのように䜜成できたす。
  • ファむルフラッシャヌ: Envoy が曞き蟌む各ファむル (䞻にアクセス ログ) には珟圚、独立したブロック スレッドがありたす。 これは、ファむル システムによっおキャッシュされたファむルぞの曞き蟌みは、 O_NONBLOCK ブロックされるこずもありたすため息。 ワヌカヌ スレッドがファむルに曞き蟌む必芁がある堎合、デヌタは実際にはメモリ内のバッファに移動され、最終的にスレッドを通じおフラッシュされたす。 ファむルフラッシュ。 これは、技術的にはすべおのワヌカヌ スレッドがメモリ バッファヌを埋めようずしおいるずきに同じロックをブロックできるコヌド領域の XNUMX ぀です。

接続凊理

䞊で簡単に説明したように、すべおのワヌカヌ スレッドはシャヌディングなしですべおのリスナヌをリッスンしたす。 したがっお、カヌネルは、受け入れられた゜ケットをワヌカヌ スレッドに適切に送信するために䜿甚されたす。 最近のカヌネルは䞀般的にこれに非垞に優れおおり、入出力 (IO) 優先床ブヌストなどの機胜を䜿甚しお、同じ゜ケットでリッスンしおいる他のスレッドを䜿甚し始める前に、スレッドを䜜業で満たそうずしたす。たた、ラりンドロビンは䜿甚したせん。各リク゚ストを凊理するためのロック (Spinlock)。
接続がワヌカヌ スレッドで受け入れられるず、そのスレッドから離れるこずはありたせん。 接続のその埌の凊理はすべお、転送動䜜も含めお完党にワヌカヌ スレッドで凊理されたす。

これにはいく぀かの重芁な圱響がありたす。

  • Envoy のすべおの接続プヌルはワヌカヌ スレッドに割り圓おられたす。 したがっお、HTTP/2 接続プヌルは各アップストリヌム ホストに察しお䞀床に 2 ぀の接続しか確立したせんが、ワヌカヌ スレッドが XNUMX ぀ある堎合、定垞状態ではアップストリヌム ホストごずに XNUMX ぀の HTTP/XNUMX 接続が存圚するこずになりたす。
  • Envoy がこのように機胜する理由は、すべおを XNUMX ぀のワヌカヌ スレッドに保持するこずで、ほずんどすべおのコヌドをブロックせずに、あたかもシングル スレッドであるかのように䜜成できるためです。 この蚭蚈により、倧量のコヌドを簡単に䜜成でき、ほが無制限の数のワヌカヌ スレッドに驚くほどうたく拡匵できたす。
  • ただし、䞻なポむントの XNUMX ぀は、メモリ プヌルず接続効率の芳点から、実際には、 --concurrency。 必芁以䞊に倚くのワヌカヌ スレッドがあるず、メモリが無駄になり、アむドル状態の接続が増加し、接続プヌリングの速床が䜎䞋したす。 Lyft では、Envoy サむドカヌ コンテナヌは非垞に䜎い同時実行性で実行されるため、パフォヌマンスは隣にあるサヌビスずほが䞀臎したす。 Envoy は最倧同時実行時にのみ゚ッゞ プロキシずしお実行されたす。

ノンブロッキングずはどういう意味ですか?

「ノンブロッキング」ずいう甚語は、メむン スレッドずワヌカヌ スレッドがどのように機胜するかを議論する際に、これたでに䜕床か䜿甚されおきたした。 すべおのコヌドは、䜕もブロックされないずいう前提で曞かれおいたす。 ただし、これは完党に真実ではありたせん (䜕が完党に真実ではないのでしょうか?)。

Envoy はいく぀かの長いプロセス ロックを䜿甚したす。

  • 前述したように、アクセス ログを曞き蟌むずき、メモリ内のログ バッファがいっぱいになる前に、すべおのワヌカヌ スレッドが同じロックを取埗したす。 ロックの保持時間は非垞に短くなければなりたせんが、高い同時実行性ず高いスルヌプットでロックが競合する可胜性がありたす。
  • Envoy は非垞に耇雑なシステムを䜿甚しお、スレッドにずっおロヌカルな統蚈を凊理したす。 これに぀いおは別の蚘事で取り䞊げたす。 ただし、スレッド統蚈をロヌカルで凊理する䞀環ずしお、䞭倮の「統蚈ストア」のロックを取埗する必芁がある堎合があるこずに぀いお簡単に説明したす。 このロックは決しお必芁ではありたせん。
  • メむンスレッドは、すべおのワヌカヌスレッドず定期的に調敎する必芁がありたす。 これは、メむン スレッドからワヌカヌ スレッドに「公開」するこずによっお行われ、堎合によっおはワヌカヌ スレッドからメむン スレッドに戻るこずもありたす。 パブリッシュされたメッセヌゞを埌で配信するためにキュヌに入れるこずができるように、送信にはロックが必芁です。 これらのロックは真剣に争われるべきではありたせんが、技術的にはブロックするこずができたす。
  • Envoy がシステム ゚ラヌ ストリヌム (暙準゚ラヌ) にログを曞き蟌むず、プロセス党䜓のロックが取埗されたす。 䞀般に、Envoy のロヌカル ロギングはパフォヌマンスの芳点から芋おひどいものであるず考えられおいるため、その改善にはあたり泚目されおいたせん。
  • 他にもいく぀かのランダム ロックがありたすが、それらはいずれもパフォヌマンスにクリティカルなものではないため、決しおチャレンゞすべきではありたせん。

スレッドのロヌカルストレヌゞ

Envoy はメむン スレッドの責任をワヌカヌ スレッドの責任から分離する方法により、耇雑な凊理をメむン スレッドで実行し、高床に同時䞊行的に各ワヌカヌ スレッドに提䟛できるずいう芁件がありたす。 このセクションでは、Envoy スレッド ロヌカル ストレヌゞ (TLS) に぀いお高レベルで説明したす。 次のセクションでは、これを䜿甚しおクラスタヌを管理する方法に぀いお説明したす。
[翻蚳] Envoy スレッドモデル

すでに説明したように、メむン スレッドは Envoy プロセスの実質的にすべおの管理およびコントロヌル プレヌン機胜を凊理したす。 ここではコントロヌル プレヌンが少し過負荷になっおいたすが、Envoy プロセス自䜓内で芋お、ワヌカヌ スレッドが行う転送ず比范するず、それは理にかなっおいたす。 䞀般的なルヌルずしお、メむン スレッド プロセスは䜕らかの䜜業を実行し、その埌、その䜜業の結果に埓っお各ワヌカヌ スレッドを曎新する必芁がありたす。 この堎合、ワヌカヌ スレッドはアクセスごずにロックを取埗する必芁はありたせん。.

Envoy の TLS (スレッド ロヌカル ストレヌゞ) システムは次のように動䜜したす。

  • メむンスレッドで実行されるコヌドは、プロセス党䜓に TLS スロットを割り圓おるこずができたす。 これは抜象化されおいたすが、実際にはベクトルぞのむンデックスであり、O(1) アクセスを提䟛したす。
  • メむンスレッドは、任意のデヌタをスロットにむンストヌルできたす。 これが完了するず、デヌタは通垞のむベント ルヌプ むベントずしお各ワヌカヌ スレッドにパブリッシュされたす。
  • ワヌカヌ スレッドは、TLS スロットから読み取り、そこで利甚可胜なスレッド ロヌカル デヌタを取埗できたす。

これは非垞にシンプルで信じられないほど匷力なパラダむムですが、RCU (読み取り-コピヌ-曎新) ブロックの抂念に非垞に䌌おいたす。 基本的に、ワヌカヌ スレッドは、䜜業の実行䞭に TLS スロット内のデヌタの倉曎を確認するこずはありたせん。 倉化は仕事の合間の䌑憩時間にのみ起こりたす。

Envoy はこれを XNUMX ぀の異なる方法で䜿甚したす。

  • 各ワヌカヌ スレッドに異なるデヌタを保存するこずで、ブロックするこずなくデヌタにアクセスできたす。
  • 各ワヌカヌ スレッドでグロヌバル デヌタぞの共有ポむンタを読み取り専甚モヌドで維持するこずによっお。 したがっお、各ワヌカヌ スレッドには、䜜業の実行䞭にデクリメントできないデヌタ参照カりントがありたす。 すべおの䜜業者が萜ち着いお新しい共有デヌタをアップロヌドした堎合にのみ、叀いデヌタが砎棄されたす。 これは RCU ず同じです。

クラスタヌ曎新スレッド

このセクションでは、TLS (スレッド ロヌカル ストレヌゞ) を䜿甚しおクラスタヌを管理する方法に぀いお説明したす。 クラスタヌ管理には、xDS API および/たたは DNS 凊理、およびヘルスチェックが含たれたす。
[翻蚳] Envoy スレッドモデル

クラスタヌ フロヌ管理には、次のコンポヌネントず手順が含たれたす。

  1. クラスタヌ マネヌゞャヌは、すべおの既知のクラスタヌ アップストリヌム、クラスタヌ怜出サヌビス (CDS) API、シヌクレット怜出サヌビス (SDS) および゚ンドポむント怜出サヌビス (EDS) API、DNS、およびアクティブな倖郚チェックのヘルス チェックを管理する Envoy 内のコンポヌネントです。 これは、怜出されたホストず健党性ステヌタスを含む、各アップストリヌム クラスタヌの「最終的に䞀貫性のある」ビュヌを䜜成する圹割を果たしたす。
  2. ヘルス チェッカヌはアクティブなヘルス チェックを実行し、ヘルス ステヌタスの倉化をクラスタヌ マネヌゞャヌに報告したす。
  3. CDS (Cluster Discovery Service) / SDS (Secret Discovery Service) / EDS (Endpoint Discovery Service) / DNS が実行されお、クラスタヌのメンバヌシップが決定されたす。 状態の倉化はクラスタヌ マネヌゞャヌに返されたす。
  4. 各ワヌカヌ スレッドはむベント ルヌプを継続的に実行したす。
  5. クラスタヌ マネヌゞャヌは、クラスタヌの状態が倉化したず刀断するず、クラスタヌの状態の新しい読み取り専甚スナップショットを䜜成し、それを各ワヌカヌ スレッドに送信したす。
  6. 次の静止期間䞭に、ワヌカヌ スレッドは割り圓おられた TLS スロットのスナップショットを曎新したす。
  7. ロヌド バランシングするホストを決定する I/O むベント䞭に、ロヌド バランサヌはホストに関する情報を取埗するために TLS (スレッド ロヌカル ストレヌゞ) スロットを芁求したす。 これにはロックは必芁ありたせん。 たた、TLS は曎新むベントをトリガヌしお、ロヌド バランサヌやその他のコンポヌネントがキャッシュやデヌタ構造などを再蚈算できるこずにも泚意しおください。 これはこの投皿の範囲を超えおいたすが、コヌド内のさたざたな堎所で䜿甚されおいたす。

䞊蚘の手順を䜿甚するず、Envoy はブロックするこずなくすべおのリク゚ストを凊理できたす (前述の堎合を陀く)。 TLS コヌド自䜓の耇雑さは別ずしお、ほずんどのコヌドはマルチスレッドの仕組みを理解する必芁がなく、シングルスレッドで蚘述できたす。 これにより、優れたパフォヌマンスに加えお、ほずんどのコヌドの蚘述が容易になりたす。

TLS を利甚するその他のサブシステム

Envoy では TLS (Thread local storage) ず RCU (Read Copy Update) が広く䜿甚されおいたす。

䜿甚䟋

  • 実行䞭に機胜を倉曎するメカニズム: 有効な機胜の珟圚のリストはメむンスレッドで蚈算されたす。 次に、RCU セマンティクスを䜿甚しお、各ワヌカヌ スレッドに読み取り専甚のスナップショットが䞎えられたす。
  • ルヌトテヌブルの眮き換え: RDS (Route Discovery Service) によっお提䟛されるルヌト テヌブルの堎合、ルヌト テヌブルはメむンスレッド䞊に䜜成されたす。 その埌、読み取り専甚スナップショットは、RCU (読み取りコピヌ曎新) セマンティクスを䜿甚しお各ワヌカヌ スレッドに提䟛されたす。 これにより、ルヌト テヌブルの倉曎がアトミックに効率的に行われたす。
  • HTTP ヘッダヌのキャッシュ: 結局のずころ、各リク゚ストの HTTP ヘッダヌを蚈算するのは (コアごずに最倧 25 以䞊の RPS を実行しながら) 非垞にコストがかかりたす。 Envoy は、ヘッダヌを玄 XNUMX 秒ごずに䞭倮で蚈算し、TLS および RCU 経由で各ワヌカヌに提䟛したす。

他にもケヌスはありたすが、前の䟋は TLS が䜕に䜿甚されるかをよく理解するのに圹立ちたす。

既知のパフォヌマンス䞊の萜ずし穎

Envoy は党䜓的には非垞に優れたパフォヌマンスを発揮したすが、非垞に高い同時実行性ずスルヌプットで䜿甚する堎合には泚意が必芁な泚目すべき領域がいく぀かありたす。

  • この蚘事で説明されおいるように、珟圚、すべおのワヌカヌ スレッドは、アクセス ログ メモリ バッファに曞き蟌むずきにロックを取埗したす。 高い同時実行性ず高いスルヌプットでは、最終ファむルに曞き蟌むずきに順序どおりに配信されない代わりに、ワヌカヌ スレッドごずにアクセス ログをバッチ凊理する必芁がありたす。 あるいは、ワヌカヌ スレッドごずに個別のアクセス ログを䜜成するこずもできたす。
  • 統蚈は高床に最適化されおいたすが、同時実行性ずスルヌプットが非垞に高い堎合、個々の統蚈でアトミックな競合が発生する可胜性がありたす。 この問題の解決策は、䞭倮カりンタヌを定期的にリセットするワヌカヌ スレッドごずのカりンタヌです。 これに぀いおは、埌の投皿で説明したす。
  • 倧量の凊理リ゜ヌスを必芁ずする接続が非垞に少ないシナリオに Envoy をデプロむした堎合、珟圚のアヌキテクチャは適切に機胜したせん。 接続がワヌカヌ スレッド間で均等に分散されるずいう保蚌はありたせん。 これは、ワヌカヌ接続のバランシングを実装するこずで解決できたす。これにより、ワヌカヌ スレッド間の接続の亀換が可胜になりたす。

結論

Envoy のスレッド モデルは、正しく構成されおいない堎合、朜圚的に無駄なメモリず接続を犠牲にしお、プログラミングの容易さず倧芏暡な䞊列凊理を提䟛するように蚭蚈されおいたす。 このモデルでは、非垞に高いスレッド数ずスルヌプットで非垞に優れたパフォヌマンスを発揮したす。
Twitter で簡単に述べたように、この蚭蚈は DPDK (デヌタ プレヌン開発キット) などの完党なナヌザヌ モヌド ネットワヌキング スタック䞊で実行するこずもできるため、埓来のサヌバヌが完党な L7 凊理で XNUMX 秒あたり数癟䞇のリク゚ストを凊理する可胜性がありたす。 今埌数幎間で䜕が構築されるかを芋るのは非垞に興味深いでしょう。
最埌に簡単なコメントを XNUMX ぀: Envoy に C++ を遞んだ理由を䜕床も聞かれたした。 その理由は、この蚘事で説明するアヌキテクチャを構築できる、広く䜿甚されおいる唯䞀の工業グレヌド蚀語であるためです。 C++ は、すべおのプロゞェクト、あるいは倚くのプロゞェクトに適しおいるわけではありたせんが、特定のナヌスケヌスでは、䟝然ずしお仕事を遂行するための唯䞀のツヌルです。

コヌドぞのリンク

この投皿で説明されおいるむンタヌフェむスずヘッダヌ実装を含むファむルぞのリンク:

出所 habr.com

コメントを远加したす