「ISUCON7」 予選突破を振り返ってみた

こんにちは。株式会社Craft Eggにてサーバーサイドのエンジニアとして働いている山村と申します。
この度は、サイバーエージェント社内メンバー (うち2名がスマートフォンゲーム&エンターテイメント事業部(SGE)所属) で ISUCON7 予選を無事突破できたので、報告させていただきます。

1. チームメンバー紹介

サイバーエージェントグル―プに所属する2013年に同期入社したエンジニア3名でチームを組みました。

  • 榎本(株式会社サイバーエージェント 技術本部サービスリライアビリティグループ エンジニア)
    主にインフラとアクセスログ解析を担当しました。
  • 山﨑(株式会社サムザップ エンジニア)
    主にアプリとスロークエリログ解析を担当しました。
  • 山村(株式会社Craft Egg エンジニア)
    主にアプリとトラブルシュートを担当しました。

2.今回の予選について

参加場所:
今回の予選はチーム名「円山町」の通り円山町にある弊社オフィスから参加しました。このオフィスにはハニカム式レイアウトで机が配備されており、突発的な議論がしやすくとても便利でした。

準備したもの紹介

-Slack
あらかじめメンバー全員の招待まで終わらせておきました。
長くなりがちなログ解析結果などを、コードスニペット機能ですぐ貼り付けて共有できる点が、とても便利で気に入っています。

– Mackerel

更新頻度が1分なのでベンチ中の様子の観察には dstat を活用していたのですが、何か問題が起こった時の調査用に役に立つと思ったので導入しました。各種公式プラグイン (mackerel-plugin-linux, mackerel-plugin-mysql など) を有効にした設定ファイルを事前に用意し、使わせていただきました。

– ログイン方法

榎本に作ってもらった ECDSA 鍵と ~/.ssh/config をチーム内で共有し、ssh isu01, scp isu01 という感じでログインできるようにしました。細かいですが時間と手間を省き、オペミスを回避できるので良いです。

 

– デプロイ方法

今回は必要なAPIサーバー全台にコマンド一つ (make deploy) でデプロイされるように書いた、Makefile を先に作りました。前回の本選では、しょうもないデプロイミスをして貴重な時間を無駄にしてしまったので、反省を意味を込めて設定したのですが、大変便利だったのでおすすめです。

– 全体的な作戦

アプリケーション実装は Go で行こうと最初から決めていましたが、そこから先はボトルネックを発見して、順に直していく作戦でいきました。コードを見るとすぐ、色々直したいところは見つかってすぐ直したくなるんですが、最も深刻なボトルネックから解決していかないと、ベンチマーカーに対しての挙動が改善したか分からなくなると考えたためです。

– 競技中の状況

初期状態でのベンチマーカーを動かしたとき、最初のボトルネックは3号機のデータベースサーバー上りネットワーク帯域のようでした。

これをアプリ側のオンメモリキャッシュで解決した後、次にアプリケーションサーバーの上りネットワーク帯域にボトルネックが移りました。

ここで、アプリ側でのインチキ Etag + If-None-Match による 304 Not Modified を作戦を企みコードの修正を行ったのですが、うまく返すようにできず、榎本に別で進めてもらっていた nginx 設定変更で、初期アイコンや静的ファイルをベンチマーカーに好かれる Cache-Control ヘッダ付きで返すようにした設定のおかげで 304 率が上がり、ようやくアプリケーションサーバーとデーターベースサーバーの CPU ボトルネックに移り、ここから先はいつも通り N+1 クエリや無駄な INSERT, UPDATE の削減を行って、無事予選突破スコアを獲得することができました。

 

3. 予選後の課題について

– COUNT(*) が遅いのを直し方を研究

予選中にはここまで改良できなかったのですが、終了後の振り返りの結果、多くの他のチームが行なっていた COUNT(*) のクエリを消す改善について、InnoDB は実際に全てのインデックスをスキャンしないと件数が分からないというのを学びました。
参考にしたサイト:
漢(オトコ)のコンピュータ道: InnoDBでCOUNT()を扱う際の注意事項あれこれ。
http://nippondanji.blogspot.jp/2010/03/innodbcount.html

– ファイルアップロードの取り扱い方

Go 初期実装では、アップロードされたファイルの受け取り方が、フルバッファリングされていてヒープを無駄遣いするという仕組みになっていたようでした。

– 本選について

本選では、ボトルネックから直すことは予選と同じと考えているのですが、本選の問題の物量に負けず、手を止めず改善し続けられるよう頑張ろうと思います。

LINEで送る
Pocket

おすすめ記事