― Web Technology and Life ―

Apacheとかforkしたプロセスのメモリチューニングに関するメモとスクリプト

2013-10-10
forkしたプロセスのメモリチューニングのための調査ツールの話と、具体的にApacheで調査の話

forkしたプロセスのメモリチューニングのための調査ツール

naoyaさんのshared_memory_size.plっていうのがあって、このブログの記事の内容とか後関連書籍の内容が文系プログラマ的にとても参考になってマジ感謝なんですが、apacheのプロセスチェックするときだとsudoつけて実行するから、いちいちSystem perlにLinux::Smapsいれなきゃいけないくて、しかもぼくのubuntu環境だと最新版の0.12の06-VmFlags.tってテストがこけてキモイし、別にLinux::Smaps使わなくてもいいやと思ったので、スクリプト化しました。

あと、共有していない部分のメモリ使用量もいちいち掛け算するのだるいので、右に出すことにした。

#!/usr/bin/env perl
use strict;
use warnings;

@ARGV or die "usage: %0 [pid ...]";

printf "PID\tRSS\tSHARED\tNONE_SHARED\n";

for my $pid (@ARGV) {
    open my $fh, "< /proc/$pid/smaps" or (warn  $! and next);
    my @rows = <$fh>;
    my $rss    = mem_size_fetcher('Rss',@rows) or next;
    my $shared = mem_size_fetcher('Shared_Clean',@rows) + mem_size_fetcher('Shared_Dirty',@rows);

    printf
        "%d\t%d\t%d (%d%%)\t%d\n",
        $pid,
        $rss,
        $shared,
        int(($shared / $rss) * 100),
        ($rss - $shared),
}

sub mem_size_fetcher {
    my ($target,@rows) = @_;

    my $mem_size = 0;

    for my $row (@rows) {
        my ($mem) = $row =~ /^$target:\s*(\d+)/i;
        $mem_size +=($mem||0);
    }

    return $mem_size;
}

使い方は、naoyaさんのと同じで、

sudo perl none_shared_memory_fetcher.pl `pgrep apache2` | head 

ってたたけば、

PID     RSS     SHARED  NONE_SHARED
31021   6600    5572 (84%)      1028
31024   5064    4868 (96%)      196
31025   5068    4868 (96%)      200
31026   5040    4840 (96%)      200
31027   5684    5172 (90%)      512
31028   5088    4892 (96%)      196
31029   5032    4840 (96%)      192
31030   5040    4844 (96%)      196
31031   5044    4840 (95%)      204

って感じに出力される。NONE_SHAREDのkb数が子プロセス単独のメモリ使用量なので、ばらつきがあるものこれだと、だいたい大目に見て、250くらいで、×プロセス数がApacheに使うメモリってことになるみたい。

なお、リクエストの度にメモリリークとかいろいろで子プロセスは太る傾向にあるから、ある程度リクエスト流して、MaxRequestsPerChildの上限近いプロセスで計算する必要があるみたい。

DSASチームのとてもありがたい下の方にMySQLのInnoDB周りのメモリ設定用ツールがあるんだけど、ホントはこんな感じのがあるといいけど、いまどきApacheだけに限定するのもキモいのでそういうのはやめた。

Apacheのプロセスチューニング

Apacheの並列処理システム

  • prefork(プロセスの単純なfork)
  • worker(fork × スレッド)
  • event(fork × event)

と三種類あるけど、現在主流のApache2.2だと、デフォルトがprefork。Nginxはevent相当だと思います。

スレッドとか罠が多そうなので、乗り換えられず、スレッド使うなら、Nginxに乗り換えるときなのかなーと思っていますが、どうなんでしょうか?なぜ、Apache2.4とかに乗り換えてeventとか使わずに、みなさんNginxに乗り換えるんでしょうか?Apache2.4が遅かった説が濃厚ですが。

preforkのチューニング

前述したツールもだけど、[24時間365日] サーバ/インフラを支える技術とかに詳しく書いてあるので素晴らしい。あと、環境によって違うと思うけど、ubuntuだと「ロードされているmpmの確認:sudo apache2ctl -V | grep 'Server MPM'」で可能。

あと、MaxClientsを300とかに設定しようとしたら、

MaxClients to 256.  To increase, please see the ServerLimit directive.

って怒られたんだけど、(ここに書いてあるコメントみたら)[http://af-design.com/blog/2009/02/17/increasing-apache-serverlimit-on-ubuntu/]MaxClientsより上に、ServerLimitを設定すればいいとかいかにもApacheらしいコメントがあってそうしたらできた(苦笑

その他参考URL

ベンチマークツールabの使い方とか

安定のbayashi.netググラビリティ

プロのサーバ管理者がApacheのStartServers, (Min|Max)SpareServers, MaxClientsを同じにする理由

とりあえず、以下は全部同じにしておけばいいというありがたいおはなし。
  • StartServers 200
  • MinSpareServers 200
  • MaxSpareServers 200
  • MaxClients 200
あとメモリリークとかあるから、適当にMaxRequestsPerChild 1000を設定。

Apacheパフォーマンス・チューニングの実践 (2/2)

KeepAlive周りの以下の設定も重要

  • KeepAlive
  • MaxKeepAliveRequests
  • KeepAliveTimeout

おわりに ~Nginxよ突然に~

前近代的な雰囲気の漂うApacheのチューニングなんで、大規模本に載っているかなと思いつついろいろ見返したんですが、結構Apacheが主流で載っているんですね。「24時間365日] サーバ/インフラを支える技術」の初版が2008年で、「4gbpsを超えるwebサービス構築術」の初版が、2009年なんですが、いずれもApacheのTipsが中心で、Nginxは存在すら触れられていません。2010年初版の「大規模サービス技術入門」になってようやく、その他のWebサーバーと並んで一言だけNginxが登場します。ただ、同年のYAPCでfujiwaraさんによるnginx & Perlのトークがあるので、まぁ2010年頃が盛り上がってきたのかなーという感じですが、みなさんの切り替えの早さには驚くべきところがありますね。 Nginxの書籍はハイパフォーマンスHTTPサーバ Nginx入門一択ですが、雑誌とかいろいろな文脈でちょこちょこナレッジが出てきているので、そろそろしっかり展開しておきたい今日この頃ですね。。。

とりあえず、#isuconの予選の初期実装もApacheだったらしいので、それにあやかりましてメモにしました。

Apache update_at : 2013-10-10T22:24:04
hirobanex.netの更新情報の取得
 RSSリーダーで購読する   
blog comments powered by Disqus