🤖

シングルプロセスのNginxがマルチプロセスのApacheより高速という意味について考えてみた

2023/06/25に公開

ISUCON13が秋に開催されることもあり、Node.jsのパフォーマンス計測に興味がわいていろいろ調べています。「C10K問題」を知る中で、ふと疑問に思ったことを自分なりに理解して整理しました。

素朴な疑問

マルチプロセスのApacheよりシングルプロセスのNginxの方が高速かつ大規模サービスに向いているってよく言われているけど、なんでだろう?

ApacheとNginxの比較

  • Apache HTTP Server, Tomcat, Spring Frameworkなど(Java)
    • マルチプロセス・マルチスレッド・ブロッキングI/O
    • リクエストごとにプロセスが立ち上がることで処理を並列化、スレッドごとにメモリ消費
  • Nginx, Node.js, Expressなど(JavaScript)
    • シングルプロセス・シングルスレッド・ノンブロッキングI/O
    • リクエストを並列処理することで高速化、メモリ消費はシングルスレッドで

マルチプロセスの動き

  • クライアントの同時接続数が充分に少ない場合、マシンのメモリやリソースに充分な空きがあればプロセスは並行して適切に処理されるため、マルチプロセスだからという理由でレスポンスが遅くなるわけではない

クライアントの同時接続数が多くなった場合を考える

  • C10K問題とは
    • マシンのハードウェアやネットワーク性能に問題がなくても、クライアントの同時接続数がマシンのスペックや設定を超えてしまうとレスポンスが遅くなる問題

C10K問題を機能的に解決したNginx

Nginxは、C10K問題をシングルプロセス、ノンブロッキングI/Oで解決した
「ApacheよりNginxが大規模サービスに向いている」と言われている理由の一つはこれ

  • マルチプロセスのマシンスペックや設定によってC10K問題が発生する閾値はかわる
    • プロセス数上限が1000だったら1000付近でもうダメだし、メモリがそれ以前に足りなくなったら1000以下でももうダメになる
  • マルチプロセスでもサーバーのスペックあげたり、コンテナとかで水平スケールアウトしてお金の力で解決する方法ももちろんある

シングルプロセス、ノンブロッキングI/Oのデメリット

  • 実装がめんどくさい(promise, async,await)
  • 一部の時間がかかる挙動がサービス全体に影響する
    • 時間がかかる処理は外に置く
  • メモリやファイルなどのリソースを明示的に解放しないと枯渇する

おわりに

  • 疑問
    • ApacheよりNginxが大規模サービスに向いているのはなぜ?
  • 答え
    • シングルプロセス、シングルスレッド、ノンブロッキングI/Oは大規模サービスで発生しうるC10K問題の対策に有効なため

腑に落ちました!
引き続き、ISUCONに向けてNode.jsまわりのパフォーマンスについて調査を続けます。

Discussion