はてなブックマーク - ISUCON3のオンライン予選にFulabで参加してきました
    このエントリーをはてなブックマークに追加

    Fusic 平田です。
    あーだこーだ言ったりやったりしている間に当日を迎えてしまいましたので、予選に参加してきました。
    今回はヌーラボさんのお二人(@dragon3さん, @tksmdさん)と組ませてもらい、チーム名はFusic x nulab = Fulabに決定。

    ちなみに最終スコアは

    で、もう一歩のところだったのかなー1 と思われます。
    ※ 2013/10/09 20:00追記: 繰り上がり当選してました!

    だいたい時系列にやったことを並べると、

    前々日にSkypeでざっくり作戦会議

    ・まあPerlかなーとかvarnish使うかなーとか
    ・台風で予定狂いそうだったので3人で祈る

    当日朝

    ・無事3人揃って参加可能に
    ・ヌーラボさんにお邪魔して、環境準備とか
     ・TV会議システムで京都のtksmdさんとやり取り
      ・超スムーズでうらやましくなる
     ・backlogのプロジェクト立てたり、公開鍵渡したり
     ・他にチャットはtypetalk、メモはEtherPad
      ・とか書いてたら普通にヌーラボさんのプロダクツ紹介になっていたことに自分で驚いた

    開始

    ・とりあえず動かして初期スコア確認(Perlで800くらいだった)
    ・皆でいろいろ覗く
    ・とりあえずis_private邪魔だなーとかmy.cnfないなーとかそういう話

    11:00ごろ作戦会議

    ・ちゃっちゃとvarnish立てよう
    ・DBのインデックスとかクエリとか見直さないとね
    ・なんとなくフロント/アプリ/DBで役割分担

    ~13:00くらいまで

    ・さくっと2000くらいまでは行って、TOP5くらいには入っていそうなのを確認
    ・その後も見直しつつベンチ回す
    ・やっぱMySQL重いしCPU食ってるのがなかなか落ち着かない
    ・このへんでmarkdownの生成周りをどうにか対処しないとなーという話に
    ・is_private=0が邪魔なので、memos_publicテーブル作って、SQLのWHERE句に出てこないよう改修開始

    ~16:00くらいまで

    ・じりじり順位落としてツライ
    ・memcacheに乗せられるものを徐々に乗せる方向に
    ・並行してmarkdownの処理もキャッシュ作って乗せたりする方向に対応
    ・workloadを上げてみて、5くらいで一番スコア出たのを確認
    ・いくつか罠を見つけたので、引き続き罠探したり
    ・varnish側でgzip切ったのも多分この辺

    ~18:00

    ・MySQLの設定変えたらdiskfullになるとか
    ・markdown周りのキャッシュが効きだしてスコアがまた伸び始める
    ・他もいろいろmemcacheに乗せまくる
    ・どうもvarnishのキャッシュが乗せきれてないのを対処再開するも時間切れ

    といった感じでした。
    他のチームのやったことを見る限り、アプローチはだいたい間違ってなかったのかなーと。
    いくつか効果出そうなところで手をつけきれなかったりとか、フロントでうまくさばけていれば2 もっとスコア伸ばせたなーとか、その辺でいくらかずつ足りなかったようです。

    開始から終了まで、ずっと楽しかったです。
    ぜひ次回があればまた参加したいですね。
    主催の皆様、本当にありがとうございました。ぺこりぺこり。

    1. 暫定の予選突破ラインが8700くらいだったようで、本当にあと一歩でした。。。 []
    2. varnishでスコア激伸びした!てのも見かけるので、ブレークスルー起こせなかったのが心残り []
      はてなブックマーク - 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. 対応する傍らで関係各位に確認した結果、やはりそういった類のアクセス集中だったようで。 []
        はてなブックマーク - ITインフラ勉強会@福岡でISUCONの予習をしてきました
        このエントリーをはてなブックマークに追加

        Fusic 平田です。
        会社で「ISUCONがんばる」って言っちゃったので、仕事の合間をぬってITインフラ勉強会に参加してきました。
        fukinfra.doorkeeper.jp/events/5367

        他の方のエントリは以下。
        第6回ITインフラ勉強会@福岡に参加してきました。 – 肉まん始めました
        【福岡】インフラ勉強会で ISUCON を疑似体験してきました。 – komiyakの通り道
        第6回 ITインフラ勉強会@福岡 (ISUCON夏期講習のAMIで、もくもくチューニング)を開催しました – まつざきの技術メモ

        1時間ほど遅刻して着いてみたら既に2チームのvsが進行していたので、ひとりチームでもくもくチューニングしてましたすみませんすみませんすみません。

        以下ざっくりやったこと。
        HeigiSQLでexplain結果眺めながら、MySQLのインデックスをぺたぺた
        ・ログとdstatの結果を流しつつ各ページの動きを確認
        ・/ticket/の描画とソースみてこりゃ重いなーと思って、普段使ってるとおりvarnishを突っ込む
        vclは↓くらいで、単にpost来たらキャッシュ消すくらいで。
        ※ リクエスト眺めていたらpostが連続で来てたりもしていたので、キャッシュの運用についてはもっと賢いやり方があるだろうなーと思いつつ。

        backend default {
          .host = "127.0.0.1";
          .port = "6000";
        }
        sub vcl_recv {
            if (req.request == "POST") {
                ban("req.url ~ /");
                return (pass);
            }
            elseif (req.request != "GET") {
                return (pass);
            } else {
                return (lookup);
            }
        }

        ・dstatで見る限りアプリ側に余裕が見られたので、starmanのworkerを30まで増やす
        ・メモリよりI/Oのほうがきつそうだったので、varnishのキャッシュ先をファイルからメモリに変更
        → /etc/sysconfig/varnish内で「VARNISH_STORAGE=”malloc,4G”」と変更
        ・たまに計測がこけて、理由が/admin/order.csvのデータの中身の不整合だったので、order.csvへのリクエストはキャッシュしないよう変更
        ・POSTをもっとさばくために、/admin/set_cacheという別アクションでキャッシュ作ったのち、/buyの処理をキャッシュで軽減できるように修正
        → の途上で時間切れ
        とあいなりました。

        で、結果としては

        とスコア11万程度までは減りました。
        計測具合からvarnish導入で一気にスコア減るだろうなーというのは予測通りでしたが、DBのチューニング具合やアプリ改修具合については全然足りていなかったですね。
        計測する→どうする、の「どうする」武器をいろいろ持っておかねば、というのが喫緊の課題です。

        参加していた方々の話を聞いていると
        ・MySQLのチューニングをカリカリやっていた方
        ・カーネルパラメータなど見直していた方
        ・Webサーバの入れ替え検討とか、検討はともかくApache入れるぜ!とか
        などと、やっぱり人によって狙いが違うなーというのが面白かったです。

        で、第3回ISUCONの予選が10/5,10/6と決まりまして。
        さっそくFulab(Fusic x nulab)なチームで登録しております。
        isucon2013.kayac.com/qualifier_round/2
        参加される方々が(自チームの他お二人含め)非常に強力でどうしたもんかとプルプルしておりますが、どうか皆様お手柔らかにお願いいたします。。。