Apacheにサーバーのメモリを食い尽くさせない
投稿日:
環境
- Amazon Linux AMI 2018.03
- Apache/2.4.34 (Amazon)
Apache(prefork)がサーバーのメモリを食い尽くしていたのでチューニングしました。
その際に行なった調査や計算をメモとして残します。
なお、preforkからeventに変更できる場合や、nginxに移行できるのであれば
そちらの方がいいかもしれません。
今回はあくまでpreforkをチューニングする前提での手順です。
サーバー物理メモリ確認
まず、サーバーの物理メモリを調べます
# cat /proc/meminfo | head -n 1
MemTotal: 2004484 kB
このサーバーの搭載メモリは2GBのようです。
現在のメモリ使用状況確認
まずサーバー全体の使用メモリを確認します。
以下のワンライナーで出します。(単位はMB)
# ps aux | awk '{print $6}' | awk '{sum=sum+($1/1024);cnt++;} END{print "sum="sum}'
sum=919.656
次にhttpdの子プロセスの使用メモリを確認します。
以下のワンライナーで出します。(単位はMB)
# ps aux | grep httpd | grep apache | awk '{print $6}' | awk '{sum=sum+($1/1024);cnt++;} END{print "sum="sum " cnt="cnt " ave="sum/cnt;}'
sum=804.273 cnt=20 ave=40.2137
出力結果は以下のようにしています。
項目 | 意味 |
---|---|
sum | 現時点のhttpd子プロセスが使っている総メモリ |
cnt | httpd子プロセスの数 |
ave | httpd子プロセス1つが利用している平均メモリ |
※補足
サーバー全体のメモリ使用量は前述の/proc/meminfoやfreeコマンドからでも出せるのですが
それだとpsコマンドの結果と少しずれてしまうのでpsコマンドに統一しています。
計算
ここまでで分かった事を整理します。
- サーバーの搭載メモリ = 約2GB ・・・①
- 現時点の総使用メモリ = 約920MB ・・・②
- うち、Apache子プロセスの使用メモリ = 約800MB ・・・③
- Apache子プロセス以外の使用メモリ = 約120MB ・・・④(②−③)
- Apache子プロセス1つあたりが使うメモリ = 約40MB ・・・⑤
ここからざっくり計算していきます。
- Apache子プロセス以外用に残すメモリ = 500MB ・・・⑥(④を元に超ざっくり&余裕を持って)
- Apache子プロセスで使うメモリ = 1500MB程度 ・・・⑦(①−⑥)
- 生成できるApacheプロセス数 = 35個程度 ・・・⑧(⑦÷⑤)
Apacheの設定にてこれを設定します。
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
ServerLimit 35 #先ほど計算した結果に変更
MaxClients 35 #先ほど計算した結果に変更
MaxConnectionsPerChild 0
</IfModule>
既存のApacheの設定ファイルに上記が設定されている箇所が存在しない場合は
httpd.confに追記するか/etc/httpd/conf.d/配下に新設定ファイルを作成して記載するのでも良いです。
他にも基本的にhttpd子プロセスは常時20個くらい動いていて欲しかったりして、
最終的に以下の設定にしました。
<IfModule mpm_prefork_module>
StartServers 20 #httpd起動時にプロセスを20個動かす
MinSpareServers 5
MaxSpareServers 20 #リクエスト待ちプロセスは最大20個とする
ServerLimit 35
MaxClients 35
MaxConnectionsPerChild 5000 #ある程度処理したら子プロセスには産まれ変わってもらう
</IfModule>