今日のことなんですが、運用しているWebサービスに集中したアクセスがあって繋がりづらい自体に陥ってしまいました(SSHすらも) psコマンドで確認したところhttpdプロセスがメモリをもりもり使っててメモリリーク(メモリリークとは違うけど、まあ今回はそう呼ぶ)していたようで、これはよくないとApacheのチューニングを行ったのでその内容を記事にしておきます。
なにをしたか
httpdプロセスが立ち上がりすぎてメモリが溢れないよう、立ち上がるプロセス量を調整しました。
↓この記事を参考にチューニングしました。
Apacheに割り当て可能なメモリ量を調べる
参考記事では「OS起動直後にfreeコマンドを打てばわかるよ」というような事を言っていましたが、現在サービス運用中で再起動はしたくないので以下の方法で割り当て量を出しました。
a,VPSに積まれたメモリは2GB
b,システムが現在使っているメモリ量は約1.5GB。(freeコマンドのusedの値)
c,現在Apacheが使用しているメモリ総量は約1GB。
※Apacheが使用しているメモリ総量はこれ↓で計算。
# ps aux | grep [h]ttpd | grep [a]pache | awk 'BEGIN{x=0}{x+=$6}END{ print x }' 1026700
つまり Apache以外が使っているメモリは 1.5GB(b)-1GB(c)=0.5GB なので 使えるメモリ量は 2GB(a)-0.5GB=1.5GB=1536MB としました。
Apacheの最大子プロセス数を調べる
まずはApacheの子プロセスあたりの平均メモリ使用量を計算。
# ps aux | grep [h]ttpd | grep [a]pache | awk 'BEGIN{x=0}{x+=$6}END{ print x/NR }' 51255
子プロセス一つあたり51255(約52MB)使っているみたい。 なので、Apacheの最大子プロセス数は
Apacheの最大子プロセス数 : P = 1536MB(Apacheに割り当て可能なメモリ量) / 52MB(Apacheの子プロセスあたりの平均メモリ使用量)
で P = 29.538461・・・・ となります。
Apacheの設定変更
ここまでで調べた値を元にhttpd.confを編集します。 参考記事では下記の内容で設定するのをオススメしていましたが
<IfModule prefork.c> StartServers P×5/256 MinSpareServers P×5/256 MaxSpareServers P×10/256 ServerLimit P MaxClients P MaxRequestsPerChild 1000 </IfModule>
それで計算するとこうなります。
<IfModule prefork.c> StartServers 1 MinSpareServers 1 MaxSpareServers 2 ServerLimit 30 MaxClients 30 MaxRequestsPerChild 1000 </IfModule>
うーん、なんか少なすぎるような。。 適当にもう少し増やしてみます。
<IfModule prefork.c> StartServers 3 MinSpareServers 3 MaxSpareServers 7 ServerLimit 30 MaxClients 30 MaxRequestsPerChild 1000 </IfModule>
ほんと適当です。根拠無いです。
おそらく ServerLimit と MaxClients さえ変えなければそこまでひどい事にはならないと思うので。
と、今回はこんな感じで設定してみました。これでメモリリーク起きなくなるはず。