見出し画像

「やらかし」と「疑心暗鬼」と「喜び」のISUCON10

チーム「ノーザンサウザンハウジング」としてISUCON10に参加し、残念ながら予選敗退になったのだが、記憶が新しいうちに記録を残す

ISUCONとは

http://isucon.net/

お題となるWebサービスを決められたレギュレーションの中で限界まで高速化を図るチューニングバトル、それがISUCONです。

現実にありそうなWebサービス(今回だと、後述するSUUMOリスペクトなサービス)をいかにパフォーマンスを上げつつ、求められる要求に答えられるかと言うのを勝負するコンテストだ

前々から聞いたことはあったのだが、なんだかその道のプロフェッショナルが鎬を削ってるんだろう

とスペシャリストでもなんでもない自分には関係ない世界だろうと思っていたのだが、数ヶ月前に友人から「でようぜー」といういつもように軽いノリで誘われ「いいよ」と答え参加が決まった

実際体験してみて思った印象は、エンジニアにおける脱出ゲーム的な印象で意外とそこまで敷居は高くなく、とても楽しいので、難しそうと参加躊躇している人はまず一回やってみるのがおすすめだ

来年も出たいと思った

やることは、

運営チームが意図的にパフォーマンスが遅くなるように仕掛けたプログラムやシステムからボトルネックを見つけそれを自分たちのサーバー上で修正する

ベンチマーカーと呼ばれる、パフォーマンスや目的とする数値を測定しスコアとして計算してくれるものを実行する

そして最終的にそのスコアが高いチームが予選通過できる仕組み

ランキングがリアルタイムで表示されて、自分の現在位置を確認しながら、「抜かれたー」「抜いたー」と一喜一憂するのは、マリオカートみたいな感じで楽しい

Live中継もされていて自分たちは、オフラインで僕の家に集まってやっていたが、Youtubeをテレビに流しながらやっていたので臨場感があった

画像1

こんな感じで、左に順位変動、右に予選通過ラインのトップ25位が表示されている

*)場面は、我らが「ノーザンサウザンハウジング」が42位になった瞬間を捉えたもの

チームメンバーと準備

前職の同僚二人 (@kenjiszk@nobuhikosawai)と組んで3人チームで臨んだ

事前に4回ほど週末に時間をとってオンラインで前回のISUCON9の課題を解いたりした

過去問題解いておくのは感じがつかめるのでやっておいたほうが良いなって思うし、実際それやってなかったらあたふたしただろう

前回も参加した @nobuhikosawai の事前準備が大事だというアドバイスを受け

レポジトリは事前に非公開で作っておいたり、githubのDiscord連携に流れるようにしたり、情報連携のためのscrapboxとそのDiscord連携、壁にホワイトボードを貼るなどのの手はずなどを整えていたため、当日のコミュニケーションはスムーズにできた

*)Discord連携はオフラインってこともあって、口頭でやりとりしていて、ほとんど見てなかった気がする

*)移動式扉にホワイトボードペーパーを貼る運用はなかなか良かった

画像2

で、事前の準備やらもともとの得意領域から、役割分担としては、自分がアプリ周り、@kenjiszkがインフラ、@nobuhikosawaiがDBという分担で行こうと決めていた

が、なんだかんだ縦横無尽に色々やったなと言う感じなので、あまり最初に決めた役割分担にこだわらず広く見れるようにしておいたほうが良いんだろうなという感じだった

参加前の目標は謙虚に

サーバーに入り、一回だけでもいいからベンチを回す

とした。

結果

結果としては、一時1800点ぐらいまでスコアを伸ばしたが、最終提出スコアはベンチマークを回せば回すほどスコアが落ちてしまい、1200点でのフィニッシュになってしまった

誤解していたのが、終了して改めて各チームに対してベンチマークを回したときのスコアで最終順位が決まると思っていたが、そうではなかったところ

次回反省として活かしたい

