「チームLGTM☆」予選ぎりぎりの12位で突破しました!
前日にウォンテッドリーの内定者のチームが1日目3位で通過という話を聞き(学生なのに社会人の枠を一つ潰し)、プレッシャーがかかる中で、内定者にスコア的には負けましたが、決勝でリベンジするチャンスは残りました。
チームメンバーは、 @south37 と @ngtk で、初めて組むチームでした。僕は、前のチームで出た時も、isucon5もisucon6も予選突破(のスコアは出していましたが、isucon6は再起動失敗による失格。。)だったので、二人にノウハウを伝えつつ、予選に挑みました。
前日までの準備
準備はまず過去のノウハウの共有をしました。
https://github.com/reikubonaga/isucon7-qualifier/issues/2
環境構築・公開鍵の設定・nginx・mysql・redis・マシンスペックの確認方法など
次に役割分担をし、3回練習をしました。isucon6予選・isucon6決勝・pixiv isucon。特に最初の3時間をしっかり行う練習をしていました。
@south37 がサーバーの設定をスムーズに行うためのレポジトリを準備 https://github.com/south37/isucon-settings
・deployやログの書き出しなどの方法をドキュメント化までしてくれてました。 https://github.com/south37/isucon-settings/tree/master/tmpl
最初の30分
・インフラ担当 @south37
・sshのpublic keyの配置
・nginxにkataribe用のログ出力を設定しベンチを実行
・gihubにソース管理
・deploy/サーバーlog監視/nginxのログの出力用のスクリプトの配置
・各サーバーのリソースの確認
・アプリ担当 @ngtk
・mysqlのスキーマ確認
・データベースの容量の確認 https://github.com/reikubonaga/isucon7-qualifier/issues/4
・ローカルにダンプをコピーし、ローカルの開発環境整備
・アプリ担当 @reikubonaga
・実際のサービスの挙動を確認
・問題理解とソースコードの解説 https://github.com/reikubonaga/isucon7-qualifier/issues/5
・kataribe.tomlを追加 https://github.com/reikubonaga/isucon7-qualifier/pull/9
方針相談
・初回のベンチ ( https://github.com/reikubonaga/isucon7-qualifier/issues/6#issue-267434731 )を走らせました。
・ベンチの結果は、予想通りiconの処理に時間がかかっており、次がfetchやmessageのn+1の問題、アセットの配信をrubyで行なっていることでした。
・また今回は予選から3台のサーバーがあったので、構成をどうするかを話しました。
・データ量がimageを除くと10MBを切るので、データはキャッシュさせる。
・画像の配信は1箇所から行うために画像配信のサーバーを用意。
・リソースを最大限活用するために3台ともwebサーバーを立て、リソース状況によって負荷を分ける
・web1: nginx, (image配信), ruby / web2: redis, ruby / web3: mysql, ruby
ボトルネックの解消
・画像配信
・DBから画像を生成し、アップロード https://github.com/reikubonaga/isucon7-qualifier/pull/10
・保存先を変更し、nginxの設定も変更 https://github.com/reikubonaga/isucon7-qualifier/pull/12
・画像にタイムスタンプをつけてキャッシュを有効に https://github.com/reikubonaga/isucon7-qualifier/pull/16
・Web1だけに画像関連のリクエストが届け、web2/web3も利用するように https://github.com/reikubonaga/isucon7-qualifier/pull/17
・DBのキャッシュとn+1の解消
・haveread https://github.com/reikubonaga/isucon7-qualifier/pull/13
・channel https://github.com/reikubonaga/isucon7-qualifier/pull/14
・user https://github.com/reikubonaga/isucon7-qualifier/pull/18
・message https://github.com/reikubonaga/isucon7-qualifier/pull/21
開始から5時間で上記の変更を行い、スコアは13万に。 https://github.com/reikubonaga/isucon7-qualifier/issues/6#issue-267434731
3台のサーバーのチューニング
アプリケーションのコード改善はひと段落し、ボトルネックがダントツでiconの配信という状態に。
サーバーの負荷を見ているとCPUリソースが空いているので、pumaのスレッド数のチューニングをすることに。
実行の度にスコアが20%程度変動しており、何か変更しても良くなっているかどうかが分からなくなる中、残り時間1時間半で228000というスコアが出た。 https://github.com/reikubonaga/isucon7-qualifier/issues/6#issuecomment-338467109
この時点で6位のスコアでした。
最後の1時間
同じ条件でも14万-18万のスコアを出すようになり、20万点が出ず。他のチームの点数が見えなくなる中、とりあえず、22万点に戻ればストップすることに。ラスト20分で21万点に戻り、これ以上続けても再度20万点以上が出るか分からなかったので、ストップ。
作業中の様子
インフラの様子は大画面で見えるようにし、アプリエンジニアは二人並んで開発しました。
振り返り
前日にpixivの問題をしていたこともあり、画像の処理がスムーズに進みました。また、 @south37 が準備していたサーバースクリプトがしっかりしていたのでオペレーションを全て任せることができ、また3台のリソースを使い切ることができました。
残り3時間正直改善することが思いつかず、点数がこれ以上伸びなくなってしまい、予選ギリギリと予選余裕の差は大きいなと改めて痛感。
予選からサーバー3台構成で考えるのは楽しめました。isucon運営者の方ありがとうございました。