...

Apache Workerモデル:Prefork、Worker、Eventの比較

Apache Worker モデル Apache HTTP サーバーがどのようにリクエストを並列処理し、リソースを利用するかは、特に MPM の Prefork、Worker、Event によって決まります。この記事では、3つのモデルが技術的にどのように違うのか、それらがどのような影響を与えるのかを示します。 パフォーマンス どのセットアップが実際のシナリオで説得力があるのか。.

中心点

以下の要点は、3つのMPMをめぐる主な違いと決定事項の概要を説明するものである。 実践的知識.

  • プレフォークプロセスベース、高アイソレーション、高RAM要件。.
  • 労働者プロセスあたりのスレッド数、優れたスケーリング、キープアライブに敏感。.
  • イベントイベントループは接続とリクエストを切り離し、非常に効率的である。.
  • チューニング具体的には、StartServers、ThreadsPerChild、MaxRequestWorkers。.
  • HTTP/2WorkerやEventと連携して機能するが、Preforkとは連携しない。.

MPMがApacheで制御するもの

私はマルチプロセッシングモジュール(MPM)を使って、 Apacheが各リクエストにプロセスを使うかスレッドを使うか、 そしてサーバがどのように パラレリズム を提供する。Preforkはそれぞれ1つのスレッドで多数のプロセスを作成し、Workerは多数のスレッドで少数のプロセスを作成し、EventはWorkerの上に構築され、実際の処理から接続を切り離す。この選択は、メモリ、CPU使用率、レイテンシーに直接影響する。そのため、セッション、keep-alive、HTTP/2などのプロトコル、使用するモジュールなどを常に考慮に入れている。もしMPMを無視すれば、測定可能なものを手放すことになる。 パフォーマンス とボトルネックになる危険性がある。.

プレフォーク:工程断熱性と互換性

プリフォークは、それぞれの問い合わせに対する個別のプロセスに重点を置いているため、強力なサービスを提供することができる。 断熱. .1つのプロセスがクラッシュしても、他のプロセスは影響を受けません。これにより、不潔なコードや古い拡張機能に対する耐障害性が向上します。代償: 各プロセスはそれ自身のオーバーヘッドをもたらすので、並列接続あたりのRAM消費量が増えます。100の同時リクエストで100のプロセスが生成されますが、これは低負荷から中負荷までしか許容できません。私は主に、スレッドセーフでないモジュールを使わなければならないときや、レガシーなCGIスクリプトが高いメモリ使用量を必要とするときに、Preforkを使っています。 分離 が必要だ。.

ワーカー:スレッドと高い並列性

ワーカーモデルでは、個々のプロセスが複数のスレッドを実行するため、リクエストごとに必要なメモリが削減される。 減少. .このアーキテクチャーは、同じハードウェア上でより多くの同時実行を可能にし、高いアクセス数に適している。しかし、長いキープアライブ接続はスレッドを束縛し、ブロック容量を圧迫する可能性がある。クリーンでスレッドセーフなセットアップ(例えばPHP-FPMなど)では、Workerを使うことで適度なRAM使用量で非常に良いRPS値を達成できる。効率的なスレッドベースの スケーリング とkeep-aliveは適切に制御されている。.

イベント:ノンブロッキング・キープアライブ戦略

イベントはワーカーモデルをベースにしていますが、キープアライブの弱点である イベントループ. .スレッドは実際のリクエストを処理するだけで、接続の維持は別のメカニズムが担当する。これにより、スレッドに空きができ、マシンはより多くの同時セッションを低レイテンシーで処理できる。Eventは特にHTTP/2接続で威力を発揮し、スレッドを浪費することなく、多重化と長い接続を実行する。最新のセットアップでは、私はEventを 標準ベース そして、モジュールやレガシー要件がこれに抵触する場合にのみ適応する。.

MPMの表形式比較

次の表は、主な違いを一目でわかるようにまとめたものである。 評価する どのモデルが負荷とモジュールの状況に合っているか。切り替える前に、私は常にすべてのモジュールのスレッドセーフと予想される接続時間をチェックする。そして、MaxRequestWorkers、ThreadsPerChild、その他の制限を利用可能なリソースに割り当てます。この表は最初の仮定を立てるのに役立ちますが、実際の条件下での負荷テストに取って代わるものではありません。特にイベントについては、長いキープアライブフェーズとHTTP/2で測定する価値があります。 メリット が見える。

MPM プロセス/スレッド RAM消費量 信頼性 代表的な使用例
プレフォーク プロセスあたり1スレッド 高い 高い(断熱性が高い) 低/中負荷、スレッドセーフなしのモジュール、クラシックCGI
労働者 プロセスごとに複数のスレッド ミディアム ミディアム スレッドセーフ・スタック(PHP-FPMなど)による高負荷
イベント スレッド+イベントループ 低い 高い 非常に高い負荷、長い接続、HTTP/2

