ISUCON 9 予選に参加した

全然ダメでしたが。

いつものチーム「ワイハリマ」で参加していました。前回は結構惜しいところまで行っていたので今年こそは予選突破するぞ!と言っていたら、全然手も足も出ず 5110 点という結果に。

当日はいつも通り、前半は yuta1024 と yabuuuuu が事前準備したインフラに適合する作業をしつつ kataribe やスローログの準備をしている間に僕がデータベースのスキーマとか、見てわかりそうな部分を改善……しようとしていたのだが、今回は SQL のテーブルは最初からそんなに悪い構造になっておらず、結局効いたのは blob が入っているテーブルで検索にインデックスが効かないため画像ファイルを DB から追い出したことくらい。二人がインフラを改善してくれていたのも効いていたようだ。

その後、 3 人合流して分析にあたり、 /transactions.json がとにかく遅いので、改善に着手した。SQL のトランザクションを貼りっぱなしで ShipmentService に https 接続していたのが、切り離しに成功して少しだけ上がる。

その後は buy が遅いということになった。buy は商品を買おうとする注文で、「在庫のある状態の商品なら、 PaymentService に決済を要求し、決済にも成功すれば購入できる、そうでなければ DB の何もかもロールバック」という処理になっていた。在庫状況を確認するのが SELECT FOR UPDATE になっており、行ロックで決済完了まで進める、という処理になっており、要は「買えそうなら商品を仮抑えして決済し、カード番号が違うとかで決済が失敗すればキャンセル」というごく普通の処理になっていたのだが、どうやら「人気商品に注文が殺到する」という、これまた現実にありそうな注文をしてくるようだった。結果、同じ商品に対するほぼ同時のリクエストが全部ロックされ、 fpm のセッション数すら溢れて nginx が 502 Bad Gateway を返す、ということになっていた。

buy に対する根本的な解決策が思いつかず、行ロック緩和について話し合ったものの雑な処理ではベンチが通らなかったりするので結局改善には至らず。別途他の二人がインフラ周りをいじって、 buy だけ専用機で fpm セッションを食わせるようにしたのはそこそこ効いたようだ。

今回、問題自体はとても良いものだと感じただけに、特にその設けられた課題に対して直接的な何かを何もできず、ただただ前年の本選問題を見てすらいなかったことなどを反省することしかできなかった。しかし、どうすればよかったのか、結局わかっていない。

(追記)チームのリポジトリ https://github.com/yuta1024/isucon9