WEBサーバのチューングをしてみました(ApacheのMPMをpreforkからeventに変更)

この記事は約10分で読めます。

こんにちは

今日はブログネタです。

見ようかなと思う人が少なそうなので、最初に要約を。。

Webサーバのチューニングをしたら、ブログの表示が笑っちゃうぐらい早くなった。。気がします。多分。。(笑)

チューニングしたのは、昨日です。変わりました?

 

このブログのWebサーバアプリケーションって、「Apache HTTP Server」ってのを使ってます。

昔から使ってるので、なんとなくですが。。最近では「Nginx」と言うWebサーバが流行っているみたいです。

「Nginx」ですが、なんて読むの?と調べた事があり、「エンジンエックス」だそうです。これは。。読めませんよ!(笑)

次にサーバを立てる時は、「Nginx」にチャレンジしてみようかなと思ってたりします。ただ、「Nginx」には「.htaccess」が無いとか。。かなり躊躇します。(^_^;

今のサーバを立てる時は、MTAを慣れ親しんだ「qmail」から「postfix」に変更したんですよね。

 

現在Webサーバの「KeepAlive」と言う機能をOFFにしてあります。

KeepAliveってなんぞ!?と言うと、ざっくりと言うとWebページって、本体(html/テキスト)があり、それ以外に画像等のパーツが大量にくっついてます。

それぞれ別のファイルとなってまして、本体を受信してからその中身を解析して記載されている必要なパーツを全て貰ってきます。

単純に本体に画像が50個あると、51回の受信を行います。それぞれに接続→依頼→切断を51回繰り返します。

流石に効率が悪いので、KeepAliveという機能がありまして、接続したまま連続してファイルを受信する機能が簡単に言うとKeepAliveです。

KeepAliveって、基本的には接続と、切断の間にサーバ側で時間が指定(10秒とか、以下10秒と記載)されていて、その間は繋ぎっぱなしになります。

効率は良いのですが、ブラウザに寄りますが、同時に複数の接続されるので使うブラウザが10多重の場合、10秒間の間10の接続が維持されます。

別に良いじゃん!って感じなんですが、10秒間に10人がアクセスがあるとサーバ側では100のプログラムが接続しっぱなしで待ってる状態になります。

で。。このサーバの場合、メモリが2Gしか(?)ないので、メモリが大量に足りなくなりスワップが大量に発生してしまいハングアップ(に見える)状況に夜な夜ななりました(^_^;

同時につながっている数(プロセス)×数十Mバイトのメモリが必要になりますが、用意できる訳もないのでKeepAliveはOFFしてました。

KeepAliveがOFFだと、同時にアクセスする数には基本差はありませんが、Webページへのアクセスが終わったら10秒待たずにその場で開放されますので、抑制できます。

実際、それだけではダメで夕方から夜間のアクセスの多重度が高い時間帯で同じ様にメモリ不足でハングアップしてしまって、仕方なく起動するプログラムの数を減らして、それを超えたアクセスはまってもらう形にしています。

 

KeepAliveのON/OFF以前に同時アクセスを賄うだけのメモリが足りないのが実情でした。

 

 

で。。何回か失敗してましたが、なんとなく気分が乗った(笑)ので根本的に対応してみました。

メモリが足りないのが問題なので、消費量を減らしましょう!

Webサーバを変更するのは大事なので、変更せずに改善できる(かも?)な方法があります。

Apache Web ServerにはMPMと言う物があります。

このページの説明が分りやすかったです。

→ Apache MPMとはなんぞやという話/備忘録の裏のチラシ

 

今のバージョンのサーバアプリには以下の3つがあります。

・prefork(マルチプロセスモデル)

・worker(マルチスレッドモデル)

・event'(イベント駆動モデル)

 

現在は、昔から馴染みのあるpreforkを使っていました。eventは今のバージョンからだそうです。

preforkって、1つの接続依頼に対して1つのプロセス(プログラム)を使って処理します。メモリ不足の原因と言うかメモリを使う原因です。

上で書いた例だと、10人がアクセスすると同じプログラムが100個起動されます。。。すごっ(^_^;

 

workerに変更しようと思ってました。workerってプロセスも起動しますが、1つのプロセス(プログラム)の中で複数のスレッド(処理)を実行します。

1つのプログラムの中で同時に処理するスレッドの数は指定できます。処理するスレッドを1プロセス50とすると、起動するプロセス(プログラム)は2つで済みます。

感動的な気もしますが、抑制できるのは基本プログラム部分で、記憶している内容などはスレッド単位で必要になりますので、メモリの使用量はpreforkよりもかなり多いハズですが、それでも同じプログラムを100個も起動してメモリ内配置するよりはメモリは必要ないはずです。

 

あと、eventですが、workerに変更しようと思ってみてて発見(笑)しました。

workerをイベント駆動形にした物だそうで、最新(笑)のブツです。主にKeepAliveを意識している様で、KeepAliveをONにしたい!と言う動機からはevent一択かな?

 

と言う事で、変更してみます。

と思いましたが、ブログシステムってWordpressはPHPと言うプログラム言語で動いてまして、PHPはCGI版(コマンド実行)とモジュール版(内部?実行)があり、実行効率が良いと思うモジュール版を使っています。で、CGI版とモジュール版のPHPって、基本的にスレッドセーフじゃないと。。(^_^;

なにそれ?と言うと、マルチスレッド(1つのプログラム内で複数のスレッド実行)はできないとの事。。なので、これを使っているとMPMをworkerやeventにはできないそうです。

 

実は。。Wordpressの動作するPHPのバージョンが変更になりまして。。状況的にPHPはサイト単位で複数のバージョンが動いています。

WordPressを使っているサイトは最新の7.3系のPHPなんですが、他のバージョンと同居させるために、php-fpm/FastCGIで動いています。(説明が書ききれないので何ぞ!は端折ります)

これはスレッドセーフ環境でも処理できますので、他のバージョンのPHPもphp-fpm/FastCGIに事前に移行しました。

 

と言う前提から書きます。

 

最初に実行環境を確認します。

コマンドを実行してMPMを確認します。予定通りpreforkでした。

# httpd -V | grep -i mpm
	Server MPM:     prefork 

 

現在のMPMの設定を確認します。最大40プロセスまで実行できます。割と小さい環境です。

# cd /etc/httpd/conf.d/mpm.conf
<IfModule mpm_prefork_module>
        StartServers            5
        MinSpareServers         5
        MaxSpareServers         10
        ServerLimit             40
        MaxClients              40
        MaxRequestsPerChild     500
        MaxMemFree              1024
</IfModule>

 

ちなみにKeepAliveはOFFになっています。

# grep KeepAlive /etc/httpd/conf/httpd.conf
KeepAlive               Off
MaxKeepAliveRequests    50
KeepAliveTimeout        5

 

MPMをeventに変更します。戻せる様に今の設定をバックアップしてからにしました。

# cd /etc/httpd/conf.d/mpm.conf
<IfModule mpm_prefork_module>
        StartServers            5
        MinSpareServers         5
        MaxSpareServers         10
        ServerLimit             40
        MaxClients              40
        MaxRequestsPerChild     500
        MaxMemFree              1024
</IfModule>

 

Webサーバを再起動しようと思いましたが、不安になったので設定ファイルの文法チェックします。

# apachectl configtest
Syntax OK

大丈夫でした。

 

再読み込み。。で良いとは思えないので、再起動します。ちなみにOSはCentos7です。

systemctl restart httpd

 

で、変更されたか確認。。。

# httpd -V | grep -i mpm
Server MPM:     prefork

変わっていないし。。

読み込むモジュールを変更しないとダメでした。(^_^;

「/etc/httpd/conf.modules.d/00-mpm.conf」中のpreforkをコメントして、eventのコメントを外しして再起動。

#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
LoadModule mpm_event_module modules/mod_mpm_event.so

 

で、確認。

# httpd -V | grep -i mpm
Server MPM:     event

eventに変わってます\(^o^)/

このブログが動いているのを確認したので、KeepAliveをONにします。100回リクエストを受け取るか、10秒経過で開放です。

# grep KeepAlive /etc/httpd/conf/httpd.conf
KeepAlive               On
MaxKeepAliveRequests    100
KeepAliveTimeout        10

 

しばらく様子を見てましたが、急に不安に。。設定。。見えを張りました(^_^;

設定を小さく変更します。

同時アクセスは160までOKとします。プロセスは最大5までです。

1000回使われたらサーバ(プロセス)を終了(次のプロセスにバトンタッチ)します。これはメモリリーク(バグ)の保険的な意味です。無くても良さそうですが不安なので。。

1プロセス32スレッドまで、プロセス数が5なので、32×5=160同時アクセスが最大。。であってるはずです。ちょっと不安。。

# cat /etc/httpd/conf.d/mpm.conf
<IfModule mpm_event_module>
        StartServers            2
        ServerLimit             5
        MinSpareThreads         32
        MaxSpareThreads         64
        ThreadsPerChild         32
        MaxRequestWorkers       160
        MaxConnectionsPerChild  1000
</IfModule>

 

Webサーバのステータスですが、KeepAliveがOFFだとスカスカでしたが。。

ONにしたら、大分忙しくなりました。

WEBページのスピードチェックをしてみたら。K(KeepAliveが増えました)

サーバの状態もしばらくウォッチしてましたが、メモリの使用量が極端に増えないので多分大丈夫かなと思います。

様子を見て、プロセス数とかもう少し増やしてみよかな?と思ってます。

 

 

コメント