表から読むと、プレフォークは次のように得点した。 遮蔽, Workerは効率的に、Eventは同時接続を最大限に活用するために使う。非互換性がなければ、新しいプロジェクトにはEventを使う。Preforkは、安定したレガシースタックにはまだ役に立つ。移行して間もない人は、Workerで大きな進歩を遂げることが多い。結局、選択肢は 計量 モジュール、トラフィック・プロファイル、ハードウェアから。.

パフォーマンスの測定ベンチマークと測定基準

測定がなければ、すべてのMPM決定は 前提. .比較テストでは、高負荷時、WorkerはPreforkより1秒あたり約50 %多いリクエストを提供する。メモリの面でも明らかな違いがある:約1000の同時接続で、Preforkのセットアップは大体2-4GBのRAMで終わり、Workerは1-2GB、Eventは通常1GB以下である。私はRPSだけでなく、最初のバイトまでの時間、95/99パーセンタイル、エラー率もチェックする。アプリケーションの負荷プロファイルは非常に重要です。短くて速いリクエストは、ストリーミングやイベントと挙動が異なるからです。 ウェブソケット.

チューニング・パラメータの説明:StartServers、ThreadsPerChild、MaxRequestWorkers

私は保守的な値から始めて、希望の値に達するまでスケールアップしていく。 利用 を満たす。WorkerとEventについては、ThreadsPerChildとプロセス数を計画し、ThreadsPerChild × Processes = MaxRequestWorkersとなるようにする。負荷のピークが503エラーにつながらないように、十分なバッファがあることを確認する。StartServersの値をクリーンにすることで、コールドスタート時の不要なフォークを防ぎます。より深く掘り下げたい場合は、背景情報を スレッドプール最適化, これはApacheのセットアップに直接転送できる。.

# 例: イベント (Debian/Ubuntu)
a2dismod mpm_prefork mpm_worker
a2enmod mpm_event
systemctl apache2 を再起動する

# ワーカースレッディングを賢く使う
# /etc/apache2/mods-available/mpm_event.conf
サーバリミット 16
StartServers 4
スレッド数 50
MaxRequestWorkers 800
最大接続数 0

その後、ベンチマークでその効果を確認し、CPUが十分に働いているかどうかをチェックする。 仕事 コンテキスト・スイッチに溺れることなく。同時に、RAMのトレンド、スワップアクティビティ、オープンファイルディスクリプターをモニターしている。キューが目に見えていっぱいになったら、MaxRequestWorkersを慎重に増やしたり、キープアライブ時間を短くしたりする。すべてが順調に動いているなら、設定をバックアップし、その内容を文書化する。 限界値.

Keep-Alive、HTTP/2、スレッドコンテンション

Keep-AliveはTCPハンドシェイクを減らしますが、スレッドを束縛する可能性があります - 特にスレッドに直接コネクションを置くWorker MPMでは。イベントは、イベントループを介して接続を確立することで、まさにこの効果を解決します。 ほどける そしてスレッドはアクティブな作業だけに使う。そうしないと多重化が遅くなるからだ。実際には、キューの長さを監視して、「スレッドの滞留」が目立つかどうかをチェックしたい。これについては スレッド・コンテンション 私は、より詳細な分析に使用している。.

また、KeepAliveTimeoutをアプリケーションに合わせてカスタマイズし、非アクティブな接続が次のような影響を与えないようにしている。 定員 はバインドしません。理想的な設定は、API、クラシックなLAMPページ、多くのアセットを持つHTTP/2ベースのフロントエンドによって異なる。アイドル時間が多い場合は、タイムアウトを下げ、MaxRequestWorkersを少し増やします。短いリクエストが多いと予想される場合は、TCPオーバーヘッドを節約するためにKeep-Aliveを控えめにしている。待ち時間が発生する場合は、イベントに切り替えるか、追加の インスタンス に。

実践的なシナリオと適切なモデルの選択

レガシー・アプリでリスクの高いモジュールにはPreforkを使い、高い利点を享受している。 遮蔽. .多くの同時接続がある最新のPHP-FPMアーキテクチャでは、Workerはすでに非常に良い結果を出している。共有ホスティングやコードステータスが不明確なホスティングではPreforkの方が安全ですが、VPSや専用ハードウェアでは通常Eventを好みます。Apacheの代替を検討している場合は、コンパクトな ウェブサーバーの比較 NginxとLiteSpeedについては、状況に応じて追加の判定補助をチェックしている。.

