私が歌川です

@utgwkk が書いている

ISHOCON1に参加した #scouty_ishocon

scouty.connpass.com

参加させていただき,解いた.最終得点は85402点で,4位だった.

gyazo.com

:ok_man: というチームで*1参加した.

github.com

ここから先は解いたときの過程などがあり,ネタバレを大いに含みます.

経過

コミットログを見ながらのほうが早い.

  • 開始と同時にいつもの dotfiles を設置した.
    • パスワードが分からず chsh できなかったのでbashを操作していた.
  • 問題を把握.爆買いサイトらしい.
  • Ruby実装ひとつで解く方針だったので,webapp/ruby 以下で git init した.
  • unicornUnixソケットを listen させるようにした.
    • 232点
  • nginxに静的ファイルのキャッシュとgzip配信をさせた(つもりでいた).
    • 実はシンボリックリンクを貼るのに失敗していた.
    • 画像/CSSの数は固定だったので,全部 gzip 圧縮して gzip_static always で配信した.
  • rack-lineprof を入れて様子を見た.GET / がとてつもなく重いし,案の条N+1が埋め込まれている.
    • viewにも埋まっていた.
    • それらはひとまず app.rb に移す(こうしないと rack-lineprof の情報量が少なくなる).
  • 秘伝の sysctl.conf を設定した.
  • 秘伝の my.cnf を設定した.
    • ここで出てくる結合クエリなどに対して効くようにインデックスを貼った.
    • このあたりで16096点
    • 実はこれもちゃんと設定できていなかった.
  • unicornのワーカープロセスを増やしたり減らしたりしていた.
    • そんなに多くなくていい.
  • GET / のページネーションに OFFSET を使わないようにした.
    • このあたりは削除クエリが走らないという前提のもとにけっこうシンプルに書けた.
  • 静的ファイルの open_file_cache を増やした.
    • あまり効いてなさそう.
  • GET / のN+1を完全に解決した.
    • 50570点
    • 調子に乗りはじめる.
  • ベンチマーカのworkload数を増やさなくていいという気づきを得られた.
    • 56867点
  • あらゆる SELECT 文にキャッシュをかけるようにした.
    • 65688点
  • セッション管理に memcached を使うようにした.
  • products.description を必要なぶんだけ取ってくるようにした.
    • 67324点
  • current_user の呼び出しをできるだけ減らした.
    • 82840点
  • このあといろいろやったがあまり伸びなかった…….alpを入れて遅いリクエストがどれか見てみたがあまりよく分からず.
  • unicornをやめてpumaに差し替えた.
    • 88184点
    • これがチームの最高点だった.
  • どうにも伸び悩み,rack-cache というのを導入したが,あまり効いてなさそう.
    • 85402点
    • これが最終得点.
  • 試合終了.1つ上のチームと3万点近く離されてしまい悔しい.

感想

いつもやることをやってから取り組むという方針でやったのである程度の点数は取れたと思う. しかしあと一歩に気づけなかったのがやはり悔しいですね……. これどこに気づいたらあともうちょっと点数伸ばせたんでしょうか?

dstat を見ながらベンチマークの様子を眺めていたけど,今回のマシンはメモリが潤沢で,ずっと余っていたので,もうちょっと活用できないかなーという気はしていたが何もできず. 戦略として「なんでもオンメモリキャッシュに頼らない」というのを心がけるようにしてるんだけど,打つ手がなくなってきてこうなったらぜんぶキャッシュか,しかしロジックが複雑に……といったことを考えてしまいよくない.やはりキャッシュは麻薬.

まだまだ,「こうするとなぜか高速になるらしい」みたいなことが多いので,ちゃんと理解した上でぜんぶ設定できるようになりたい. 1人だとぜんぶ1人で面倒を見ないといけないので,どうしてもわちゃわちゃしたり,気づけないことがあったりするけど,複数人でやると気づきが得られるので,やっぱり複数人は強いですね.

いい問題をありがとうございました.焼肉はまだ遠い.

*1:個人戦だがチーム名が付けられる.