apeescape2.com
  • メイン
  • 収益と成長
  • 財務プロセス
  • Uiデザイン
  • ライフスタイル
バックエンド

マルチプロセッシングネットワークサーバーモデルのガイド

高性能ネットワーキングコードを何年も書いている人として(私の博士論文は、 マルチコアシステムに適合した分散アプリケーション用のキャッシュサーバー )、ネットワークサーバーモデルの基本についての説明を完全に見逃したり省略したりする、このテーマに関する多くのチュートリアルを目にします。したがって、この記事は、ネットワークサーバーモデルの概要と比較に役立つことを目的としており、高性能ネットワークコードの記述から謎を取り除くことを目的としています。

どのネットワークサーバーモデルを選択する必要がありますか

この記事は、「システムプログラマー」を対象としています。 バックエンド開発者 ネットワークサーバーコードを実装して、アプリケーションの低レベルの詳細を処理する人。これは通常、 C ++ または C ただし、最近のほとんどの言語とフレームワークは、さまざまなレベルの効率で、まともな低レベルの機能を提供します。



コアを追加することでCPUのスケーリングが容易になるため、これらのコアを可能な限り使用するようにソフトウェアを適応させるのは当然であるということを常識としています。したがって、問題は、複数のCPUで並行して実行できるスレッド(またはプロセス)間でソフトウェアをどのように分割するかということです。

また、読者は、「同時実行性」は基本的に「マルチタスク」、つまり同時にアクティブなコードの複数のインスタンス(同じコードであろうと異なるものであろうと関係ありません)を意味することを知っていると思います。並行性は単一のCPUで実現でき、現代以前は通常はそうでした。具体的には、同時実行性は、単一のCPU上の複数のプロセスまたはスレッドをすばやく切り替えることで実現できます。これは、実際にはそうではなかったものの、ユーザーがアプリケーションが同時に実行されていると認識できるように、古いシングルCPUシステムが同時に多くのアプリケーションを実行することに成功した方法です。一方、並列処理とは、具体的には、コードが文字通り、複数のCPUまたはCPUコアによって同時に実行されていることを意味します。

初心者向けの機械学習チュートリアル

アプリケーションを(複数のプロセスまたはスレッドに)分割する

この説明の目的上、スレッドまたは完全なプロセスについて話している場合は、ほとんど関係ありません。最新のオペレーティングシステム(Windowsを除く)は、プロセスをスレッドとほぼ同じくらい軽量に扱います(または、場合によっては、スレッドはプロセスと同じくらい重い機能を備えています)。現在、プロセスとスレッドの主な違いは、プロセス間またはスレッド間の通信とデータ共有の機能にあります。プロセスとスレッドの区別が重要な場合は、適切なメモを作成します。それ以外の場合は、このセクションの「スレッド」と「プロセス」という言葉は同じ意味であると考えてください。

一般的なネットワークアプリケーションタスクとネットワークサーバーモデル

この記事では、特に次の3つのタスクを実装するネットワークサーバーコードについて説明します。

  • タスク1: ネットワーク接続の確立(および切断)
  • タスク#2: ネットワーク通信(IO)
  • タスク#3: 便利な仕事;つまり、ペイロードまたはアプリケーションが存在する理由

これらのタスクをプロセス間で分割するための一般的なネットワークサーバーモデルがいくつかあります。 すなわち:

  • MP: マルチプロセス
  • 速度: 単一プロセス、イベント駆動型
  • それ: 段階的なイベント駆動型アーキテクチャ
  • AMPED: 非対称マルチプロセスイベント駆動型
  • 症状: 対称型マルチプロセスイベント駆動型

これらは、学術コミュニティで使用されているネットワークサーバーモデル名であり、少なくとも一部の「野生の」同義語を見つけたことを覚えています。 (もちろん、名前自体はそれほど重要ではありません。本当の価値は、コードで何が起こっているかを推論する方法にあります。)

これらの各ネットワークサーバーモデルについては、次のセクションで詳しく説明します。

マルチプロセス(MP)モデル

