ファイルディスクリプタの大群の問題 - ソリューション

[]問題が発生しました

    Linuxのファイルディスクリプタを単一のプロセスがあるオリジナルの手のサーバプログラムは、最近2つの主な理由のために、マルチプロセス版にそれを書き直したいです:

  1. 中にピーク時の同時ネットワークサービス要求はビットずっとプログラムの現在のバージョンは非常に大規模な、単一のプロセスである:治療の1サイクルだけは(イベントがepoll_waitを持っている)単一のイベントを処理するために、いくつかの不幸なイベントがネットワーク処理によってキューに入れられた後にソケットのfdを作りますタイムリーな(心配しているいくつかのソケットクライアントなど焦りタイムアウトなど);
  2. 我々は、マルチCPUサーバーの利点を活用したいです。
 
    しかし、次のように奥行き書き換え作業で、彼らが最初に想定されている私のプログラムの冒頭で、「雷の群れ」の問題が発生します。
  1. メインプロセスは、第1のポート、listen_fd =ソケット(...)を聞きます。
  2. epoll、epoll_fd = epoll_create(...)を作成します。
  3. その後、それぞれの子プロセスはイベントがepoll_wait、受け入れる新しい(...)、イベント処理を待つサイクルを入力する)(フォークを開始しました。
 
    そして彼は「大群」現象に遭遇しました:listen_fd新しい(受け入れる)がオーバー要求したとき、オペレーティング システムは、 これらのプロセスはイベントがepoll_wait(あるためlisten_fdで)(すべての子プロセスを目覚めさせるだろう、 オペレーティングシステムが 受け入れる責任が誰であるかを判断する方法がありません、単に完全に全て)......目を覚ますが、最終的にのみ成功した方法が受け入れる、他のプロセスが失敗を受け入れます。IT外国人の友人は、すべての子どもたちがとてもサンダ群れ(ショック・グループ)と呼ばれ、「目覚め」されていると思います。
    比喩、通りは4つのサービス小さな窓がありますマクドナルドのレストランでは、それぞれがウェイターを持って、そこにあります。新しいゲストは、フロントドアに来て、「ようこそ!」レ​​ストランのドア自動誘導ドアベルが鳴った(ネットワークイベントでそれらをキャッチする基礎となるオペレーティング・システムの同等)、その後、4人の参加者は、オペレーティング・システムのウェイクの同等(ルックアップされますすべてのサービスプロセスが)ここで自分の過去のサービスウィンドウゲストを迎えるためにしたいと思います。ゲストは最終的に窓に向かって移動する場所を他の3つの窓のスタッフだけで「失望ため息、」(もうすぐ(受け入れるように同等のため息辞任)EAGAINエラーを返す)しながら、しかし、結果は埋め続け、その後、想像することができます行く自分自身のことを行います。
    この「大群」現象のように必然的につながる 資源 、廃棄物の良い解決策を持っている木材を?
 
[する方法を見つけます]
    Nに優れ、さまざまな読書、オンライン投稿やページをマルチリード のオープンソース プログラムの ソースコードを 以下のように、彼らの実験的試験と組み合わせは、要約されています:
  1.  ショックグループが発生したときに実際には、いないすべての子プロセスが目覚めされますが、一部の子供が目を覚まします。プロセスはまだ受け入れるだけ成功して起こされた。しかし、他の人が失敗しています。
  2. すべての複数のプロセスがlighttpdのとを含む問題の悩まさ基、おびえいるLinuxファイルディスクリプタ機構サーバプログラムに基づいて、nginxの  、および他の手順の種々のプログラムが同じでない近づきます。
  3. lighttpdのためのソリューション:ショックグループを無視しますする特定の対策があり、ウォッチャー/労働者モードを使用して最適化キャプチャ)(受け入れ、フォーク()とepoll_create()位置(したがって、それぞれの子プロセス自体はepoll_createこと()とイベントがepoll_wait())は、エラーなどを無視するように投げます。新しい子プロセスを受け入れるのlighttpd以上がある場合、この方法のように、起こされます。
  4. nginxののソリューション:避けショックグループ具体的な対策は、アプリケーションロックの前に行くためにグローバルミューテックス、イベントがepoll_waitにおけるそれぞれの子プロセスを()を使用して、少ない待ち時間より取得し続けることを処理するアプリケーション、およびロードバランシングの設定などがアルゴリズムをするとき、サブタスク処理(総量の7/8が設定量に達し、各タスク処理の量を等しくする)ロックを試したことはありません。
  5. 優れた国内の商用MTAサーバプログラム(名開示されない):モデル、同じ状態の各スレッドをスレッドリーダー/フォロワー、要求に応答するターンのリーダーを取ります。
  6. nginxのと二つのオプションを比較するlighttpdのは、前者は、実装が容易シンプルなロジックですが、その方法を議論の余地(このテストは、オーバーヘッドのhttpの一部ではないことをユーザーがいるのコストに起因する資源のウェイクアッププロセスの不要な廃棄物のの一部://www.iteye 。COM /トピック/ 382 107)。後者は、より複雑なロジック、また、より多くのプログラムの支出をもたらしたミューテックスとロードバランシングカウントポイントの導入です。同時に、これらの2つのプログラムが問題を解決するので、ちょうど大きなオーバーヘッドなしで他の計算のオーバーヘッドの一部であり、データの比較を。
  7. 牙建は、Linuxの2.6.x後に循環カーネル、あなたは問題が群れ、紙アドレス雷が鳴っ受け入れる解決してきた  http://static.usenix.org/event/usenix2000/freenix/full_papers/molloy/molloy.pdfを  。
  8. しかし、実際の後、)改善本論文で言及し、ほとんどのプログラムはフォークでマルチプロセス・サーバー(あるため、大群の問題実際の生産環境を解決するために失敗した後、イベントがepoll_wait(listen_fd、...このような)イベント新しいlisten_fdプロセスが、彼らはまだ目覚めされる要求を受け入れています。主にカーネルレベルでの改善された論文は、)(アトミック操作を受け付け作る複数のプロセスが呼び出されないようにします。
 
[採用]プログラム
    :複数の考慮事項は、基準の最終的な選択は、次のようにマルチプロセスファイルディスクリプタプログラムIの必要性の部分は、コアプロセスであることに気づき、ウォッチャー/労働者モデルをlighttpdの
  1. メイン処理は、第一ポート、listen_fd =ソケットをリスン(...);,のsetsockopt(listen_fd、SOL_SOCKET、SO_REUSEADDR、...)、(listen_fd)をsetnonblocking、聞く(listen_fd、...)。
  2. フォーク()の開始後、子プロセスの最大数(CPUコアサーバの実際の数に応じて構成された提案)、ウォッチャー、唯一の子のメンテナンスや全体的な信号処理作業になるため、メインプロセスに到達します。
  3. それぞれの新しいプロセス(ワーカー)は、全て、epoll_fd = epoll_create独自に作成するのepoll(...);、その後、listen_fd追加epoll_fd、その後、一般的な循環へ、イベントがepoll_wait()をリッスンし、イベントを処理します。彼らは注意する必要があり、epoll_create()この段階は、後フォーク()でなければなりません
  4. 大胆なアイデア(未実現):使用して、各ワーカー・プロセスマルチスレッド大きなソケットFDサイクルの処理速度を向上させるためのアプローチは、行うために必要なミューテックス同期を追加することを検討するだけでなく、良いよりも、この子より害が(+スレッドプロセスが頻繁な切り替えをもたらしたことを心配します追加のオペレーティングシステムのオーバーヘッド)、このステップが実施され、テストされますが、このロジックのようなnginxのソースコードのルックスを見ていません。
 
[概要]
   現在、Linuxサーバプログラムの開発を通じて(アプリケーションサーバのゲームサーバー/ WebServerのサーバ/ balabalaすべてのタイプかどうか)、ファイルディスクリプタは、人気、フライドチキンの一つとして記述することができます。それは不思議nginxの/ Lighttpdの力と他のプログラムがそれのように好きではない、単一のプロセスのイベント処理能力は/選択の世論調査よりもはるかに強いてきました、確かに良いことです。
    しかし、すべての後、唯一のプロセスは、その後、複数のCPUサーバハンギングそれはの追求のために罪である 高い機械稼働率 要求に応じて、より短い処理時間 、またはマルチプロセスのepollを思い付く投げます。オンラインサーバー上の新しいプログラムのパフォーマンスは、効果が幸せな、本当に良いです。

おすすめ

転載: www.cnblogs.com/redman274/p/12200735.html