読者です 読者をやめる 読者になる 読者になる

平常運転

アニソンが好き

過去記事とかは記事一覧で見れます

ISUCON5の本選に参加して惨敗しました

perl engineer

タイトルの通りです。
先日行われた、Iikanjini Speed Up Contestの略であるところのISUCON5の本選にはてなの若手エンジニア3人によるチーム「はむちゃん」で参加し、見事惨敗してきました。最後のスコア計測時に再起動試験をクリアできなかったので最終スコアはなしで、終了直前のベンチマークで出した値は4万点台だったので仮に再起動試験で同程度のスコアを出せていたとしても9位ライン、ということになります。isucon.net

予選が好成績で調子に乗っていた記事はこちらです。astj.hatenablog.com

本選の感想

最初に、今回の終了直後のこのツイートをもって感想とさせてください。


ふりかえり

本選のお題が何になるかはいろいろ噂されていましたが、冗談半分に言われていたマイクロサービスとDockerのうち前者が大正解という感じでした。イントロダクションのスライドでマイクロサービスという単語が出てきたときはまじかー来たかーという感じでした。ちょうど前日の昼休みに社内のマイクロサービスの使い方について(チームメンバーでは無い別の)社内のエンジニアと話をしていたところなのでタイムリーだ、と思ったけど役に立てることは出来なかった。

システム構成的なところについては、主に担当したid:y_uukiさんがそのうちブログを書いてくれると思っているので割愛します。今回構成面はほぼ丸投げにしてしまった。

既に各所で語られていますが、本選はなんとRDBMSMySQLではなくPostgreSQLでした。ぎょっとしつつ、y_uukiさんが下準備をしている間暇だったのでしゅっとMySQLに書き直しを僕が行ったのですが(手元のMySQL dbと組み合わせて動くようにするのはすぐできた)、

  • サーバ上でmysqld動かそうとしたら妙にハマった
  • PostgreSQL(標準SQL)とMySQL||演算子の挙動が違うことにより、チェックサム計算をperlに移した時に動かなくてハマって、時間を食ってしまった
    • mysql> SET sql_mode='PIPES_AS_CONCAT';

という感じで、結果的にコストに見合わない変更をぶちこんでしまったので判断ミスだったと反省しきりです。ポスグレのままではdb勝負になったときに何もできなくてまずいぞ、という感覚で進めてしまったのですが、ベンチしてDBが律速じゃ無いことを先に見ていたなら少なくとも後回しにする判断はできたよなぁ、というのが事後の振り返りです。計測せよという話。

今回「惨敗」とタイトルに書いたのは、スコアをろくに伸ばせなかった+failしたというのは勿論なのですが、その結果というよりは内容があまりに惨敗だったというところが大きいです。アプリケーション単体で閉じてる部分の変更がなかなか上手くいかずにそこで時間と労力を使ってしまい、本丸であるはずのサブシステムリクエスト部分の改善にほとんど手を割けなかったので、これでは本質的なことは何も出来てなくて惨敗だぞ、という気持ちであります。
社内の最近のサブシステムの使い方に則り、直接アプリケーションプロセスから外部マイクロサービスを叩くのではなくいったんnginxを挟もうということでnginxを通すようにして、ついでにnginx層でキャッシュ(具体的な内容全く見てなかったけど今リポジトリ見たところ1分キャッシュだった)を挟むことでスコアを人権のある程度には伸ばせたのですが、そこで手が止まってしまってそれ以上の改善にはあまり踏み込めませんでした。nginx通す元々のメリットの1つにリクエストログの収集があったのですが、そのリクエストログの分析も今ひとつ捗らなかったのは痛恨かなと思っています。
……とここまで書いたところで思いだしたけれど、郵便番号から地名情報を引くAPIに関してはid:ntakanashi さんが先にガッと手元にdumpを作って読み込ませるというのを用意していたのでした。実装してもらってるときはこれでサクセスや、という雰囲気もあったけど、結局これだけではそこまで劇的なスコアの改善はできなかったように記憶しています。ログはごちゃごちゃしていて既に振り返るのも困難。

