ISUCON8予選突破した
今年も予選から素晴らしい運営、問題で堪能させてもらいました。
去年本戦3位で終わり、思うところがあり、今年は一人で出るか、もしくは出るの見送ろうと思ってたんだけど、TwitterのTL上でnajeiraさんが、メンバー募集していたのを見て、急に出たくなってしまって一緒に参加させてもらうことにした。
興味あります。
— songmu (@songmu) 2018年8月28日
去年3位
優勝経験有り
Go書けます
これまで、同僚か元同僚かとしかチームを組んでこなかったので、あまり馴染みがない人と組むのは楽しそうだし、そういう新しいチャレンジも面白そうに思ったのだ。
ということで「死闘の果てに」と言うチーム名で、najeiraさんとbluerabbitさんと参加することにした。チーム命名はnajeiraさん。
事前の顔合わせでも、fabricでdeployしましょう、解析には github.com/najeira/measure を使いましょう、とかこれまで使ったことのないツールを使うことになって、楽しみになったし、実際良い経験になった。
分担としては、bluerabbitさんがインフラメイン、najeiraさんと僕でコードを書くという感じ。実際にはnajeiraさんもNginxへの入れ替えとかインフラタスクもやってもらえたので助かった。
予選当日
予選は日曜参加で、najeiraさんの職場の環境を使わせてもらった。ちゃんとした椅子もディスプレイもあり、ゲストWifiもしっかりしていて快適で良かった。
今回の問題は、ISUCON2を彷彿とさせる問題だけどしっかりボリュームもあって手ごわかった。
最初にミドルウェアの構成を見て、MariaDBなのはCentOS7だからそりゃそうかという感じ。h2o使っているところを見て、なるほど、これはDeNA出題だな、とも。h2oのままでも問題ないとは思ったけど、najeiraさんが使い慣れているNginxに切り替えていて、そこは僕も特に反対する理由もなかったのでそれはそうしてもらった。
僕はまず肩慣らしに、rankのvalidatをDB引かないいようにしたり、sheetsテーブルをオンメモリ化したりしていた。この辺はあまり意味がなさそうではあるけど、コードを触りながら雰囲気を掴むためにやったという感じ。
あとは、reservationsテーブルのcanceled_atとreserved_at辺りのクエリが厄介なことになっていたので、last_updated_atというカラムを追加して、最終更新で並べたい場合はそっちを見るようにして、インデックスもそっちにだけ張るようにした。この時初期化処理で、以下のようなSQLを発行するようにした。
UPDATE reservations SET last_updated_at = GREATEST(reserved_at, IFNULL(canceled_at, reserved_at))
恥ずかしながら、 GREATEST
を知らなくて、najeiraさんにその場で教えてもらうというグレートな体験をした。
この辺り、粛々と変更してたんだけど GREATEST
の中で IFNULL
しないと上手く動かなかったり、 SELECT *
してるところを展開しようとしたらミスってたりと、細かいところで手こずってしまって、チームにも迷惑をかけてしまった。
このへんで、najeiraさんが getEvents
周りの処理を効率化したのも合わせて点数はそれなりに伸びた。この時点で14時くらいで、点数は2万点くらい。
Redis不発
で、空席管理に関しては、これは「ISUCON2で見たやつや」という感じになって、RedisのSetを利用した実装を書き始める。
16:30には予約のデータをRedisに入れる実装が完了。あとはDBから予約を取るのを止めてRedisのみにすればよい。そこの実装も17時には完了。
と、思いきや全然ベンチが通らない。その時点で、bluerabbitさんのreserved_sheets テーブルの追加が有効に機能しており、4万5千点と予選突破が濃厚な点数が出ていたので、この実装を入れることは残念ながら諦めることに。
終わるまでの間、コードを見直していた所、ものすごく馬鹿なミスをしていたことが判明。それが以下のコード。
rediKey := fmt.Sprint("s:%d:%s", event.ID, params.Rank)
…お分かりだろうか。fmt.Sprintf
の "f" が足りない!!!これはひどい…。
ということで、一箇所キーの作り方を間違えていたのでありました。いやー予選通って良かったですね。これが原因で通ってなかったら戦犯ものです。
直してベンチ回したかったものの、スコア保全のために断念。予選でスコア保全策に出てしまうと最後ちょっと手持ち無沙汰になってしまうのは致し方ないとは言え残念な気持ち。
しかし、ISUCON2で優勝したときはtypesterさんがしっかりRedis実装を入れていたのに、今回、僕が同じことができなかったのは無念というか、衰えというか現場間の鈍り感じずにはいられませんでした。
とは言え、何はともあれ本戦に行けたのは良かった。本戦ではもっとバチッと強い修正を炸裂させて、満足のいく結果を出したい。
najeiraさんとbluerabbitさんとは結構うまく連携が取れたんじゃないかと思う。najeiraさんとbluerabbitさんの二人がチームを組んだ経験があって息が合っていたので、後は僕が合わせるだけだったのでやりやすかったのかもしれない。良い経験になって楽しかった。
予選が良い問題だったので、本戦も楽しみです。運営の皆様、いつもありがとうございます!