詩と創作・思索のひろば

ドキドキギュンギュンダイアリーです!!!

Fork me on GitHub

ISUCON9予選敗退(H::W::A::Abyss::Abyss::Abyss) #isucon

ISUCON9 2日目結果と本選出場者決定のお知らせ : ISUCON公式Blog

日曜日に行われたISUCON9予選に参加し、敗退してきました。前掲の記事の「失格となったチーム」がわたしたちです。チームメンバーは id:t_kytid:mechairoi

去年も予選敗退していて、最近LINE本社に行ってないな~と思っていたので今年は勝ちたかった。今年もはてな京都オフィスで予選に参加。

f:id:motemen:20190909133951p:plain

事前の作戦が大事なので、「コミュニケーションが大切」「マニュアルを読む」を確認した。

だいたいハマり出すとコミュニケーションが減ったり同じことをやりだしたりしてチームとしての効率が下がってしまうので、一時間ごとにタイマーを鳴らしてそこで話そう、という作戦を立てていた。あとは alp と pprof と pt-query-digest でボトルネックを見ていくというシンプルな戦略。

あと、1日目の結果を見ていて

美顔器 on Twitter: "近年の傾向を分析した結果、今回のISUCON戦略は「学生気分」とします"

という気づきを得たので方針は「学生気分」となった。

やったこと

  • 10:53 最初のベンチが取れるまでがだいたい1時間くらい。デプロイは手元で build してバイナリだけ rsync するような方法で、これはサイクル早く回せてよかった。
    • ベンチを回していると isucari の CPU 使用がボトルネックになっているのが分かったので、pprof。http.ListenAndServe(":6060", nil) して待ち受ける練習をしてたんだけど、よく考えたらセキュリティポリシーで塞いでいたので ssh でポートフォワードした。
  • 11:49 pprof すると postLogin 内の bcrypt が重いことが明らかだったので、「学生(10年前の自分)だったらどうするか?」と考えて即座にパスワードを平文化することを思いつき、ベンチを回してパスワードを収集する実装を投入。還元率 1 で 5,230 イスコイン。
    • あとで書くけど、この初手で地獄への道が敷かれていた。笑える。
    • まあ気づいていたとしても MD5 化くらいはやったと思うので、あとはそうだと思って読んでください。
  • 13:28 当然スコアは上がるんだけど、ベンチマークを回してパスワードを収集するたびにパフォーマンスが上がり、どこかのタイミングで臨界して POST /buy が失敗するようになったので、どうしようかねー、と話して外部 API へのアクセスをリトライするようにしたところ、うまく行って還元率 2 で 8,030 イスコイン。
    • これなんでリトライでうまく行ったんだろ。今考えるとよくわからない。500 になってたのかな?
  • かりそめの暫定一位を取ったところでお昼ごはん。
  • 14:03 どうせ3台構成にするから今のうちにやっとこ、ということで 1 台を nginx+アプリ、1 台を MySQL にしたところ還元率 0 で 2,710 イスコイン。還元率を 1 にすると以下のエラーが出て FAIL するようになってしまった。この失敗理由が見えないので一同相当にハマってしまった。Revert したり構成戻したり、でかなり時間を取ってしまった。なんでなの……。
POST /buy: リクエストに失敗しました (item_id: 50030),
POST /buy: リクエストに失敗しました (item_id: 50036),
POST /buy: リクエストに失敗しました (item_id: 50043)
  • 17:13 トランザクションを分離する変更を id:mechairoi がしてくれたのでそれを入れて、id:t_kyt が nginx の雑なチューニングをしたのを入れて、ヤケクソで還元率を 4 にして 9,950 イスコイン。
    • あと、カテゴリのオンメモリ化もどこかのタイミングで入っている。
    • いろいろやった結果ここで落ち着いた。「リクエストに失敗しました」の謎は結局解けなかった……。
  • その後 nginx の HTTP/2 を有効にしたり、還元率を 3 に変更したりして最高 10,590 イスコイン の最終 10,070 イスコイン でフィニッシュ。
  • 終了 10 分前くらいに再起動試験をしたら、アプリの起動時に DB アクセスしていたのが失敗するせいでアプリが起動しなくなっていて、あわてて修正した。最後までがんばった。

今思うと、

  • ShipmentService の状態はこの条件以降は変わらないよね~、ということを昼飯のときに id:mechairoi が言っていたのを拾えなかったのは少し惜しかった。こういう気づきを、いかに精度よくテンポよく実装に移せるか、が ISUCON ではいつも大事。
  • ベンチの終了時に外部 API が 502 を返していたのに気づいてなかった。途中で 502 が出てて、ログがバッファリングされているのかな……されてるわけないんだけど、と思ってしまっていたのはヘンだった。。
  • 還元率でユーザの行動傾向変わるのに気づいてもよかったな~。新着をいじってもよかったな~。
  • rsync でバイナリ(と *.sql のみ)デプロイしたのはよかった。自然と motemen がデプロイ担当になっていて、そこで整流できたのもよかったかな。

試合終了、そして

参加された皆さまはすでにお気付きのとおり、パスワードを平文で保存するのはレギュレーション違反である。

終了時にはそのことを知らず、それなりにやることはやった感もあったので、18 時ごろに再起動試験を終え、少し伸びた終了時刻までの間にビールを買ってきてやれやれ、と、同じくオフィスで予選に参加していた他のチームと感想戦をしながら Twitter や Discord を眺めているうちに、違和感が……。あれ? と思ってレギュレーションを再確認したらそれに気づいてしまった。実装した当の自分が最初に気づいていたわけで、なかなかショックがでかい。

チームメンバーに告げ、当然のお通夜ムードになった中、2日目の予選通過チームが発表されると全体の上位20チームの一番下に弊チームの名前が載っていた。どうやってチェックするつもりだったかはわからないけど、運営による追試をどうやらすり抜けてしまっていたらしい。メンバーの間では、報告しよう、ですぐに意見が一致したので 941 さんに DM を送って無事失格となりました。100万円は惜しかったけど、正直に告げることを選択できるチームだったのはよかった。

これでこの話は終わりです。

はてなで一緒に働きませんか?