R-ISUCON 2018 Winterレポート/ 「準備」と「計測」ーー基本を重視するものがISUCONを制す?
鷲見 佳絵
こんにちは。広報の鷲見です。
リクルートテクノロジーズでは、エンジニア・マーケターが自分たちの技術力研鑽や情報共有のためにたくさんの勉強会やイベントを自主的に開催しています。
その中でも、グループ横断で参加者を募り、大規模に行われているのが「ISUCON」。
春に引き続き、三浦のマホロバマインズを舞台に、19チームによって1泊二日の熱い戦いが繰り広げられました。
今回は、日ごろからお世話になっているライターの高橋 睦美さんによる現場潜入レポートをお届けします!
(written By Mutsumi Takahashi)
「リクルートならではの問題」でチューニングを競う
前回の開催から半年余、リクルートグループ横断のISUCON、「R-ISUCON 2018 Winter」が12月7日、8日の2日間にかけて開催されました。師走の忙しい時期にもかかわらず多数のエンジニアが三浦半島に集結。リモート参加組も交え、19組が丸一日かけてこれまで磨いてきたスキルを生かしてシステムのチューニングに取り組みました。
ご存じの方も多いでしょうが、ISUCONとは「Iikanjini Speed Up Contest」の略称です。システムをいい感じにチューニングし、パフォーマンスを発揮させるーーエンジニアなら普段から携わっているタスクでしょうが、その多くは、フロントエンド、あるいはデータベース、もしくはOS周りといった具合に得意分野での作業にとどまりがちで、あらゆるレイヤにまたがって全体として最適化を行う機会はそうありません。プロダクトが大きく成長し、支えるシステムが複雑化しているならばなおさらです。
その点ISUCONは、小規模かつチューニングの余地が多大にある環境でエンジニアが持てる武器をフル活用できる総合格闘技と表現できるでしょう。自分の得意とする分野はもちろん、普段あまり触れることのない部分まで含めてどのようにモニタリングし、最適化していくかが問われます。本家ISUCONを通じてこの醍醐味を感じてか、最近ではリクルート以外にも、社内・グループ内ISUCONを開催し、エンジニアのスキルやモチベーションアップにつなげる試みが広がってきたようです。
R-ISUCON運営チームの古川陽介さんらが意識しているのは「リクルートならではの問題」です。
「本家ISUCONのシステムも複雑化していますが、僕らは、リクルートで作っているサービスで『やってしまう系』の問題を作ることにこだわってます。だから前回はN+1問題を取り上げましたし、今回の問題もそれを意識しています。実はここ数年、リアルタイム系のサービスでナーバスな実装を目にすることが増えています。WebSocketを用いたリアルタイムアプリケーションが増えている中、どうすれば効率的な実装ができるのかを考え、問題に落とし込んでみました」(古川さん)
ということで、今回のチューニング対象はWebSocketを活用して作られた「RINE」というチャットアプリケーションです。何でもストリーミングで送ったりするけれど、本当にそれは必要なのか。全員に送る必要はあるのか、既読処理はどうするか……といった事柄が問われます。
前回のR-ISUCONの情報を耳にして、「これなら俺たちの力も発揮できそうだ」と考えたフロントエンドエンジニアで構成されたチームもありましたが、想定とはちょっと異なるこの問題に面食らったようです。
もう1つ大きな変化があります。これまでチューニングの対象は1台でしたが、今回はAWS上に3台一組の環境が用意されました。スコア自体は1台当たりのパフォーマンスで判定されますが、例えばWebとデータベースを分けて分散処理させて性能を出せば、その分記録は伸びる形です。逆に1台ならば、データベースの情報を全部メモリに載せてしまうといったチューニング方法がとれますが、3台に分散した環境でどのように必要な情報をペナルティなく共有させるか……といったアーキテクチャの最適化も考えなくてはなりません。
今までの過去問と違う? 熾烈なハイスコア争いを展開
競技は7日、15時を少し回ったところでスタートしました。
早速、持参のホワイトボードなどを用いて、「三台一気に手をつけちゃおうか?」「テーブルは分散させた方がいいかな」「フロントエンドで負荷分散させるといいかもしれないけど、その場合、遅延でペナルティが発生するかもしれないし……」といった具合に、各チームが思い思いに作戦会議を展開。渡された鍵を手に早速部屋に引きこもるチームも少なくありませんでした。
あとはひたすら、各チームとも黙々と作業に取り組みます。リアルな口数こそ少なかったものの、もしSlackのログが見れたらさまざまな意見が交わされていたに違いありません。
そんなこんなで夜を迎え、前半戦(1日目)でトップに立ったのは、【ぴぎこん】。とはいえ、この時点での順位は仮のものと考えていたようで「僕らはあれこれ手当たり次第試しているだけで、もっと戦略的に考える他のチームが伸びてくるのでは」と、夕食もそこそこに、宴会場内であれこれチューニングに取り組んでいました。
第3回でもそうでしたが、宴会場に数十人の男性が集まっているというのに、食事もビールもそこそこに作業の続きに入るチームがほとんど。深夜まで夢中になってチャレンジしていたチームもあったそうです。チーム【俺マジでマホロバは行けないからね!】の石井潤さんは、「睡眠不足で2日目は頭が働きませんでした。やっぱり休憩は大事です!」と振り返っていました。
さて、今回のR-ISUCONでは、前回に比べるとスコアの絶対値はそれほど大きくありませんでした。8日朝の時点でもハイスコアは4000点台を伺う程度でしたが、逆に言えばそれだけ接戦が繰り広げられたということ。しかも、競技時間全体を通して出された最大スコアを競うのではなく、最後にベンチマークを回して記録されたスコアを競うレギュレーションとなったため、一度は高いスコアを叩き出しても次のチャレンジでは0点に戻ってしまったりで、切り戻しのテクニックも要求されたようです。
それでも2日目のお昼を回る頃には10万点、11万点を記録するチームが登場し、会場に「ざわ……ざわ……」とどよめきが走っていました。
こうして15時過ぎ、競技は終了。やはりWebSocketに手こずったチームが多かったようですが、そんな中でも、チーム【優しさ駆動開発】のように「アウェイ感はあったけれど、フロントエンドエンジニアとして爪痕は残せたかな」と充実感を漏らす参加者もありました。
複数台処理やSQLのN+1問題処理がチューニングポイントに
さて、いよいよ種明かし。古川さんの説明によると、主なチューニングポイントは3つありました。1つ目はデータベースの/groupsの処理です。前回のISUCON同様典型的な「N+1問題」で、多くのチームがjoinでひとまとめにするなど処理の高速化に取り組んでいました。2つ目は今回の主なテーマでもあるWebSocketで、「既読のステータスを意味もなく全員に送ったりと、『WebSocketでイベントを送りすぎるよね問題』を用意しました」(古川さん)。そして3つ目は、メモリが1GBしかなくてスワップ領域が足りなくなる問題でしたが、こちらは「想定していないワナでした」とのことです。
出題者の意図を読み取ってか、早速複数台に処理を振り分けるチームも目立ったようです。「点数が跳ね上がったチームにどんなことをしたかSlackで尋ねてみたら、早い段階で3台構成に変更したチームが多かったです」(古川さん)
そしていよいよ結果発表。「最初の夜はひたすらバグ報告を行うテスターをやっていて、最後の1時間になってやっとISUCONのやり方が分かった」と述べていた【CS-CORT】、1台のインスタンスで2万9000点を超えるスコアを記録して5位に食い込んだ【あの日みたギャルの名前はまだ僕たちは知らない】といったユニークなチームもありました。
3位は、前回のR-ISUCONでは2位に入った【あとで決めます】。「NodeとJava、好きな方の実装をいじりつつ、点数の伸びがいい方を選んでJavaにした」とのことで、インスタンスもMySQLとRedis、それ以外の3台構成で役割を割り振る形で点数を伸ばしました。
熾烈だったのが1位、2位の争いでした。2位はリモート参加の【すか2】。実装はGoを選んで、最初はSQL周りをガンガン直していったとのこと。「これでそこそこ点数は上がったけれど、次にどうしようかとソースを見ていたらbelongsUserGroupsとReadAtというのが見つかり、その2つを全部Redisにぶっ込んだ」とのことです。
最終的に優勝を飾ったのは【ふんばり温泉チーム】で、11万2511点を記録しました。現実の運用さながらに、プロファイリング・計測の仕組みを用意し、「どこがサチっているか」を把握した上で、優先順位を付けながらチューニングを進めていったそうです。
ポイントの1つが、他チームも目をつけていた/groupsの処理ですが、joinでクエリを結合して頑張ってみても思ったほど高速化できなかったため、テーブルを1つにしてデータを非正規化するという選択肢を採用しました。「普段のサービス運用で同じような問題に遭遇することもあるけれど、毎回非正規化をしているわけではありません。いろいろな対処法が考えられますが、『周りの制約によって最適な対応策は変わる』ことを普段の業務で学んでいたため、今回の問題では自信を持って非正規化を選択できました」と振り返っています。
実は、2位の【すか2】とは僅差……というか、実は、【すか2】が一時12万点越えを果たして最高スコアを記録したのですが、その後ベンチマークを回したら下がってしまいました。逆に【ふんばり温泉チーム】は10万点を超えたあたりから「何かあったらすぐrevertして戻すということをやっていた」上、最後はあえてベンチマークを回さず、PCを閉じて他チームの結果待ちモードに入っていました。レギュレーションを踏まえたこんな戦略の違いが結果に現れたようです。
「事前準備」と「計測」ーー優勝チームの戦略は基本に忠実
【ふんばり温泉チーム】の戦略には、他にもいくつか学べることがありました。
1つは、事前の準備を入念に行うことです。あらためてチームの皆さんに伺うと、チーム内の役割分担やコミュニケーションツールとルールの整備にはじまり、各種設定ファイルとAnsibleを使った設定自動化の仕組み、計測ツールの準備と使い方のまとめなどを用意してR-ISUCONに臨んだそうです。
「準備をしておけば、単純に初動が早くなっていち早くチューニングに取りかかれますし、計測→打ち手→計測……という改善サイクルも高速に回るため、次のボトルネックをより早く探せるようになると思います」と振り返っています。
また、「想定外の技術スタックが出てきた場合はどうするか」も決め、いわば例外処理を定義していたことも印象深いです。開発ルールを定め、「revertの可能性が高いときはプルリクエストを送る」といった細かなことまで決めていたことも、当日の速やかな意思決定に、ひいてはハイスコアにつながったのかなと思わされます。
事前準備についてはチーム【俺マジでマホロバは行けないからね!】の石井さんも「メンバーがあらかじめタスクリストを作ってきてくれたので、初動がかなりスムーズに進みました。事前準備の重要性が分かりました」と述べていました。
【ふんばり温泉チーム】のもう1つのポイントは、「監視」「計測」の重要性です。「常にどこがボトルネックになっているかを計測し、特定した上で打ち手を打つのはシステム開発・運用全般で必要なスキル、考え方だと思っています」とし、日々の業務にも生かしていきたいということです。
【ふんばり温泉チーム】の皆さんは以前のR-ISUCONにも参加していた他、本家ISUCON予選にも挑戦してきました。「エンジニアの普段の業務の延長線上にある『チューニング』という内容をテーマにし、しかもその結果が点数という定量的な指標で評価されること」がISUCONの魅力だと感じているそうです。加えて、「ここまで作りがひどいサービスと関わる機会もそうそうないので、改善幅が顕著に出て気持ちいい」のも要因だとか。
中堅~ベテランエンジニアにも「自らを謙虚にする機会に」
「こういう場に参加することで、エンジニアとして謙虚になれる」ーー前回のリベンジを期して参加したチーム【RJB】の高橋陽太郎さんはこんなふうに述べていました。前回の反省を踏まえ、今回は事前にさまざまな準備を整えて挑んだそうですが、がらっと異なる問題に面食らったとのこと。それでも、準備とこれまでの経験を生かしてチューニングに取り組みました。
R-ISUCONは、さまざまな問題を擬似的に体験し、ビジネスとの兼ね合いもあって本番サービスでは絶対にできないようなチャレンジができる場になっているだけでなく、「自分を謙虚にしてくれる機会だなと思っています。競技をしていると、年齢や立場とかに関係なく、『若い人ってやっぱり技術的にすごいところがあるな』と周りをリスペクトできる瞬間があります」と高橋さんは、述べていました。
さて、次のR-ISUCONはどうなるでしょうか。今回は、第2回の運営チームプラス優勝チーム【Theorem】のメンバーがタッグを組んで運営に当たりました。「問題を解く方は決まった時間頑張ればいいけれど、作る方は大変でした」と言いますが、人数が増えた分、安定した進捗が可能になったそうです。そして次回は、今回優勝した【ふんばり温泉チーム】が運営チーム側に立ち、挑戦を受けることになりそうです。
【ふんばり温泉チーム】は「せっかくならまだR-ISUCONで使われていない技術スタックなども取り入れつつ、若手も参加しやすいよう基本的なチューニングポイントを織り交ぜ、参加者全員が楽しめるような問題を作れたらいいなと思っています」と述べています。
もう1つ、印象深い出来事がありました。初日にスタートダッシュを見せた【ぴぎまる】が結果発表の場で、「機械学習を活用したR-ISUCON的なイベントを実施する予定です」と宣言。まだまだいろんなチャレンジが広がりそうです。