ISUCON4で開幕暫定一位を獲得

ISUCON4 の予選(総合の7位)と本選(23位)に参加してきました。

予選

  • limits.conf, sysctl, nginx.conf の最適化
  • MySQL のインデックス追加
  • Unix Domain Socket を使うように Go アプリを修正
  • CSS ファイルをひとつにまとめる

他 Redis, Varnish を差し込もうとしましたが、デバッグに追われ時間切れでした。

本選

  • limits.conf, sysctl, nginx.conf の最適化(なぜ expires を設定しなかった)
  • データを複数台の Redis に分散して使うように Go アプリを修正
  • 安定しないスコアに法則性を見出そうとしてデプロイとロールバックを繰り返していました

/asset に 17s かかってるログを見たのに expires を設定しなかったんですよね。愚か。

 

開幕暫定一位とは

参加するからには何かしら結果を残したいという思いから生まれた案が開幕暫定一位でした。
これは文字通り「競技の開始直後に他のどのチームよりも早くベンチマークを実行して暫定的なトップになる」というものです。以下の画像を参照。
 

f:id:Ajido:20141113004045p:plain
予選で開幕暫定一位を獲得したMEAN普及委員会

 

f:id:Ajido:20141113004341p:plain
本選で開幕暫定一位を獲得したMEAN普及委員会

 

開幕暫定一位を獲得するために

 
レギュレーションが発表され AMI ID が判明次第、即インスタンスを起動できる準備を整える。

# fabfile.py

def ec2_launch(ami_id):
  launch_args = ' '.join([
    '--image-id', ami_id,
    '--security-groups', 'isucon',
    '--instance-type', 'm3.xlarge',
    '--no-ebs-optimized',
    '--region', 'ap-northeast-1',
    '--key-name', 'ajido',
    '--block-device-mappings', '\'[{"DeviceName":"/dev/xvda","Ebs":{"VolumeType":"standard","DeleteOnTermination":false,"VolumeSize":8}}]\''
  ])
  local('aws ec2 run-instances --count 1 ' + launch_args)

 
ベンチマークの実行方法を推測する。コマンドは毎回異なるようなので、臨機応変に対応する。
当日直前に公開されるレギュレーションをチェックしている暇はないので、仕様は -h から読み取る。

## マニュアルに記載されている実行方法
$ sudo su - isucon
$ ./benchmarker bench --api-key XXXXXXXX

## Switch User を使わず一行程で実行する
$ sudo -u isucon /home/isucon/benchmarker bench --api-key XXXXXXXX

 
初期実装のバグに対応する。このあたりが一番楽しい。結構焦ります。
まず予選では直接ベンチに関係しませんが、障害がひとつありました。

## supervisor で実装が切り替えられない → 起動に成功するけど落ちる → EADDRINUSE っぽい → プロセスチェック
# Unicorn が起動してたので殺す
$ sudo netstat -apn | grep LISTEN

 
本選ではスコアサーバを含め、初期実装には三つの障害がありました。

## "Connection refused" → 80をチェック → LISTEN してない → nginx を起動
$ sudo lsof -i:80
$ sudo service nginx start

## "< invalid" なんとかで失敗する → アプリの初期実装にバグがありそう → Go に切り替える
$ sudo service supervisord stop
$ sudo vim /etc/supervisord.conf
$ sudo service supervisord start

## wsの接続に失敗してベンチが終了する → スコアサーバの問題っぽいので無限ループにして放置(ごめんなさい)
$ while :; do ./benchmarker remote -H XXXXXXXX; done

 
予選・本選共に開始数分でベンチを実行してスコアを送ることができました ╭( ・ㅂ・)و ̑̑ グッ !
 
予選は初期実装に障害がなかったものの競合が多く、スクショを取った直後には開幕暫定二位が出現していました。対して本選は競合が少なかったものの、初期実装の障害の多さにはテンションが上がりっぱなしでした。
 

最後に

 はじめての参加でしたが、本当に楽しいイベントでした。運営スタッフの皆さん、ありがとうございましたmm