ISUCON8 に初参加してみました

いろんな方の感想blogは開催されるたびに読んでたのですが、自身は1度も参加したことはありませんでした。

今回、たまたまお声がけいただいて、「†漆黒のすぐちむ†」というチームで初参加してみました。
結果的には、2日目トップで予選突破できましたが、メンバーのお二人(漆黒の石川さん、四国の中陳さん)のコード改修が素晴らしすぎて、ほとんどの時間がdstat眺めながらDB死にそうwって言ってた記憶しかないです・・・。

役割としては、いわゆるインフラ部分の面倒を見る係です。
その視点で、やったこと、できなかったことを思い返してみます。

ちなみに最終的な構成は次のようになりました。
1号機(isu8-1)：h2oとphp-fpm同居 (ベンチマーカーのターゲットサーバ)
2号機(isu8-2)：MariaDB
3号機(isu8-3)：未使用
ミドルウェアは全て与えられたものを使っています。

アプリケーション側はチームメンバーが詳しい記事を書いていますので、ぜひご覧ください！
https://qiita.com/YasunoriISHIKAWA/items/43357601504176491dae
https://qiita.com/jinjin1/items/e6166754e9c2e418691a

## 事前準備
- OS は CentOS の予定と告知されていたのですが、さすがに6系は来ないだろうと思って、CentOS7と予想。
 - まだまだ sysvinit が体に染み付いてしまっているので、systemd の操作をスムーズにできるようにカンペ作成。
- 多分使うだろうツールのインストール方法とか確認してカンペ作成。
 - htop sysstat dstat tcpdump percona-toolkit とかとかのインストール方法の確認
 - ググるとalpというツールがよく使われているので、そのインストール方法と使い方確認
- 役割的に全員の公開鍵をもらってサーバに登録する予定だったので、その手順確認
 - 当たり前の作業でそうそうミスらないのですが、やっぱり競技開始直後とかって緊張するだろうから準備しました。 


あと、初参加なので一応去年の問題は解いてみて、なんとなくの感覚だけはつかんでおきました。

## 当日

### 開始前
- 無事開始時間前に全員集合
- コミュニケーションチャネルの確認（discordだと誤爆怖いし、チャットワークでやろうとか）
- 二人の公開鍵回収


### 開始〜1時間くらい

#### ログイン方法の確認と、鍵登録
 * ポータルにログインして、サーバのIPアドレスとパスワードを確認
 * 自分がサーバにログインし、全員分の鍵をauthorized_keysに書く
 * 2人に .ssh/config 形式で設定を配って、鍵でログインできることを確認してもらう
 
```
Host isu8-*
    User        isucon
    StrictHostKeyChecking no
    UserKnownHostsFile=/dev/null
    LogLevel ERROR

Host isu8-1
    HostName     x.x.x.x

Host isu8-2
    HostName     x.x.x.x

Host isu8-3
    HostName     x.x.x.x
```

#### レギュレーション確認

 * 点数配分の確認とか
 * 過去のblogとか見てると、レギュレーションの勘違いとか、きちんと把握てきていないケースとかが見られたので、なんとなく重要そうなところは意識的に **声に出して読み上げました。** 

#### 環境の確認
 * CPU -> 2cores
 * memory ->1G
 * swap -> 2G 
 * diskサイズ -> 50G
 * 今回サーバが3台与えられたのですが、それらにスペック上差異がないことを確認
 * ネットワーク
  * グローバル側：50M
  * インターナル(サーバ間通信)：1G
  * インターナル(ベンチマーカー)：1G ←実はこれに最初気が付いていなくて、だいぶ後から気がつきました、ベンチマーカーと対象サーバの線は充分太い。
 * レギュレーションの情報と合わせて、今回与えられた環境をホワイトボードに書いてくれました（石川さん
 
#### ミドルウェアの確認
 * h2o
  * まじか、nginxじゃないのか
 * php-fpm
  * 7.2 新しい
 * MariaDB
  * 5.5 CentOS7ですし

#### 最低限ツールをインストール

* 確かこんな感じ

