Apache最大同時接続数の設定考察について
2019年10月12日Linux Tips, テクニカル, トピックス
Apache Webサーバは、接続に関するプロセスの作り方を3種類のモジュールタイプで提供している。
それはprefork/worker/eventがその3種類に該当し、いずれかのモジュールタイプを選択して利用することになる。デフォルトはpreforkである。(Redhat8/CentOS8ではeventがデフォルト。)
preforkは単純に1セッションづつ扱うhttpdプロセスを決められた最大数(maxclients)まで状況に応じて生成してゆく方式である。
なぜ、このpreforkをデフォルトにしているかだが、様々なサーバ環境構築で万人が使って失敗しにくいというのが本音だろう。thread safeな仕組みなら大きな問題は出ない。しかしパフォーマンスが高いのは間違いなくworker,eventタイプである。
worker,eventはapache連携する他のサーバとの兼ね合いがあるため通信スレッドの生成パターンが相性良くないと落ちてしまう原因を作る。マルチプロセス方式とマルチプロセス/マルチスレッド方式、マルチスレッド方式はどれも通信コネクションの生成挙動が異なるのでApacheに限らずコネクションの生成パターンを観察する術はサーバ連携を行う際はよく調べる必要があります。
worker,eventタイプはマルチプロセス/マルチスレッド方式なので使い方間違えると失敗する玄人な動作モードだ。workerとevent型は基本的に同じ動きなのですが、event では「プロセス数不足」というEventをきっかけに生成する部分だけworkerと違う。イベントが終わった後のプロセスの終了も考えると連携するサーバ、あるいはアプリケーションが
それを理解していないといけない、あるいは一定時間No responseなら待機モードになるとかそういう意味のサーバ連携、アプリ連携で相互の噛み合わせを調整する必要があります。fastcgiでPHPを使う場合(php-fpm)使う際はworker、eventを使うがこちらはapacheと相性が良いのは間違いない。http2に切り替えているサイトも多いのでmod_phpからfastcgiで使うパターンが最近ではかなり増えているようだ。
preforkモードでのApacheセッション設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<IfModule mpm_prefork_module> StartServers 50 ←起動時に生成の子サーバプロセス数。デフォルトは5。 MinSpareServers 50 ←アイドル状態の子サーバプロセス最小数。デフォルトは5。 MaxSpareServers 100 ←アイドル状態の子サーバプロセスの最大数。デフォルトは10。 ServerLimit 500 ←MaxClientsに対しサーバ側の受け取る上限数。(MaxClientより大きな数にする) MaxClients 480 ←応答できる同時リクエスト数。デフォルトは256。 MaxRequestsPerChild 2000 ←1子プロセスのリクエストを受け付ける総数(ライフサイクル)。デフォルトは10000。0にすると無制限だが無制限はよくない。 必ず最大数を決める。よく勘違いされるパラメータだがここで設定した数を受け付けるとリセット処理として 子プロセスが死んで新たな子プロセスが生成される。消せないメモリのゴミ掃除といったところだろう。多くの インターネットサーバはメモリ空間の一部が後々溜まって消せないメモリ空間で満たされる。 そのためこのようなオプションを設けて一旦メモリ空間を放棄して新プロセスで新規メモリ空間を掴む。 それが安定した動作の基本となっているケースが多いのでおそらくガベージコレクションの理由で使っていると思う。 Google Analyticsでセッションの平均滞在時間を見て短ければ多目で良いと思う。滞在時間が長ければ短めに するなどKeepAliveとの兼ね合いで検討。アクセス数の多いサイトだとこの設定によってレスポンスの応答 に影響が出る。 </IfModule> |
メモリ量、CPUの処理能力、平均的なネットワークの帯域の余裕によってこの適正値があると思います。メモリ容量に余裕があるならServerLimit,MaxClients, MaxRequestsPerChildは多めにとっても良いと思います。上記の例はあくまでも解説用の架空の値なので作業するサーバの状況に合わせて値を適宜変更してください。
MaxClients及びServerLimitの設定値 計算方法
昔から色々な説が飛び交っているけれど、私は概ね次のように考えて設計している。
MaxClients = サーバ合計メモリ * (80%〜70%) / httpdプロセスの最大メモリ使用量(子httpdピーク時の平均値です。)
httpdプロセスメモリ使用量 = (親httpdメモリ容量 + 子httpdの平均物理メモリ使用量 ✕ MaxClients)- 子httpd共有プロセスメモリ使用合計値 + その他WEB連携サーバ(MySQLサーバ,FastCGIプロセス等)
- ※httpdプロセスで使うメモリ容量はそのサーバマシンで他に何(プロセス)が動いているかでメモリ考慮割合は異なるがおおよそサーバ全体メモリが5GB以下なら最初の運用は70%以下の容量に抑えて計算するのが安全と思う。後はログや統計を見ながら少しづつアップさせできるだけSWAPが頻繁に起きない程度にしておくことをお勧めする。
他のプロセスが極めて使用率が低いなら多少増やしてSWAP対応もありだが、SWAPも使い出すと止まらなくなるためリクエストに対するレスポンスWait時間が長くなり遅くなる。落ちる場合も当然ある。SSDにswapしているなら処理が早いので良いがまだSSDの信頼性&耐久性がちょっと心配。SSDのICチップに内蔵のトランジスタが焼けてしまわないかと思ってしまう。最近読んだ記事によると意外にも統計上はSSDの故障率は少ないみたいだ。昔からSSDはRead/writeの多発は故障、消耗(寿命が短命)に繋がるだろうと言われてきたので、実際の実績としては想定以上に長持ちしているとのこと。 - ※子httpdの平均物理メモリ使用量、親httpdのメモリ使用量、その他のメモリ使用量はtopコマンドのRESをチェックし計算する。子httpdプロセス共有は(SHR)で計算する。
- ※親プロセスから子プロセスをforkすると、子プロセスが親プロセスのメモリ空間をshareします。すなわちそのshare分(SHR)を引く必要があります。
- ※パラメータで ServerLimit > MaxClients になるように設定する。
- ※セッションの終了とセッションの開始はTCPのリサイクルに要する時間、ハンドシェークのステータス変化に遅延が生じるため「ServerLimit > MaxClients」のようにしないとセッションの要求と需要が噛み合って来ない。適正値は実験で求めるとよい。サイト毎のサーバやネットワーク、コンテンツの性格、ユーザの傾向にも依存するため余裕をもって値を設計するとよいだろう。
測定の際に使うtopコマンドの使い方
下記はapacheユーザだけ特定してtopコマンドでプロセスを表示する 方法です。当然httpd子プロセスのみ表示されるためメモリの使用量が観測しやすくなります。
1 |
$ top -u apache |