このイベントは、スレッドがアイドル状態でないため、トラフィックのピーク時にバースト性を発揮する。 貫く. .CPUを多用するアプリでは、マシンをオーバーブッキングしないようにMaxRequestWorkersを制限している。RAMが不足している場合は、Preforkを追放してWorkers/Eventを優先する。マルチテナント環境では、コンテナやcgroupでサービスを分離し、Worker/Eventが潜在能力を発揮できるようにする。最終的には、自分のスタックでどのモデルが最も低いかを測定する。 レイテンシー を供給している。

Ubuntu/Debianでの設定の実際

私はMPMを特別にアクティブにしたり、非アクティブにしたりして、その効果をテストし、ロールバックオプションを維持している。 レディ. .Debian/Ubuntuでは、既知のコマンドを使い、ステータス出力をチェックする。その後、mpm_*.confファイルを微調整し、バージョンごとの変更をログに記録する。本番前に、デッドロックやメモリのボトルネックを早期に認識するために、負荷のピークをシミュレートする。エラーカウンターとパーセンタイルが正しくなってから、私は 価値観 生産中.

# プレフォークをオンにする
a2dismod mpm_worker mpm_event
a2enmod mpm_prefork
systemctl で apache2 を再起動

# Worker をオンにする
a2dismod mpm_prefork mpm_event
a2enmod mpm_worker
systemctl apache2 を再起動する

# スイッチオンイベント
a2dismod mpm_prefork mpm_worker
a2enmod mpm_event
systemctl apache2 を再起動する

# モニタリング
apachectl ステータス
htop
journalctl -u apache2 -f

私はスレッドセキュリティの問題を素早く特定するために、エラーログを並行して監視している。 探す. .HTTP/2では、プロトコルが正しくネゴシエートされているか、TLSの設定が正しいかをチェックする。顕著なレイテンシーがある場合は、prefork/worker/eventを交互に比較し、RAMの開発に目を光らせる。バランスが悪ければ、KeepAliveやスレッド数、制限を調整します。こうすることで、私は オーバーブッキング.

スレッドセーフとモジュールの互換性

PreforkからWorker/Eventに切り替える前の最も重要な事前チェックは、以下の通りである。 スレッドの安全性 を使う。クラシック: mod_php は歴史的に Prefork と密接に結びついています。最近のスタックでは、Apache 自体がスレッドベースでスケールできるように、proxy_fcgi 経由の PHP-FPM を代わりに使っています。フィルタモジュールや認証モジュール、自作モジュールや統合モジュール(画像処理など)も「スレッドセーフ」でなければなりません。私はロードされたモジュールをチェックし、リリースノートを分析し、負荷がかかった状態でクラッシュとレースコンディションのテストを実施します。以下はHTTP/2に適用されます:Preforkでは、それは事実上オプションではありません。 前提条件, 多重化と優先順位付けが機能するように。.

容量計画:ストレージ予算を現実的に計算する

私はMaxRequestWorkersの寸法を „感覚で “決めるのではなく、測定可能なプロセスとスレッドサイズに基づいて決める。手順

  • テストロードを実行し、Apacheプロセスごとの常駐セットサイズ(RSS)を測定する。.
  • ワーカー/イベントのためのスレッドごとの追加オーバーヘッドを考慮する。.
  • カーネル、ページキャッシュ、TLSセッションキャッシュ、ログバッファ、アップストリーム用のバッファをスケジュールする。.
# プロセスサイズを見積もる (例)
ps -ylC apache2 --sort:rss | awk '{sum+=$8}.END {print "RSS (kB) total:",sum}'
ps -L -p  -o pid,tid,psr,stat,rss,cmd
pmap -x  | tail -n 1 # プロセスごとの合計

計算例:イベント・プロセスは25MBを占有し、スレッドは平均1MBを必要とする。16個のプロセスと50個のスレッドを使用すると、16 × 25 MB + 800 × 1 MB ≒ 1.2 GBとなります。私はMaxRequestWorkers = 800に設定し、30-40の% RAMを空けておき、計測後にスケールアップしている。Preforkを使用する場合は、「プロセスサイズ×MaxRequestWorkers」を計算するだけでよい。 保守的.

オペレーティングシステムの制限、バックログ、記述子

Apacheは、基盤となるプラットフォームと同じ速さしか出せない。私は定期的に3つの点をチェックしている:

  • ファイル記述子: スレッド/プロセスがソケット、ファイル、パイプを開く。systemd経由でLimitNOFILEを増やし、転送を確認する。.
  • バックログを受け入れる: 接続バーストに対しては、ListenBacklogを拡大し、適切なカーネルバックログを提供する。.
  • ソケット/タイムアウトのチューニング: RequestReadTimeout、Timeout、KeepAliveTimeoutは、特に „遅いクライアント “を軽減するために設定します。.
