第2回 社内ISUCONに参加した話
宮地克弥
こんにちは。新卒入社してもうすぐ1年、リクルートテクノロジーズの宮地です。ハンターランクはまだ41です。
ちょっと前になるのですが、12月頭に社内ISUCONが開催され、参加したので感想と何をやったのかを書いていきたいと思います。
参加チームは前回社内ISUCONに参加した話 | リクルートテクノロジーズ メンバーズブログと同様にisucon_friendsとして古川さん、與那城さんと参加しました。
ISUCONとは
Iikanjini Speed Up Contestの略です。本家はこちら
3人一組のチーム対抗戦で、お題となるwebサービスをレギュレーションの範囲内で限界まで高速化を図るチューニングバトルです。
今回のお題と当日の流れの説明
前回はpixivさんが公開されているpixiv-isuconがお題として出題されましたが、今回はYahoo! JAPANさんが提供しているy-isuconをお借り致しました。
Yahoo! JAPANさんで開催された時は1週間と長期戦でしたが、今回は1泊2日の合宿形式による短期決戦で開催されました。
合宿の会場はマホロバ・マインズ三浦を利用させて頂きました。
当日のレギュレーション
当日のレギュレーションは以下になります。
* お題に関するレギュレーションは y-isucon
のレギュレーションに準拠
* 競技時間は12/8(金)10:00~12/9(土)13:00まで
* スコアは最高得点のものを利用
何をやったか
僕は第1回も参加しているのですが、基本的は変わらず「推測するな、計測せよ」を守る形で進めていました。
ただ前回の反省を踏まえて、効果が見込めるのが自明な部分は先に済ませることにしました(内部通信をunix domain socketにする等)
分担
- 古川さん: 問題の特定、方針を出す
- 宮地: ミドルウェア,OSの設定と調整
- 與那城さん: アプリケーションの改修
以前と同じ体制で挑みました。ここからの話は僕目線での話になるので、主にMWやOS周り中心に書いてきます。
昼飯
腹が減っては戦が出来ぬということで、今回のisuconは昼飯からスタートしました。
この頃はまだ競技が始まっていなかったため、どういう問題が出るんだろうという話で盛り上がっていた覚えがあります。
初動
お昼も食べ終わり、部屋に戻ってから競技開始です!
初動も以前と同じで計測等の環境構築と全体の方針決めを行いました。
やったこと
- コードをgit管理する
- kataribeにてendpointごとのプロファイリング準備
- netdataによるOSリソースの取得と可視化
- pt-querydigestによるmariadbのSQLのプロファイリング準備
- deployと計測準備用のscriptを配置等々
ここで設定したログを確認しボトルネックの調査→次に手を付けることを決める という流れで進めていきました。
序盤(開始〜晩飯まで)
同じ会議室に居ては他チームに作戦がバレてしまうというのもあり、ここから各チーム自室に移動しました。
やったこと
- Node.jsからGoに切り替え
- webアプリが2つのバイナリで構成されていたものを一つに纏める
- 内部通信をunix domain socketに変更
- indexを張る
- favicon.icoが404になっていたので適当に設定
- sessionをRedisに持たせる
- MariaDBをアップデートしてFullTextインデックスを貼る
- 静的コンテンツをクライアントにcacheさせる
- DBの設定チューニング
この辺は今までのisucon参加の経験を元に、やれそうなところはガンガン進めていきました。
序盤終了時のスコア
ISUCONに慣れてきたというのもあり、早めにテンプレート的な対応が出来たので、頭ひとつ飛び抜けた点数を取ることが出来ました。
晩飯タイム
ここで一旦晩飯タイムです。和食のコース料理が出てきたということしか覚えていません。
この時点でどこまでやって点数を伸ばしたかの探り合いと、それっぽいキーワードを出しつつ次どんなチューニング進めるかの心理戦をひたすらしていました。
この時点で僕らのチームは一位だったので鼻高々に、『あの辺を調べるとヒント見つかるかもね〜』と言ってた記憶があります。このあとすぐ抜かれるとも知らずに…
中盤(晩飯〜寝るまで)
晩御飯を食べ終わってすぐに他チームが点数を伸ばしてきて、 悠長にAmazon Prime Dayを横目にやる余裕が無くなってきました。
やったこと
- RDBの中身を全部Webアプリケーション上のメモリに載せる
- varnishを挟んでHTMLをキャッシュさせる
ここを解決したら大きく点数が伸びるというのはポイントは分かっていたのですが、良い解決策がパッと見つからず悩んだ結果、アプリの大規模改修(全データインメモリ戦略)をする作戦に移行しました。
こちらの改修は與那城くんと古川さんに任せ、自分はそれ以外のところで何かできないか考え、varnishによるHTMLキャッシュや、もし時間内に改修が終わらなかった場合の全文検索のためのelasticsearchの導入検証を行ったりしていました。
中盤終了時のスコア
大規模改修をしていたため、点数も変動がほぼない中、徐々に他チームは点差を広げていっていました。
この時間が一番つらかった
終盤(起きる〜競技終了前まで)
やったこと
- セッションキャッシュもWebアプリケーションで持つ
- OSの設定チューニングを行う
- tcpのlife cycleを短くする
- エフェメラルポートの利用範囲を広げる
- 利用できるファイルディスクリプタ数を上げる
- 等など
- 各種ログの出力をOFFにする
- 使ってないMWは全部止める
- GoのTemplateエンジンをやめてコードに埋め込む
- GOのGCをOFFにする(ダメ絶対
ここから先はスコアも非公開になり、競技も終盤です。
與那城君が見事アプリ改修を終え、僕も時を同じくダウン(4時頃?)してました。10時頃に起きたら、僕らが寝てる間に古川さんがセッションもwebアプリ内にインメモリで持つ改修を行ってくれました。
その後、最後の追い込みをしていたところOSの設定チューニングをするのを忘れていたことに気づき、あわてて設定したら点数が思いっきり跳ね上がりました。
残りのやれることをやっていく中で、benchmark中に明らかにFull GCが走ってると思われるスパイクが何度か発生しているのを見つけました。全部インメモリにしてもそんなにメモリを喰っていなかった&インスタンスサイズもそこそこ大きかったので、GC切っても問題ないだろう。ということで試しに切ってbenchmarkを回してみた所、見事にメモリもswapも食い潰してリモートからは一切作業ができない状態が誕生し、僕らのisuconはここで終わってしまいました・・・。
結果
最高得点は 149415点で、なんとか優勝することが出来ました!!!!
最初の滑り出しは良かったものの、中盤以降ずっと伸び悩んでおり正直負けたと思っていましたが、残り2時間を切ってから行ったことで大きく点数を伸ばすことができました。
ちなみにGC切って死んだのは競技終了15分前だったので、そこまで大きな影響はありませんでした(15分前でホントに良かった)
運営のみなさまも短い期間で準備して頂きホントにありがとうございました!!
良かった点
前回、効果が出ることが分かっていたけど後回しにしていた(そこがボトルネックになってから対応する予定だった)ところから手を付けたり、「推測するな、計測せよ」を守りながら進められたことで見当違いな対応はほとんどせずに進められたのはとても良かったと感じました。
また、だいぶ進め方にも慣れてきて、問題以外のところ(主に初動の部分)でつまずくことが無かったため、問題に集中することが出来たのも大きかったです。
反省点
チームというより個人的な反省ですが、中盤以降に伸び悩んでいたタイミングで僕がもっとアプリ側に参加出来たり,RDB周りでもっと積極的にテーブル構成の変更ができていれば、もっと色々な検証が出来たなと感じました。
あとこれはisuconあるあるだと思うのですが、シングル構成だと競技が進むに連れてアプリ内にデータを持つことが増え、MWを使わなくなるようになっていきます(今回で言えばmariadbとredisをほぼ捨てた)。そうなった時にインフラ側からスコアを伸ばすための引き出しをもっと増やしておくべきだなと感じました。今回はvarnishを使ってhtmlキャッシュを行ったりしましたが、更新が多いページだとキャッシュパージだったりでCPUを大きく使ってしまう為、思ったほどスコアは伸びなかった印象でした。
また、2位のチームは人間的な生活(普通の時間に寝て朝風呂,飯を食べていた)をし、アプリの改修も運用できるレベルのものだったため、勝負には勝ったけど少し負けた気分になりました。。
次回の話
次回はリクルートテクノロジーズだけではなく、他のリクルートグループの方々も集まり過去最大の規模での開催が決定しました!
本家ISUCONに習い、次のISUCONは僕らのチームで作問と運営をします!
果たして残り短い期間で準備が終わり、無事開催できるのか。乞うご期待ください!