Hateburo: kazeburo hatenablog

Operations Engineer / 運用系小姑 / Perl Monger

ISUCON11予選に「チーム中目黒乗り過ごし」で参加し本選出場決まりました

ISUCON11の予選に参加し、なんとか本選出場を決めました!チームは去年と同じ「中目黒乗り過ごし」でメンバーも変わらず、hanabokuro氏、mtokioka氏と参加しました。

isucon.net

チーム中目黒乗り過ごしとして、2年連続で9位で本選出場です。去年の予選記事はこちら。

kazeburo.hatenablog.com

ちなみに、去年の本選はFailでした。

先日ISUCONのインタビュー記事に載りましたので、こちらもどうぞ

type.jp

今回の問題

f:id:kazeburo:20210824143717p:plain

ISUのコンディションを収集し、可視化するサイトということで、IoTや大量のネットワーク機器の監視メトリクスの扱いが課題のネタとなっていたように思いました。

世界観が面白く、ISUが投擲の道具じゃなく、愛される存在になったのだと感慨深いものがありました。

構成とスコア

当初は1台でやっておりましたが、最終的に3台を次のように使いました。

f:id:kazeburo:20210824141043p:plain

getTrendの生成負荷が高かったので、nginxとgetTrendだけを処理するappを用意し、その他を別のappに寄せました。

スコアはこんな感じで推移。

f:id:kazeburo:20210824142720p:plain

ベストスコアは 684,624 ですが最終的には 289,148 でした。

f:id:kazeburo:20210824141148p:plain

17時の時点では、トップでしたのでパブリックスコアボードでしばらく1位でした。ちょっとうれしい。

使ったツール・言語

DBのクエリの分析に、pt-query-digest を使い、アプリケーションの方にはGCPの Cloud Profiler をいれてどこに時間がかかっていそうかを見ていました。

f:id:kazeburo:20210824141242p:plain

これは 11:20ごろのprofileのスクリーンショットです。

言語は Go になります。わかりにくいところは Perl も参考にさせていただきました!

やったこと

使った repository はここで公開しています

github.com

前半

まずtopをみて、DBの負荷が目立ち、INSERTも多くあることがわかったので、MariaDBの設定を行いました。MySQLではなかったのは一瞬悩みましたがそのままにしています。。

sync_binlog = 0
innodb_doublewrite = 0
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT_NO_FSYNC
innodb_adaptive_hash_index = 0

複数台にする際にbind-addressを消した以外はいれたのはこれだけです。

そして、getTrendの生成をbackgroudに回したり、icon画像が不要なところではselectしないようにしたり、必要なindexを張ったりしていたのが序盤です。スコアは2万を超えたあたり。

中盤 (13時すぎ)

Goのapplicationはアクセスログを吐くようになっていて、syslogに負荷がかかり、またログが見づらくなるので、ログのミドルウェアを外しつつdebugモードも解除。

さらに1台ではスコア向上が難しいと考え、複数台構成に変更し、このタイミングでデプロイを簡単にするMakefileを作りました。

この時間帯には、getIsuConditionsFromDB の負荷を下げるため、isu_condition テーブルに condition_level カラムを追加した。

スコアは 10万近くまで上昇。

終盤 (15時すぎ)

捨てるデータの割合であるdropProbabilityを0.5まで下げてスコアが上がるのを確認。

generateIsuGraphResponse でDBからデータを取ってくるところにBETWEENを入れ、不要なデータを取得しないよう対応し、getIsuListのN+1を解消、getTrendにLIMIT 1を追加するなどして、16:50ぐらいには、dropProbabilityをもっと下げて、ベストスコアの68万点がでた。

途中中断

17時ちょっと過ぎたところで、スコアがぐっと下がってしまい 26万点となってしまう。この理由が分かっていない状態で、中断となったのが我々には痛かった。中断の間は、kernelパラメータいれたり、再起動の試験をして過ごす。

再開後、applicationのmax file descriptorに引っかかっているがわかったので、それをいれてみるなどしたが、スコアは戻らず、最終スコアは32万点でおわり、あとはFailしていないことだけを祈る形となった。

まとめ

Failせず、本選出場できるスコアが出せたのは嬉しい。中断前のスコアがなぜ出せなかったのかは、今後の課題としたい。

今回の問題、ぱっと見シンプルなようで、ボトルネックが変わっていくところなど、奥が深いように感じました。加点ルールをより生かせれば、もっと高いスコアが出せるような気がするので、時間があるときに挑戦したいと思います。

また、環境構築、ベンチマーカやポータルも丁寧に作られており、競技に集中できるようなっておりました。おそらく準備は大変だったと思います。運営のみなさまありがとうございました。本選も楽しみです。よろしくお願いします。

今回、ちょうど17時にトップに立てたので、家族にはいいところを見せられたようです。いつも応援ありがとー。本選もFailしないよう頑張ります。