優勝チームのスコアがどれくらいかわからないが、終了一時間前のスコア凍結時で7250、25位で1600ぐらいだったので、後少し何か改善を加えられて安定してスコアを出せれば予選突破できたかもなぁという感じで思った以上に健闘できたとお互いに称え合った

目標としていた「ベンチマーカー一回回し」も一回と言わずブンブン回せたし、3commit位はできると良いねといっていたcommit数も60(Revert含む)となり非常に満足している

やらかしとハイライト

具体的に何をやってスコアがどうなったかの細かい話は他の二人が書いてくれるブログに任せるとしてせっかくなので自分目線でのやらかしとハイライトを書きたいと思う

まず簡単な前提の共有をしておくと今回は各チーム3台サーバを与えられ、自由に構成を変えて良い。細かいレギュレーションはこんな感じ

与えられたサービスは「ISUUMO」と呼ばれる「椅子を買ったときに、その椅子に合わせた不動産を検索できるサービス」

スコアは、椅子の購入件数不動産の物件の資料請求件数から計算されて、それが大きくなるようにするのが目的だ

まぁ当然みんな思ったと思うけど、椅子を先に買ってその椅子に合う不動産を探すというのはなかなかクレイジーなサービスだと思う

まずやらかしから

今回チーム内でも最大のやらかしと呼び声の高いホームディレクトリ一掃事件

こんなことやったらまじでだめだなぁって思うし、なーんでこんなことやっちゃったんだろうって感じだ

エンジニア引退したほうが良いと思うレベルかもしれない・・

2台目のサーバーをgitからpullしてmakeするように変更しようとしてたときのこと

僕:とりあえずうっとおしいからホームにあるファイル全部backupしちゃうね

各々他の作業に集中していて多分聞いてなかったと思うし、まさかそんなことやるとは思ってなかっただろうけど「おっけー」と返ってきたので

何も考えずに

cd ~
mkdir backup
mv .* backup
mv 他のファイルたち backup

と打って

ls -la
​

「よし綺麗にbackupだけになったな。ふぅ・・・」

よし一旦一回exitや

僕:あれ、ssh入れない、なんかパスワード求められるな・・

(んー他の人にも聞いてみるか)

僕:みんなサーバー2にsshできる?

みんな:ん?できない。なんかした?

僕:あのさ・・・ホームディレクトリ、dotfilesもまとめて全部移動しちゃったんだよね・・・よく考えたら.sshとかもあったんだったよ

kenjiszk:それは無理よ。復旧できない。運営に言うしかない

僕:・・・

で、運営にリセットをお願いしようと思っていたら

たまたまkenjiszkがsshしたままセッション残していて事なきをえた

神様・仏様・健二様と言いたい

これが最大のやらかし

後々運営との問答集を見てみると、サーバーの再起動以外の復旧はしないと書いてあったので、もしこれkenjiszkがログインしたままでおいておかなかったら詰んでたと思う

教訓

全員全サーバーにsshしたセッションを残しておくこと

そもそもそういうことしない

ベンチ通らなくしたのは誰だ事件

ある時、僕のPRを入れたベンチがFailし、Revertして修正して再度PR投げてベンチ通した。

sawai:MySQLのFull Text indexの修正いれてベンチ回しますね

→ Failする

sawaiさん疑いの眼差しを僕に・・・

僕:いやいやいや、一回前までは通ってましたよ

sawai:いやそこでもすでに壊れてたんじゃないすか。Revertとかしてたし [疑いの目・・・]

僕:いやいやいやいやいや、大丈夫でしたよ。

swai:一回戻して確認しましょう

→ Success

僕:ほらやっぱり言ったとおり、大丈夫だったじゃないですか、なんで疑ったんですか!?

sawai:いや、ローカルで動いてましたもん

という今回のチーム戦で最も心理的安全性が低くなりかけた瞬間だ

面白かったので

事あるごとに「sawaiさん、あの時疑ったもんなぁ」って4,5回は根に持つ感じで言った(よくなかったかもしれない)

