私が歌川です

@utgwkk が書いている

pixiv社内ISUCONを解いた

チーム 😇 (:innocent:) でISUCONの練習ということで,pixiv社内ISUCONを解いた.使用言語は Ruby で,最終得点は94943点.

inside.pixiv.net

ネタバレが多く含まれるので続きを読むにします.

リポジトリはこれです.実際の問題と同じくサーバは c4.large,ベンチマーカは c4.xlarge に設定しました.もうインスタンスは削除したので破産しません.

github.com

やったこと

  • EC2インスタンスを立てた
    • ほんとうは ConoHa VPS を借りて ansible 流し込めばいいかなーと思っていたが,うまく適用できなかったので AMI を使った.
  • DBスキーマを書き出した
  • unicorn にUnixソケットをリッスンさせた
  • MySQL への接続にUnixソケットを使った
  • 静的ファイルを nginx でキャッシュするようにした
    • ここで /image/:id.:ext がDBからバイナリを取り出して返していることに気づく.マジで……
  • try_login で余計なカラムを取らないようにした
    • このあたりで id を取っていないせいでベンチマーカが panic で落ちることに悩まされた.
  • make_posts のN+1問題を (comment 以外) 解決した
  • nginxの worker_connections を増やしたり,epoll を使うように明示的に設定したりした
  • MySQL のチューニングをした
  • そろそろ画像をDBに入れてるのどうにかしたいなーと思い,まず画像をファイルに書き出した
  • アップロード時に画像をファイルに保存するようにした
  • アップロードされた画像を nginx から配信するようにした
    • このあたりで13699点
  • スロークエリを見せてもらい, / でテーブルをフルスキャンしてることに気づいた
  • ページごとの枚数制限などを全部 make_posts に移譲してて,最悪……
  • SHA512ハッシュを取るのに外部コマンドを叩いていた(!?)ので Ruby のライブラリを使うようにした
  • COUNT(*) が遅いのでインデックスを貼った
    • これ以外にもいろいろ貼った
    • スキーマも保存しておけばよかったですね
  • このあたりで Too many open files に悩まされる
    • @wass80 に上限を上げてもらった
  • / のテーブルフルスキャンしてるクエリを修正した
    • このあたりで39407点
  • アップロードされた画像をgzip圧縮して配信するようにした
    • 点数が3倍近くになった(!!!)

まとめ

このようなことを朝10時から18時ぐらいまでやって,最終得点は94943点だった.かなりよくできたと思っている. 画像配信サービスなので gzip 圧縮必要かなと思ってやってみたところ点数がかなり上がったので,最後までしっかり考察して手を動かすべきですね. あとは朝起きるなどの技術が必要.

AMIが公開されているのでシュッとインスタンス立てられて便利ですね.1日ぐらいならそんなにお金もかからないのでよさそう*1

ところでこれは私見ですが,ISUCONの練習は手元のマシンでやるよりもAWSとかGCPとか,なんでもいいのでインスタンスを借りてその上でやるのがいいと思う. マシンスペックは保証されてるし,AMIなどのテンプレートが公開されているのでやりやすい. 練習に使うようなインスタンスは1日動かすぐらいではそんなに課金されない*2ので,学生でも手を出しやすいと思う*3

*1:クーポン欲しい.

*2:今回使ったインスタンスは2つで,8時間ほど動かしたが,それでも3USDぐらいだった.

*3:カードがあれば,の話だが.