# systemd オーバーライド
systemctl edit apache2
[サービス]
LimitNOFILE=65536

# カーネルパラメータ(一時)
sysctl -w net.core.somaxconn=4096

# Apache: バックログとタイムアウト
リスン 0.0.0.0:443
ListenBacklog 1024
タイムアウト60
RequestReadTimeout header=10-20,MinRate=1 body=10,MinRate=500
KeepAliveTimeout 5
MaxKeepAliveRequests 100

私はタイムアウトを少し厳しくして、エラー率を監視する方が好きだ。もし正当な長時間のアップロードが予想される場合は、次のように値を調整する。 バーチャルホスト で。

グレースフル・リロード、デプロイメント、コンテナ

運用上、私は既存のコネクションを壊さずにリロードすることを好む。. apachectl -k graceful や systemctl reload は設定をリロードしますが、実行中のリクエストはきれいに期限切れになります。コンテナ環境では、ServerLimit/ThreadsPerChild を小さくして、ポッドが スタート で終了します。CPU時間やRAMに上限がある場合、MaxRequestWorkersもそれに応じて低くしなければならない。.

プロキシ/アップストリームのセットアップを正しく行う

多くのApacheインスタンスはTLSを終了し、PHP-FPM、アプリサーバー、またはマイクロサービスにプロキシする。私はフロントエンドのキャパシティ (MaxRequestWorkers) をアップストリームプールにリンクしています:PHP-FPMの場合、pm.max_childrenとpm.max_requestsが上限となる。この比率は、Apache がアップストリームの処理能力を大幅に超える同時リクエストを受け付けないように保つ。 タイムアウト. .proxy_fcgiとproxy_httpに明示的にタイムアウトを設定し、keep-aliveがアップストリームにとって有用なのか、それともリソースを圧迫するだけなのかをチェックする。.

スコアボードによるモニタリングと診断

mod_statusの出力は、選択したMPMがどの程度機能しているかを明らかにする。私は以下のステータスの割合に注目している: 読書 (受信ヘッダー)、, 送信 (答えは送信される)、, キープアライブ (労働を伴わないオープン接続)、, 待機中 (無料)。の割合が高い。 キープアライブ Workerはバインドされたスレッドを示す。パーマネント 読書 クライアントが遅いか、不正確である可能性がある。 リクエスト読み取りタイムアウト-価値観である。多くの クロージング/ロギング-ピーク負荷時の状態は、スレッドプールが小さすぎるか、ロギングのI/Oボトルネックを示している。.

安全性と堅牢性:Slowloris & Co.

Event-MPM、緊密なKeepAliveTimeouts、RequestReadTimeoutの組み合わせは、「Slowloris」型の攻撃パターンに対抗するのに役立つ。Preforkはプロセスの分離によってモジュールのクラッシュを防ぐが、RAMの影響を受けやすい。疲労困憊 多くのコネクションを持つ。ウェブサーバーレベルでの制限と上流のWAF/レート制限を組み合わせることで、Apacheがそもそも何百万もの半分しか開いていないセッションに直面しないようにしています。攻撃は分布の尾を膨らませるので、95/99パーセンタイルまでログを分析する。.

ディストリビューションのデフォルトと典型的な障害

イベントは現在、多くのDebian/Ubuntuで標準となっている。とはいえ、デフォルト値は保守的なことが多い(ThreadsPerChild 25-50など)。私は、測定後にこれらの値を増やすようにしている。よくあるエラー

  • MaxRequestWorkersが利用可能なファイル記述子よりも大きい。.
  • ApacheとPHP-FPM/Appサーバ間の制限の非同期。.
  • KeepAliveTimeoutが高すぎるため、多数のモバイルクライアントを使用する作業員がいる。.
  • ログI/Oのバッファ不足 - ブロックローテーションジョブ 短期.

私は目標値(CPU使用率、RAM、RPS、P95)を文書化し、作業コンフィギュレーションのバージョンを保存する。その時初めて ロールアウト.

簡単にまとめると

プレフォークが好調 断熱 はレガシースタックに適しているが、多くのメモリを消費する。Workerは、プロセスごとにスレッドを持つ優れたセンターを提供し、Keep-Aliveが不必要にバインドしない限り、きれいにスケールする。Eventは接続と処理を分離し、利用率を高め、HTTP/2と長いセッションで強みを発揮する。私は体系的に測定し、リミットを調整し、コード、トラフィックのプロファイル、ハードウェアに合ったMPMを選択します。クリーンなチューニング、明確な測定ターゲット、集中的なモニタリングにより、Apacheは3つのモデルそれぞれから最大限の力を引き出すことができます。 パフォーマンス アウト。

現在の記事