MPネットワークサーバーモデルは、特にマルチスレッドについて学ぶときに、誰もが最初に学んだモデルです。 MPモデルには、接続を受け入れる「マスター」プロセスがあります(タスク#1)。接続が確立されると、マスタープロセスは新しいプロセスを作成し、接続ソケットをそれに渡します。したがって、接続ごとに1つのプロセスがあります。この新しいプロセスは通常、単純で順次的なロックステップの方法で接続を処理します。接続から何かを読み取り(タスク#2)、計算を実行し(タスク#3)、書き込みを行います(タスク#2)。再び)。

MPモデルは 非常に 実装は簡単で、プロセスの総数がかなり少ない限り、実際には非常にうまく機能します。どれくらい低いですか?答えは、タスク#2と#3が何を伴うかによって異なります。経験則として、プロセスまたはスレッドの数がCPUコアの数の約2倍を超えてはならないとしましょう。同時にアクティブなプロセスが多すぎると、オペレーティングシステムはスラッシングに多くの時間を費やす傾向があり(つまり、使用可能なCPUコアでプロセスまたはスレッドをジャグリングする)、そのようなアプリケーションは通常、CPUのほぼすべてを消費することになります。 「sys」(またはカーネル)コードでの時間。実際に役立つ作業はほとんど行いません。

長所: 実装は非常に簡単で、接続数が少ない限り非常にうまく機能します。

短所: プロセスの数が多くなりすぎると、オペレーティングシステムに過負荷がかかる傾向があり、ペイロード(計算)フェーズが終了するまでネットワークIOが待機するため、遅延ジッターが発生する可能性があります。

シングルプロセスイベントドリブン(SPED)モデル

SPEDネットワークサーバーモデルは、Nginxなどの比較的最近の有名なネットワークサーバーアプリケーションによって有名になりました。基本的に、3つのタスクすべてを同じプロセスで実行し、それらの間で多重化します。効率的にするには、次のようなかなり高度なカーネル機能が必要です。 epoll そして kqueue 。このモデルでは、コードは着信接続とデータの「イベント」によって駆動され、次のような「イベントループ」を実装します。

  • 新しいネットワークの「イベント」(新しい接続や受信データなど)があるかどうかをオペレーティングシステムに確認します
  • 利用可能な新しい接続がある場合は、それらを確立します(タスク#1)
  • 利用可能なデータがある場合は、それを読んで(タスク#2)、それに基づいて行動します(タスク#3)
  • サーバーが終了するまで繰り返します

これらはすべて単一のプロセスで実行され、通常はMPモデルのパフォーマンスを低下させるプロセス間のコンテキスト切り替えを完全に回避するため、非常に効率的に実行できます。ここでの唯一のコンテキストスイッチはシステムコールからのものであり、それらは、いくつかのイベントが関連付けられている特定の接続にのみ作用することによって最小限に抑えられます。このモデルは、ペイロード作業(タスク#3)が過度に複雑でなく、リソースを大量に消費しない限り、数万の接続を同時に処理できます。

ただし、このアプローチには2つの大きな欠点があります。

  1. 3つのタスクはすべて、1回のループ反復で順次実行されるため、ペイロード作業(タスク#3)は他のすべてと同期して実行されます。つまり、クライアントが受信したデータへの応答の計算に時間がかかる場合は、他のすべてのタスクが実行されます。これが行われている間は停止し、レイテンシに大きな変動が生じる可能性があります。
  2. 単一のCPUコアのみが使用されます。これには、オペレーティングシステムに必要なコンテキストスイッチの数を完全に制限するという利点があり、全体的なパフォーマンスが向上しますが、他の利用可能なCPUコアがまったく何もしないという重大な欠点があります。

これらの理由から、より高度なモデルが必要になります。

長所: オペレーティングシステムでパフォーマンスが高く、簡単である可能性があります(つまり、OSの介入が最小限で済みます)。必要なCPUコアは1つだけです。

短所: (使用可能な数に関係なく)単一のCPUのみを使用します。ペイロードの動作が均一でない場合、応答の遅延が不均一になります。

段階的イベント駆動型アーキテクチャ(SEDA)モデル

SEDAネットワークサーバーモデルは少し複雑です。複雑なイベント駆動型アプリケーションを、キューで接続された一連のステージに分解します。ただし、注意深く実装しないと、MPの場合と同じ問題が発生する可能性があります。それはこのように動作します:

  • ペイロード作業(タスク#3)は、可能な限り多くのステージまたはモジュールに分割されます。各モジュールは、独自の個別のプロセスに存在する単一の特定の機能(「マイクロサービス」または「マイクロカーネル」を考えてください)を実装し、これらのモジュールはメッセージキューを介して相互に通信します。このアーキテクチャは、ノードのグラフとして表すことができます。ここで、すべてのノードはプロセスであり、エッジはメッセージキューです。
  • 単一のプロセスがタスク#1(通常はSPEDモデルに従う)を実行し、特定のエントリポイントノードへの新しい接続をオフロードします。これらのノードは、計算のためにデータを他のノードに渡す純粋なネットワークノード(タスク#2)にすることも、ペイロード処理(タスク#3)を実装することもできます。すべてのノードがそれ自体で応答できるため、通常、「マスター」プロセス(たとえば、応答を収集して集約し、接続を介してそれらを送り返すプロセス)はありません。

理論的には、このモデルは任意に複雑になる可能性があり、ノードグラフにはループ、他の同様のアプリケーションへの接続、またはノードが実際にリモートシステムで実行されている場所が含まれる可能性があります。ただし、実際には、明確に定義されたメッセージと効率的なキューがあっても、システム全体の動作について考えたり、推論したりするのは扱いにくい場合があります。各ノードで実行される作業が短い場合、メッセージパッシングオーバーヘッドは、SPEDモデルと比較してこのモデルのパフォーマンスを破壊する可能性があります。このモデルの効率はSPEDモデルの効率よりも大幅に低いため、通常、ペイロード作業が複雑で時間がかかる状況で使用されます。

長所: 究極のソフトウェアアーキテクトの夢:すべてがきちんとした独立したモジュールに分離されています。

短所: モジュールの数だけで複雑さが増す可能性があり、メッセージキューイングは直接メモリ共有よりもはるかに低速です。

非対称マルチプロセスイベント駆動型(AMPED)モデル

AMPEDネットワークサーバーは、SEDAの使い慣れた、モデル化が容易なバージョンです。異なるモジュールやプロセスはそれほど多くなく、メッセージキューもそれほど多くありません。仕組みは次のとおりです。

  • タスク#1と#2を、単一の「マスター」プロセスでSPEDスタイルで実装します。これは、ネットワークIOを実行する唯一のプロセスです。
  • タスク#3を、キュー(プロセスごとに1つのキュー)でマスタープロセスに接続された、別の「ワーカー」プロセス(複数のインスタンスで開始される可能性があります)に実装します。
  • 「マスター」プロセスでデータを受信したら、十分に活用されていない(またはアイドル状態の)ワーカープロセスを見つけて、そのデータをメッセージキューに渡します。マスタープロセスは、応答の準備ができるとプロセスからメッセージを受け取り、その時点で応答を接続に渡します。

ここで重要なことは、ペイロード作業が、接続の数に関係なく、固定された(通常は構成可能な)数のプロセスで実行されることです。ここでの利点は、ペイロードが任意に複雑になる可能性があり、ネットワークIOに影響を与えないことです(これは遅延に適しています)。ネットワークIOを実行しているプロセスは1つだけなので、セキュリティが向上する可能性もあります。

長所: ネットワークIOとペイロード作業の非常にクリーンな分離。

短所: プロセス間でデータをやり取りするためにメッセージキューを利用します。これは、プロトコルの性質によっては、ボトルネックになる可能性があります。

対称型マルチプロセスイベント駆動型(SYMPED)モデル

SYMPEDネットワークサーバーモデルは、多くの点でネットワークサーバーモデルの「聖杯」です。これは、独立したSPED「ワーカー」プロセスの複数のインスタンスがあるようなものだからです。これは、単一のプロセスがループ内の接続を受け入れ、それらをワーカープロセスに渡すことによって実装されます。各プロセスには、SPEDのようなイベントループがあります。これはいくつかの非常に好ましい結果をもたらします:

  • CPUは、生成されたプロセスの正確な数だけロードされ、すべての時点でネットワークIOまたはペイロード処理を実行します。 CPU使用率をさらにエスカレートする方法はありません。
  • 接続が独立している場合(HTTPなど)、ワーカープロセス間にプロセス間通信はありません。

実際、これはNginxの新しいバージョンが行うことです。それらは少数のワーカープロセスを生成し、それぞれがイベントループを実行します。さらに改善するために、ほとんどのオペレーティングシステムは、複数のプロセスがTCPポートで着信接続を個別にリッスンできる機能を提供し、ネットワーク接続の操作専用の特定のプロセスを不要にします。作業中のアプリケーションをこのように実装できる場合は、そうすることをお勧めします。

長所: 制御可能な数のSPEDのようなループを備えた、厳密なCPU使用率の上限。

短所: 各プロセスにはSPEDのようなループがあるため、ペイロードの作業が不均一な場合、通常のSPEDモデルと同様に、レイテンシーが再び変動する可能性があります。

いくつかの低レベルのトリック

アプリケーションに最適なアーキテクチャモデルを選択することに加えて、ネットワークコードのパフォーマンスをさらに向上させるために使用できるいくつかの低レベルのトリックがあります。より効果的なもののいくつかの簡単なリストは次のとおりです。

  1. 動的なメモリ割り当ては避けてください。 説明として、人気のあるメモリアロケータのコードを見てください。これらは複雑なデータ構造、ミューテックスを使用しており、コードが非常に多く含まれています( jemalloc たとえば、約450 KiBのCコードです!)。上記のモデルのほとんどは、完全に静的な(または事前に割り当てられた)ネットワークや、必要な場合にのみスレッド間の所有権を変更するバッファーを使用して実装できます。
  2. OSが提供できる最大値を使用してください。 ほとんどのオペレーティングシステムでは、複数のプロセスが1つのソケットでリッスンでき、ソケットで最初のバイト(または最初の完全な要求)が受信されるまで接続が受け入れられない機能が実装されています。使用する ファイルを送信() できれば。
  3. 使用しているネットワークプロトコルを理解してください! たとえば、通常は無効にするのが理にかなっています Nagleのアルゴリズム 、および(再)接続率が高い場合は、長引くことを無効にすることは理にかなっています。 TCP輻輳制御アルゴリズムについて学び、新しいアルゴリズムの1つを試すことが理にかなっているかどうかを確認します。

将来のブログ投稿で、これらのほか、採用する追加のテクニックやトリックについて詳しく説明する可能性があります。しかし今のところ、これは、高性能ネットワークコードを作成するためのアーキテクチャの選択、およびそれらの相対的な長所と短所に関して、有用で有益な基盤を提供することを願っています。

エンタープライズセールスエグゼクティブ-ダラス/ヒューストン

その他

エンタープライズセールスエグゼクティブ-ダラス/ヒューストン
トップピッチデッキの間違い

トップピッチデッキの間違い

投資家と資金調達

人気の投稿
プレトタイプを使用したビジネスケースのサポート
プレトタイプを使用したビジネスケースのサポート
タイムロックウォレット:イーサリアムスマートコントラクトの概要
タイムロックウォレット:イーサリアムスマートコントラクトの概要
女性エンジニアを擁護する
女性エンジニアを擁護する
製品アナリスト、成長マーケティング
製品アナリスト、成長マーケティング
意味のあるデザインと楽しいUXの芸術
意味のあるデザインと楽しいUXの芸術
 
Namekoを使用したPythonマイクロサービスの概要
Namekoを使用したPythonマイクロサービスの概要
完全なユーザー認証とアクセス制御– Laravel Passportチュートリアル、Pt。 1
完全なユーザー認証とアクセス制御– Laravel Passportチュートリアル、Pt。 1
Apache Luceneとのダイアログの全文検索:チュートリアル
Apache Luceneとのダイアログの全文検索:チュートリアル
安全でないモノのインターネット(IoT)を作成していますか?セキュリティの課題と懸念
安全でないモノのインターネット(IoT)を作成していますか?セキュリティの課題と懸念
ミラーAPIチュートリアル:Web開発者向けGoogle Glass
ミラーAPIチュートリアル:Web開発者向けGoogle Glass
人気の投稿
  • 装飾的なパターンは一般的に関連付けられています
  • 会社のCFOは何をしますか
  • gulp vs grunt vs webpack
  • トライデータ構造とは
  • ゲシュタルトの原則のうち、私たちがグループでオブジェクトを知覚する傾向があると述べているのはどれですか?
  • アジャイルコーチになる方法
カテゴリー
エンジニアリング管理 ツールとチュートリアル モバイルデザイン バックエンド データサイエンスとデータベース トレンド プロセスとツール Uiデザイン デザイナーライフ 人とチーム

© 2021 | 全著作権所有

apeescape2.com