MPがありません。

$liiu->mp == 0

ISUCON10予選に参加してきました

isucon10予選に会社の同期とひとはというチームで参加しました。
最終的にスコアは 1479 で、順位は68位くらいだったようです。

事前準備

New Relic が無料で使えるので使いたいよね、という話をしていて事前にチームで集まってNew Relicを触っていたりしました。
最初は言語をみんなが書けるPerlでやろうという話をしていたのですが、New RelicをPerlで使うのはかなり大変だったので途中からちゃんと動くnodejsでやる方針になりました。

また、当日の段取りはチームメンバーがある程度考えてくれていました。

やったこと

deployスクリプトの作成

  • まず3台配られた各サーバーのNginx, MySQLの設定をコピーしてきてレポジトリに追加しました
  • デプロイスクリプトは次のような内容になりました
    1. git pull してくる
    2. 変更をもとに戻しやすいようにブランチも指定できるようにする
    3. 各サーバのNginx, MySQLの設定を cp -rf で上書き
    4. npm ci を実行
      • この日初めて知ったのですが、npm install と違い package-lock.json を更新しないので本番とかCIの場合はこちらを使うほうがいいとのことだった
    5. nodejsで動いているWebアプリ、Nginx, MySQLのサービスをrestartする
  • デプロイするときは各サーバでそれぞれこのスクリプトを実行するという運用にしていました
  • ある程度デプロイを自動化したことにより簡単に変更を反映できるようになりました
    • Ansible や etckeeper を利用すればもっと早くデプロイの自動化ができそうだったので試してみたいと思います

searchの改善

  • まず件数をcountしているところのクエリ発行を消せそうとなりましたが、消せませんでした
  • その後はベンチのときのアクセスログを解析して、どのパラメータがよく使われているかを調べていました
    • MySQLはインデックスが1つしか使われないので、1番よく使われるパラメータに対応するカラムにインデックスを貼るとスコアが上がると考えて貼ってみましたが、気づいたらチームメンバーが既に貼っていました
    • 後日講評を読んだところ、searchで使われるカラム全部にインデックス貼って良かったようでした
  • そもそもアクセスログより先にslow query logをまず見るべきでした

考えていたこと

自分がやっていたことは上記2つくらいで、あとは次のようなことを考えていたりしていたと思います。

  • APIにリクエスト投げてちゃんと動作しているか確認するスクリプトがあれば捗るのでは?と考えていた
    • search系のAPIのパラメータが多くて、その辺り網羅しないとあまり意味がなさそうだったので結局やらず
  • データをメモリに乗せればスコアが伸びるのでは?
    • 考えついたのが終了1時間前くらいだったので何もできず・・・

チームでやったこと

スコアの伸びに繋がったことのみです

searchの改善

estate.rentchair.price にインデックスを貼って、少しスコアが伸びました。

nazoteの改善

MySQLの空間インデックスを使うように変更を入れました。

複数台構成にする

1台ロードバランシングさせて3台全部をアプリケーションサーバにしました。
2台構成にした時点ではそこそこスコアが増えたのですが、3台構成にしてもあまり変化はありませんでした。

振り返り

事前準備していたことや経験値が増えたこともあって、前回参加した2年前よりどう動けばいいのかがわかってきた感じはありました。
しかしまだまだきちんと動けていないところやMySQLの理解が足りないと感じるところがあったので、精進しないとなあという感じです。
ボトルネックを解消しようとする前にきちんとメトリクスを計測してプロファイラやslow query logを見てから手をつけるということを肝に命じようと思います。