```
yum install epel-release
yum install wget telnet htop sysstat dstat tcpdump
yum install http://www.percona.com/downloads/percona-release/redhat/0.1-6/percona-release-0.1-6.noarch.rpm
yum install percona-toolkit
```

#### ベンチ
* 説明に書かれた方法で php-fpm が立ち上がるように設定
* ベンチかけつつ dstat -f を眺める
* このタイミングで h2o のログに応答時間を足したのと、DBのslowlogを出した。
* mariadbのプロセスがCPUを全力で使っているのがわかる
* slowlog 出すぎ


### その後、終了1.5時間前まで

アプリケーション側でひどい実装やクエリがいくつかあって直すような流れだったので、その辺は二人にお任せしました。
逆に、設定変更や再起動など、サーバ、ミドルウェアの諸々のオペレーションは全て自分がやりました。

基本的には何かボトルネックになっているか(いずれボトルネックになりそうか)を確認しつつ、設定変えたり構成変えたりを繰り返しました。

* (やった) /etc/security/limits.conf を修正

```
* soft nofile 4096
* hard nofile 4096
```

* (やった) php-fpm のプロセス数を様子見つつ上げていく
 * その時点のボトルネック次第で変動しそうではあるが、ベンチを取りつつ適正値を探った
 * 最終的には16くらいにした気がする
* (やった) php-fpm のsystemd の設定で以下を追加

```
[Service]
LimitNOFILE=1006500
LimitNPROC=1006500
```
* (やった) php-fpm で xdebug のモジュールが読まれていたので外した。
* (やった) MariaDBの設定を見直し
 * データ量が大したことないので意味はないかもしれないけど、いくつかは見切りで設定し、パフォーマンスが落ちなければそのままにしました。

```
innodb_buffer_pool_size=512M
innodb_flush_method=O_DIRECT
innodb_flush_log_at_trx_commit=2
innodb_file_per_table=1
max_connections = 3000

#slow_query_log                = 1
#slow_query_log_file           = /var/lib/mysql/mysqld-slow.log
#long_query_time               = 0.1
#log-queries-not-using-indexes = 1

query_cache_limit=16M
query_cache_size=128M
query_cache_type=1
```

* (やった) 午後のどこかのタイミングで、「今でもDB負荷きついし、これはDB分けたほうがいいね」的な流れになって、DBを別サーバに分けました。
* (やった)１号機と同居していたMariaDBは自動起動しないようにしました。

* (できなかった) h2o を nginx に変更
 * 動作はしたものの、ベンチマークの最後の方で /admin/*** の特定のpathでCSVをdownloadさせるところでこけるようになってしまい、理由が全然わからず諦めました。
* (できなかった) Maria5.5->MySQL8
 * わからんすぎて断念
* (できなかった) Maria5.5->MySQL5.7
 * 入れ替えて、ベンチマークがfailになったので調べもせず断念(もしかしたらSQL_MODEとか)
* (できなかった) プロファイラツールの blackfire を入れる
　* 入れたけど、結果がweb上に表示されるところまで持っていけなかった


### 終了1.5時間前から終了まで

とにかく再起動試験をクリアすること、しょうもないミスで失格にならないことに専念しました

  * 終了30分前にはもう作業終了にしますと宣言
  * 自動起動の設定の確認
  * 結果的に不要になったプロセスが起動しないように設定と確認
  * ログ出力オフ
  * rebootして想定した状態になっているか確認
  * reboot後一切サーバ内で作業を行わずベンチマークが複数回通ることを確認
  * 最後余った時間でscoreガチャして、いい感じのスコア出たとこで作業終了
 
## 感想

結局インフラ視点では大したことはできず、アプケーション側のお二人がメチャがんばるみたいな感じになってしまって、申し訳ない感いっぱいです。
ミドルウェアの変更みたいな大掛かりなことだけでなく、h2oのログフォーマットを alp で読める形式で出すとか、pt-query-digest の結果をわかりやすく伝えるとか、そんな初歩的なことすらできていませんでした。

とはいえ、反省点や、もっとこうすればよかった、これ知ってればよかった、がたくさん見つかったのは今後のプラスになると思うので、 **きちんと復習**  して本戦ではもう少しいい働きができるように頑張ろうと思います。


いじょうです！