大事な教訓

多少ネタにしつつ、カジュアルに

気になったことは、お互い言ったほうが良い

険悪になるのは良くないけど、険悪になりそうなときに我慢して不和を抱えたままになるよりは、思いっきり言って解消するのが良い

と、僕は思ってるけどsawaiさんがどう思っていたかは是非聞いてみたいところだ

ハイライト

次はハイライト

不動産を探すサイトということで、本家「SUUMO」にもあるらしいという、なぞって検索

地図上で指(マウス)でなぞって範囲を指定するとその範囲にある不動産を出してくれるという便利機能

これがくっそ重いということがプロファイルからわかった

で、なんか直せないかなーって見てたら、どうやら

なぞった線分を緯度経度で配列で受け取ってそのポリゴンの最小・最大緯度、最小・最大経度の矩形でまず不動産をとってきて、その後一軒ずつの不動産に対して、緯度経度がなぞったPolygonの内部にあるかどうかをMySQLのクエリで判定していることがわかった

クエリとしてはこんな感じ

SELECT * FROM estate WHERE id = ? 
AND ST_Contains(
 ST_PolygonFromText('POLYGON((34.976002 139.575806,34.976002 139.795532,35.012002 140.874939,35.016501 140.874939,35.027747 140.869446,35.050235 140.850220,35.189522 140.710144,35.759886 140.078430,35.880149 139.941101,36.091280 139.696655,36.242058 139.496155,36.337253 139.336853,36.348315 139.317627,36.357163 139.301147,36.536123 138.724365,36.544949 138.694153,36.547156 138.680420,36.547156 138.669434,36.374856 138.526611,36.350527 138.510132,36.257563 138.449707,36.202174 138.419495,36.160053 138.397522,36.115690 138.375549,36.049099 138.350830,36.018004 138.342590,35.995785 138.339844,35.946883 138.334351,35.755428 138.334351,35.677379 138.339844,35.597019 138.350830,35.556809 138.359070,35.523285 138.375549,35.151354 139.084167,35.025498 139.356079,34.985003 139.487915,34.976002 139.575806))'),
 ST_GeomFromText('POINT(36.113316 139.301063)'));

ST_Containsというのがあるのも初耳だったし、POLYGON, POINTでこんなことできるんだーってのは驚きだった

だけど、これ1件1件MySQLにクエリ投げてMySQLにやらせるの重くね・・・?

Polygon作って、内部にあるか判定するだけならアプリでやっちゃえばいいじゃんと思い調べてみた所

goにgolang-geoってのがあるのを発見し、実装してみたら意外に簡単に実装できた

修正は至ってシンプルでこんな感じ

これでベンチを回すと一気に700点ぐらいだったのが1200ぐらいまで確か伸びてテンションめっちゃクソあがった

これが今回の自分的ハイライト

感想

楽しすぎた

はじめて参加して、自分にやれることはなさそうかなーと思ったけど思ってた以上にやることがたくさんあって手分けしてるとあっちゅうまに時間が過ぎ去った

想定回答とかはまだ見ていないけど、そういうのも見て手数を増やしたりすることは普段の業務にも役に立つし勉強になるだろうと思うからやりたい

後、チーム内でも反省会というか振り返りはしたい

チームの心理的安全性、何でも思ったことを言い合える関係性が大事

とにかく今回は運良く思いついた実装がハマってスコアが大きく伸びる経験ができたのだけど、これが非常に病みつきになりそうな感覚

業務でのクエリ改善とかでも一気にパフォーマンス上がると嬉しいけどそれに似た感覚

来年は予選突破を目指して、サーバーを壊さないようにまた参加したいなと思う

運営チームの皆さん

とにかく開催前〜開催中〜終了後ととにかく大変そうでしたが、こんな素晴らしい大会を開いてくださってありがとうございました!

#ISUCON10

この記事が気に入ったらサポートをしてみませんか?