チーム「さばかんちゃーはんかれー」でISUCON8に参戦してきました。

チーム「さばかんちゃーはんかれー」でISUCON8に参戦してきました。
最後fail出てしまったんですが、終了間際のスコアが29000ほどでした。いずれにせよ本戦には届きませんでしたね。
個人的には2年ぶりの3度目の挑戦だったので、今年こそはと思い、数ヶ月前から同僚に声かけをして、 過去問練習したり、スクリプトの準備をしたり結構頑張ってきました。それだけに悔しいです。
しかしながら一人ではここまで戦えませんでした。一緒に戦ってくれた @matsukaz, @kz_morita には感謝の限りです。
1人チームの人すごい。

チームでやったこと

起床 - 10:00

昼飯を買い込んで、オフィスに集合しスタンバイ。
前日にメンバーに余裕を持って来いと偉そうに言ってた自分が開始ギリギリでした。
セッティングしといてくれてありがとう。

10:00 - 11:00

  • レギュレーションの読み込みと、ログイン環境の整備。あとappやconfをリポジトリにぶち込んで行く。
  • netdata, kataribe, pt-query-digestをインストール。
    • その過程でh2oの存在に気づきチームがざわつく。
    • h2oのパフォーマンスも十分かつ、nginxに置き換えたところでそこまで仕事をさせる場面はなさそうと判断し、h2oのままで行くことに決める。
  • 参考実装をgoに切り替えて初期ベンチ。1000くらい

11:00 - 12:00

  • 事前に仕込んでいたスクリプトを今回ように修正
  • netdata用にポートを解放
    • netdataでCPUを使い切ってることを確認。特にmysqlがCPUを食っている
  • my.cnfをシンボリックリンクにしたところmariaDBが読み込んでくれず若干ハマる。結局元に戻す。
  • カーネル系の設定をとりあえずぶち込む
  • for update を一部クエリから雑に剥がしてみてベンチ。1100くらい

12:00 - 13:00

  • pt-query-digestが動き始める
    • 情報を元にindexを追加
    • indexが効くようクエリを修正

13:00 - 14:00

  • kataribe用にh2oのログを調整
    • ルートのアクセスが多く重いことを確認
      • getEvents -> getEventの多段N+1がやばいので修正を開始
  • h2oの静的ファイルの304対応

14:00 - 15:00

  • getEventのN+1を修正しベンチ。20000くらいに跳ね上がる

15:00 - 16:00

  • この辺りでサーバを複数使用することを検討
    • app2台とDBで分離する方針に決定
    • DBの分離だけ先に対応
      • 鈴木明さん問題に遭遇。初期化shellの接続先をDBサーバのhostに修正。
      • CPUのボトルネックがappのみに
  • この時点で26000くらい

16:00 - 17:00

  • DNSラウンドロビンでappを2台に振り分ける
    • appのCPUに余裕ができる
  • 再起動対策でDBの暖気設定を入れる
  • h2oのmaxconnectionを引き上げ
  • sheetsテーブルを使用しないよう修正
  • ベンチがfailしまくりだす

17:00 - 18:00

  • getEventで既存コードを異なる挙動になる可能性のある箇所を修正
  • 怪しいコミットをrevertし再ベンチ。29000くらい
  • しかし最後またfailしてしまいfinish

良かった点

  • 割と早めにgetEventに対応でき、一時上位争いに食いこめた
  • netdataがすぐに入れれてボトルネックもある程度絞れるので超良かった
  • profileツールのインストール,on/off,プロファイル実行周りをスクリプト化していたので、プロファイルを取るのが捗った
  • アプリのビルド、再起動周りもスクリプト化していたので捗った
  • h2oをそのまま使って良かった。nginx入れてもやはりあまり効果はなかったと思う。

反省点

  • my.cnfなどの環境構築周りでミスってかなり時間を使った
  • 不必要な暖気設定のために、MariaDBのバージョンをあげるためにMariaDBを再インストールする労力を割いてしまった
    • レギュレーションをちゃんと読めていなかった
  • 3人の役割分担が曖昧で冗長に作業をしたり、手が止まる時間があった。

