Posts Tagged ‘apache’

    はてなブックマーク - Apacheのmod_cacheを利用して静的コンテンツをキャッシュさせた話(追記あり)
    このエントリーをはてなブックマークに追加

    Fusic 平田です。

    前のエントリの延長のようなそうでもない話です。

    あらすじ

    ある日「サーバがレスポンスをろくに返さない」と連絡があり、すわ障害発生かとおもむろにsshクライアントを立ち上げ、接続。
    この時点でよくあるのは

    • サーバがハングしていたりして接続できない
    • なんとか繋がるもののすごく重い・ロードアベレージが鬼のように高い
    • その他障害などでエラーが発生しているとかディスク障害が起きてるとかblog書いてる場合じゃない事態とか

    といったあたり(書いてる場合じゃない事態はそうそう起きません)なのですが。
    普通にssh接続できるし、dstatで眺めてもCPUなりメモリなりで刺さってるわけでもなし。
    はて。。。と思いつつ

    # tailf /var/log/httpd/access_log

    とかやってみると、滝のように流れまくるアクセスログ。

    「どうしてこうなった」はさておき、とにかく対応せないかんという話で。
    前のエントリの流れを汲むなら「よしvarnishでもさっくり突っ込んでキャッシュでぶん回して対処」といきたい1 んですが。

    で、アクセス状況をざっくり計測した感じだと

    • アクセスは特定の静的ページ(http://toaru-site.com/miwaku_no/contents/)に集中している
    • 特定の静的ページがいわゆるランディングページなので、何かしら宣伝なりを打った結果の一時的なアクセス集中だろう2

    といったあたりから、Apacheのmod_cacheで一時的に凌げる範疇だろうということで、さっくり設定を入れて対応してみました。

    1. キャッシュ設定を追加

    ※ OSはCentOS6で、Apacheは2.2.15です。
    /etc/httpd/conf.d/cache.confとして以下のファイルを作成。

    CacheRoot /tmp/cache
    CacheEnable disk /miwaku_no/contents
    CacheDirLevels 5
    CacheDirLength 3
    CacheIgnoreCacheControl On
    CacheIgnoreNoLastMod On

    のちapache再起動して、/tmp/cache以下にキャッシュファイルが作成されることと、対象ページのレスポンスが速くなることを確認。

    2. 他のパラメータを調整

    これでおおよそ大丈夫かなと思ったのですが、他の設定値を若干絞っていたりして、まだ動作がよろしくない。
    ということで、

    • Maxclientなどの値を、dstatで具合を見つつ増やす
    • KeepAliveをOff→Onに変更

    といったあたりを調整。

    3. キャッシュ設定を少し追加

    画像やCSSもキャッシュさせて、より負荷を下げるように調整。

    これでおおよそ安定して捌けるようになったので、この設定のまま1日様子見。
    のちアクセス具合も通常に戻ったので、設定を戻して事なきを得ました。

    てことで

    現状の構成をなるべく変えることなく、と言う観点で対応できたのは良かったのかなと。
    アクセスが集中しやすい箇所をあらかじめキャッシュさせるようにするなど、事前に戦略を練るべきではありましたが。。。

    追記

    cakephperさんからツッコミいただきました。
    ※ 回答としては、originサーバでの話です。

    言われてみれば若干腑に落ちないところもあるなー、ってことで実験。

    測ってみた

    手元のApache環境で、Cache設定あり/なしで、

    $ http_load -parallel 100 -seconds 10 ./miwaku_no_urllist

    てな感じで、100並列/10秒実行。
    実際にアクセス食らったページとおおよそ同様のページ/画像/他(計53リクエスト)で実験。

    ○ cacheなし

    $ http_load -parallel 100 -seconds 10 ./urllist 
    12186 fetches, 100 max parallel, 2.43872e+08 bytes, in 10 seconds
    20012.4 mean bytes/connection
    1218.6 fetches/sec, 2.43872e+07 bytes/sec
    msecs/connect: 0.119898 mean, 1.853 max, 0.046 min
    msecs/first-response: 81.5065 mean, 925.366 max, 1.622 min
    HTTP response codes:
      code 200 -- 12186

    ○ cacheあり

    $ http_load -parallel 100 -seconds 10 ./miwaku_no_urllist 
    15541 fetches, 100 max parallel, 3.18031e+08 bytes, in 10 seconds
    20464 mean bytes/connection
    1554.1 fetches/sec, 3.18031e+07 bytes/sec
    msecs/connect: 0.119447 mean, 6.493 max, 0.04 min
    msecs/first-response: 63.8984 mean, 988.844 max, 2.231 min
    HTTP response codes:
      code 200 -- 15541

    どちらも10回ほど実験してみて、結果としては

    • cacheなし:約11000~14000リクエスト
    • cacheあり:約14000~17000リクエスト

    てことで、平均すると25~30%程度のパフォーマンス向上が見られます。
    KeepAliveをOn/OffしたりMaxClientあたりをいじってみたりもしましたが、おおよそ同じような向上具合。
    静的コンテンツに対しても、一定の効果はあるようです。

    ついでなので

    varnish突っ込んで

    $ http_load -parallel 100 -seconds 10 ./miwaku_no_urllist_via_varnish

    というのもやってみました。

    ○ varnish

    $ http_load -parallel 100 -seconds 10 ./miwaku_no_urllist_via_varnish 
    65393 fetches, 100 max parallel, 1.35126e+09 bytes, in 10 seconds
    20663.7 mean bytes/connection
    6539.29 fetches/sec, 1.35126e+08 bytes/sec
    msecs/connect: 0.154726 mean, 6.537 max, 0.033 min
    msecs/first-response: 14.9211 mean, 44.383 max, 0.688 min
    HTTP response codes:
      code 200 -- 65393

    はやい。(小並感)

    1. 実際、その選択肢もなくはなかった。 []
    2. 対応する傍らで関係各位に確認した結果、やはりそういった類のアクセス集中だったようで。 []
      はてなブックマーク - WordPressが動いているサーバのApache設定
      このエントリーをはてなブックマークに追加

      Fusic 平田です。
      次の人にバトンタッチしたつもりが自分でした。

      発端

      このエントリが原因でサーバが落ちたのがきっかけ。
      と言ってもそこまでアクセス数がすさまじかったわけでもないので、いろいろ見直した次第です。
      状況としては

      • 落ちた原因はメモリ枯渇
      • メモリは256MB+swap1GB

      といった感じです。

      見直しその1 – プロセス数とか調整

      とりあえずMaxClientsとかを見直し。
      デフォルトのままで

      <IfModule prefork.c>
      StartServers      8
      MinSpareServers   5
      MaxSpareServers   20
      ServerLimit       20
      MaxClients        256
      MaxRequestsPerChild  4000
      </IfModule>

      になっていたんですが、これだと富豪すぎるので

      <IfModule prefork.c>
      StartServers      8
      MinSpareServers   8
      MaxSpareServers   8
      ServerLimit       8
      MaxClients        8
      MaxRequestsPerChild  32
      </IfModule>

      くらいまで極端に減らしました。
      繋がらないとか出たらまた増やしながら様子見ようという魂胆。

      各設定値についてはこのへんが参考になるかと。
      省運用目的だとこのくらいで十分かな、といった印象です。
      もっとメモリに余裕があって待機プロセス多くても問題ない時は

      <IfModule prefork.c>
      StartServers      32
      MinSpareServers   32
      MaxSpareServers   32
      ServerLimit       32
      MaxClients        32
      MaxRequestsPerChild  64
      </IfModule>

      くらいで運用してたりします。
      「これだと一斉にMaxRequestPerChild迎えて死ぬからいやん」って人はmod_bumpy_lifeがいい感じです。

      見直しその2 – 不要モジュールを切る

      あとは1プロセスごとの使用メモリを抑える方向に。
      余計なモジュールはロードしなくていいので。
      これはいらないだろう、を少しずつ切ってます。

      #LoadModule authz_owner_module modules/mod_authz_owner.so
      #LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
      #LoadModule authz_dbm_module modules/mod_authz_dbm.so
      #LoadModule ldap_module modules/mod_ldap.so
      #LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
      #LoadModule env_module modules/mod_env.so
      #LoadModule ext_filter_module modules/mod_ext_filter.so
      #LoadModule dav_module modules/mod_dav.so
      #LoadModule dav_fs_module modules/mod_dav_fs.so
      #LoadModule actions_module modules/mod_actions.so
      #LoadModule speling_module modules/mod_speling.so
      #LoadModule proxy_ftp_module modules/mod_proxy_ftp.so

      もっと切っていいモジュールはあるんですが、その辺はサーバの用途とにらめっこして決めるのがいいでしょう。

      で再起動して様子見

      再起動してtopを画面脇に流しつつ様子見。
      こっそりabでリクエスト投げたり普通にリロード連打したりで、とりあえずは安定したっぽいのでこのくらいで。
      まとめると

      • preforkのデフォルト設定は普通のサイトだと結構な富豪具合なので要調整
      • モジュールも明らかに不要ならさっくり切る

      といったところです。
      あまり凝ったことをしないで済むようには心がけています。

      てことで

      今度こそ次の人にバトンタッチ。