途中で一度再起動はしていてその時点ではfailしていなかったように思うのと、それ以降は再起動によって壊れる変更を加えていないつもりだったので、failしたのはAPIのキャッシュが素朴だったからレスポンス内容のチェックでコケたのではないかと思っています。作業中にも数回出ていたんだけれどあまり頻度が高くなく、かつ常に手探り状態だったのであまり深追いできなかった……という状況でした。まぁ、もしかしたらもっと致命的なところで何かコケたのかもしれないけれど……
("同じトークンで同時に複数リクエストを投げては行けない"という制約があったAPIに対しても特段の配慮をできていなかったので、終了直前に入れたユーザ周りのキャッシュでスループットが上がった結果エラー遭遇率が上がっていた可能性はありそう)

所感

予選と本選を通して、特に個人的に強く思ったのは、「普段やってることはできるし普段やらないことはどうしようもない」ということだったかなと思います。予選ではperl + MySQLのwebアプリケーションでMySQLのクエリが律速という、ある意味一番普段やってることに近い構成だったので、何をやればいいか想像がつく(勘が効く)し、必要な改善を実際に進められる手応えが得られた……し、スコアもよかった。一方で、(他のチームメンバーは分からないけど)僕は普段Redisもあまり触らないので、Redisにデータ載せようとするとシリアライズだの何だので何かとつまづきまくって捗りませんでした。本選はこれが一層如実に出た状態で、入社してからマイクロサービスへのリクエストのキャッシュ戦略に頭を捻る局面があまりなかった(リクエストに対してそこまでシビアなサービスへのリクエストを扱う機会があまりなかった)ので、このあたりへの勘が全く働かなかったなぁと思っています。仮に時間があったとしても、トークン周りの仕様やHTTP2に気づけたかというと、僕自身に関してはノーではないかなと……
ただ、本選は残念な結果でしたが、予選に関しては「普段やってることをやればそれなりの結果を出せた」という意味で、チームはむちゃんの実力を知ることができて大変よかったなと思っています。263チームが出場した今回のISUCON予選で、本業オブ本業というような分野であれば5位という成績を出すことができたというのは誇ってよかろう、というのも正直な感想です。

後はやはり、あまりにも初歩的なことではあるのですが、「推測するな、計測せよ」ということに尽きるなと思っています。計測して、その上でどこがボトルネックなのかを判断し(てAPI部分の改善に注力し)なければならなかったと、今になっては思うばかりです。

おわりに

予選、本選、ともにたいへん質の高い問題や快適なベンチマークツールを用意していただき、また本選の設備関連も大変充実しており(チーム状況にまったく余裕がない中僕はお弁当いただきました。おいしかったです!)ました。
これだけの規模のコンテストを実施された運営主催協賛の皆様には本当に頭が下がる思いです。ありがとうございました。
もし来年以降もまた開催されるようであれば、是非パワーアップしたネオはむちゃんで再挑戦したいと思っております。

フォトギャラリー

参加賞としていただいたノベルティ?的な中に入っていたブラウンくんです。明日から僕の代わりに仕事してもらう予定です。

会場案内の写真です。これを撮った頃は元気があった。

懇親会で出された協賛のNHNテコラスさんの提供による寿司です。たくさんいただきました美味しかったです寿司は最高。

本選会場であるヒカリエから眺めたハロウィンの渋谷の様子です。やや見づらいですが交差点の左下の黒い蠢きは人間です。

余談オブ余談

気合い入れのためにアイドルマスターのライブTシャツ(今夏の10周年ライブのTシャツでした)を着てきたのですが、最後の記念写真にばっちりアイマスTシャツ姿で写ってしまっております。公開されるものなのか分かりませんが、公開されたら是非ご確認下さい。