感想

結構戦えた感触はありました。
夕方頃に暫定1位になったりして興奮したりもしましたが、最後は力不足でスコアを上げきれませんでした。
また、提出スコアが再起動後に最終試験に行うものと勝手に思い込んでしまっており、DBの暖気設定を入れるなど無駄な時間を使ってしまいました。
マジでレギュレーションはちゃんと読まないとダメですね。。。
来年またリベンジしたいと思います!

ISUCONに初参戦して砕け散ってきました

初ブログということで、テーマは先日初参戦したISUCONについて。

 

isucon.net

 

ISUCONWebサービスを限界まで高速化を図るチューニングバトルです。

クライアントからサーバサイドに転向して約1年が経とうとしているので、力試しも兼ねて参加しました。

 

チームは自分含め3人。メンバーのdo7beが書いたブログは以下になります。

ISUCON5予選で最高スコア1万弱を出しました - do7be.exports

 

役割

 役割はそれぞれ分けて、

として、自分はミドルウェアを担当しました。

特段ミドルウェアの領域に強いという訳ではないのですが、他のメンバーの実力を最大限発揮できることと、自分自身もっと強化したいと思っていた領域なので丁度よいかなと。

 

やったこと 

時系列で以下のようなことをやりました。

開始前
  • 自社オフィスに集合。みんなかなり早く集まったようで、メンバーから生存確認の連絡を受ける。
  • 設定ファイルやソースの運用方法を確認。
  • 鍵やインスタンスの確認。
10〜12時頃
  • インスタンスを他のメンバーが準備している間にレギュレーションを読み込む。
  • 鍵がうまく登録できずトラブル。作り直して無事入れるようになる。
  • 言語の設定確認。PHPでいく方針だったので、systemdに戸惑いながらも初期のRubyからPHPに切り替えて、benchを流す。
  • 各種設定ファイルをリポジトリの管理下に置く。
11〜14時頃
  • kataribeをインストール。nginxのアクセログを収集し分析する。重いアクセスにあたりをつける。
  • pt-query-digestをインストール。DBのslow queryを全クエリ対象にしてログを収集。分析してDB、アプリケーション担当に共有してやばそうなクエリにあたりをつける。
  • nginxの設定をチューニング。
  • メンバーがコツコツクエリやアプリケーションを修正してじわじわスコアがあがりはじめる。2000点くらい。
14〜16時頃
  • ページレベルでnginxのキャッシュができないか試行錯誤する。結局今回のシステムでは決定的な改善ができそうになく断念。かなりの時間を使ってしまった。
  • その間にもメンバーがクエリ改善。6000点くらいまであがり、暫定10位前後で遷移。
16〜17時頃
  • 改めてDBのログを収集し、最後の調整に入る。
  • sysctl.confでTCP周りの設定を調整する。
  • メンバーがクエリを結構大胆に変更したりして、10000点弱までスコアが伸びる
17〜18時頃
  • 再起動テストをするとスコア激減してあせる。my.cnfが反映されていなかったことが発覚するが、反映しても再起動後スコアが落ちる。
    (終了後にmysqlのウォームアップが原因と知りとても悔しかった)
  • php7を入れたくなる衝動にかられるが、メンバーに止められやめる。

結果

最終スコアは7000点ぐらい(詳細は記録し忘れました)

最高スコアが10000点弱いってるだけに悔しかったです。またやたらと「タマキ」が表示されてbench結果が伸びない事象に遭遇し苦しめられました。ほかのチームも結構でててたみたいですね。

まとめ

ISUCONに初参戦し、見事に砕け散りました。

個人的にはWebに対する知見があまりないなか思ったより戦えたように感じ、少し自信がつきました。

もともとは3,4ヶ月前にくらいから同じ社内のメンバーの呼びかけで過去問を解いたりして勉強をしてきたのが予選で大きく役にたったと思います。

めちゃくちゃ疲れましたがとても楽しかったです。来年もあるなら参加して予選突破を目指したいと思います!