ISUCON8参戦記

今年も同じメンバーでバナナマン -4thの覚醒というチームで[ISUCON](http://isucon.net/archives/51582325.html)に参加してきましたの記録

## 他メンバーの参戦記

- [ISUCON8に参加したのでその雑記](https://qiita.com/yamamoto_hiroya/items/57486fa6928942c77832)

## 事前準備

予選数日前に3人で集まって言語、役割分担と初動を事前相談。

* 言語
    * Ruby
* 役割分担
    * アプリ担当1人
    * インフラ担当1人（自分）
    * ブレイン担当1人（NEW！）
* 初動
    * アプリ担当:ローカル環境構築
    * インフラ担当:ベンチ実行と計測ツールの導入
    * ブレイン担当:アプリの理解とボトルネック探し

前回の反省点として

- 焦って問題分析が足りない状況でのコード修正やアプリ担当2人の内1人が待ち状態になった
    - →状況把握と指示出しをするブレイン役を置いた
- 手元で修正後にデプロイすると動かないが頻発していた
    - →ローカルでアプリケーションを動かす環境構築をしようという作戦
    - →アプリ担当はSinatraの環境構築の素振りをしていた

## 開始直後

レギュレーションを読みつつ初回ベンチ実行。

- 想定内
    - サーバ3台構成（予想通り）
    - プロセス管理はsystemd（予想通り）

- 以下、想定外
    - 3台ともサーバの中身は全部同じ（予想外）
    - Webサーバがh2o（やばい）
    - DBサーバがMariaDB（やばい）
    - 初期設定でベンチが通らない（Rubyに変えたら1024）

<img width="947" alt="first-bench.png" src="https://qiita-image-store.s3.amazonaws.com/0/1823/56972525-a130-6e16-bb63-59c4f8e69469.png">


## 午前中

- nginxの設定が悪さしていたっぽくてCSVのバリデーションエラー（やばい）
- newrelic入れたらDOMのバリデーションにひっかかりベンチ通らない（やばいやばい）
- 午前中スコア0（お通夜）

ベンチが通らないので何が悪いのかもわからない状態。かなり焦る。

## 午後1

- nginxの設定ミスってる可能性を考えh2oに戻す
    - ベンチが通りスコアも2000点台に上昇（まじでごめん）
- ここから自分がデプロイ&ベンチ実行おじさんと化す
- アプリ担当が改善して3000点あたりをウロウロ（15:00頃）

<img width="1210" alt="dark-mode.png" src="https://qiita-image-store.s3.amazonaws.com/0/1823/3d31ab6f-3493-6081-9b77-c03898784596.png">


思うように点数が上がらずこのまま3000点くらいで終わるんじゃ・・・という空気が漂いだす。（この時の空気はやばかった）

## 午後2

インフラ担当として何もできてないので、1台構成だったサーバーを3台構成にしたらなぜか点数が下がり頭を抱える。この他にもmy.cnfやnginxの設定をいじるも効果はでず死にたくなる。

プロセスの起動方法を見てなかったことに気づき、ようやくtorb.rubyを見始めrackupからpumaに変更し、ワーカー数とスレッド数を変更したところ+4000で8000点前後まで上昇。なんとか自尊心を取り戻す。

## 終了直前

終了1時間前までの他チームの点数から予選突破はおそらく30000点台は必要だろうと推測。この時点で最高スコア8000点ほどなので、元々ラスト1時間はコードはなるべくいじらず安定させることに注力しようと話していたが、どうせ失うものはなにもないとぎりぎりまで修正する方針に転換。

結果的にこの判断は正しく、終了10分前くらいにブレイン担当の修正したコードが秘孔をつき15000点台と約2倍に点数が跳ね上がりテンションMAXでフィニッシュ。

<img width="1250" alt="last-score.png" src="https://qiita-image-store.s3.amazonaws.com/0/1823/82b11705-1531-767c-5ac3-c7022d117856.png">
<img width="893" alt="last-graph.png" src="https://qiita-image-store.s3.amazonaws.com/0/1823/a794edf2-ffc8-e110-92b1-3ac5d5ba5190.png">

## やったこと

- アクセスログ解析にalpはとてもよかったがh2oのログフォーマット指定がわからんかった（準備不足）
- mariaDBはほぼMySQL互換で助かった
- 分割したら/initializeでDBサーバ初期化が動かない（手動でdb/init.shを叩く）
    - →MYSQL_HOST環境変数を指定すればいいだけだったっぽい
- torb.rubyの起動コマンドがrackupだったのでpumaに変更
    - →スレッド数とワーカー数を調整してスコアが上がる（よかった）
- RACK_ENV=production指定したけどスコアが下がる（なぜ？）

## よかったこと

- 事前に作戦会議
    - →ローカル環境構築は大当たり（ぴろ++）
    - →ブレーン役配置
- 役割分担明確化
    - ブレーン役がコードの理解に時間を割いて指示（ちゃんまー++）
    - インフラ担当は最後までインフラ周りをいじってた
- 最後の点数アップは実は3人の連携プレー！！
    - →おかしいところ指摘（自分）→別部分の高速化（ぴろ）→ぴろの修正を流用してスコアアップの高速化（ちゃんまー）

## 反省

- nginxでリバースプロキシ
    - →素の状態と段階的に設定追加していくテンプレ用意すべし
    - →後から調べたらただのpermissionの問題だった（ほんとごめん）
        - →nginxの起動ユーザーをisuconにしたがテンプファイルを作成する場所のバーミッションが許可されていなかった
        - →エラー内容は/var/log/error.logに出力されていたので、焦らずログを確認すべし
- WEB1 APP2 DB1 構成にしたかったけどh2oでの設定方法がわからず断念
    - →/etc/hostsでDNSラウンドロビンすればよかったっぽい（きびしい）
- MySQLのチューニングもっとできたかな
    - →環境に合わせてチューニングするための知識をつけるべし
- 今回NewRelicだとベンチが通らなくなってしまったので複数のプロファイルの引き出し用意すべし
    - →netdataとかdstatとかかな
- インフラとアプリの修正を同時に行い問題の切り分けができなかった
    - →アプリの修正とミドルの修正を別サーバで行うべし
- git管理対象をもう一段上の階層でよかった
- 感想戦でWEB+APP,APP,DB構成にしてみたら26000点台まで上昇
    - →自分が仕事してれば30位台まで行けた・・・

<img width="902" alt="after-score.png" src="https://qiita-image-store.s3.amazonaws.com/0/1823/f9b6dd25-b2d2-7619-0730-996fa757958f.png">

## まとめ

今回も（主に私に）課題はたくさん見つかったが、年に一度のエンジニアの天下一武闘会としてとても楽しかった。と同時にできることがまだまだあったので悔しい。知らないこと・足りないことがよくわかる。

過去最高順位（全体64位）までこれたのはこれまでの経験から改善策を打てたことと、チームメイトの力によるところが大きかったので、これに満足せずに次回があればぜひ参加したいと思う。

<img width="631" alt="ranking.png" src="https://qiita-image-store.s3.amazonaws.com/0/1823/c3feb7b6-e55f-638f-b351-8d706ea6c288.png">

## リポジトリ

https://github.com/asflash8/isucon8q