ISUCON5予選参加記

チーム「:sushi:食べたい」でISUCON5の予選に参加してきた。 最終スコアは4955点で予選敗退でした。 全体でどのくらいの順位だったのか知りたかったけど公開はされないらしい。 予選突破にはあと3倍弱くらい必要だった。 チームメンバーと共通している言語がなかったのでgolangでやったけどgolang力が足りな過ぎた。

事前にやったこと

bitbucketのwikiに下記の様なことをまとめたりした。

  • 公式サイトやslideへのリンク
  • プロファイリング系ツールのまとめ
    • pprofの使い方
    • qt-query-digestでslow-query-logを集計
    • goaccessでnginxのログを集計
  • チューニング系のまとめ
    • 速度チューニングしたmy.cnf
    • limits.conf, sysctl.confなどの秘伝のタレ
    • golangunix domain socketでいろいろ繋ぐコード
  • チームメンバーの公開鍵
  • 運営からの連絡
  • 当日の時間配分

isucon4の予選をやりながらまとめたのでubuntu寄りの情報になっていなくて本番はスロースタートになってしまったのが残念だった。 ubuntuが来ることは公開されていたのでもう少しubuntuで簡単に展開できるようにしておけばよかった。 当日の情報もwikiに追記していけば良かったので最低限ページを用意していたのは良かった。

当日やったこと

土曜日に参加したので11:00からスタートだった。LINEカフェで参加していて1時間くらい空き時間があったので、まとめ切れていなかったlimits.confのメモリ周りの記事を見たり、tagomorisさんとkamipoさんのインタビュー記事を読んでどんな問題が出るかみたいな話をしていた気がする。

序盤

とりあえず、初期状態でベンチを回してスコアが200くらいだった。

役割分担的には自分がプロファイル系ツールを用意して、ほかの二人がアプリの中身を読んだり、サーバーを用意したりしてもらった。

ソースコードと設定ファイルはプライベートリポジトリで管理しながらすすめて、割と並列で動けるようになっていた。

ubuntu 15.04力が低すぎてsystemdとかapparomorとか全然わからなかったけどインフラ得意なメンバーが全部やってくれて圧倒的感謝しかなかった。

ベンチマーク動かしつつ、色々設定ファイル変えながらメトリクスのインストールスクリプト整えるのに1時間半くらいかかってしまっていたのでここはもう少し準備しておくべきだった。このあたりで加えた変更はnginxのプロセス数を増やしたり、mysqlにインデックス張ったりした。isucon4予選でしか練習してなかったのでschema.sqlにインデックス張れば反映されると勘違いしていたので実はこの時点張ったと思っていたインデックスは貼れていなかった。しかも後で見てみるとチャットにメンバーがヒントになりそうなこと書いていたりしたので自分もう少し早く気づけという感じだった。この時点でたしかスコアは700くらいだったと思う。

中盤

/とかrelationsとかが重いということが集計からわかっていたのでそのあたりを潰すためにsqlを書き換えたりしていた。one/anotherを片方だけにする派とinsert減らす派がいたっぽいけど後者だった。insertほとんどないので前者の方が早くなっていた感ある。

この後もひたすら重いと出ていたentriesとcommentsのjoinやentriesを1000件とってきているところをうまく書き換えられないかとやっていたけどsql力が低くてうまくいかなかった。sql書き換えている途中でalterじゃないとだめだと気付いたので適用してスコア1200くらいになっていた。

終盤

中盤からメンバーにやってもらっていたusers周りのキャッシュのベンチが通ったのでマージしようとするも変更が割とあって恐怖だったので一番効くらしいrelationsのキャッシュだけ拝借することにした。この変更が割と効いてスコアが4200くらいになった。

残り時間が少なくなってきたのでやればスコア上がる系のmysqlにsocketで繋ぐなどの変更を加えたところ、my.cnfが反映されていないという疑惑が出てきた。確かにmy.cnfに書いてあるsocketの位置と実際に作成されているsocketの位置が異なっていたが、slow-query-logの設定などは反映されていたのでおそらく別の設定ファイルで上書きされていたとかだろうか(時間もなかったので調べられていない)。my.cnfを一か所にまとめたところ今度はmysqlが起動しなくなってこの時点で終了30分前とかだったので、これはやばいと切り戻して、アプリの方を書き換えてsocketで繋ぐようにした。

終了1時間でやることは事前に決めていたのでメトリクス系ツールやログの出力をoffにしたり、再起動してちゃんと動くかなどを確認した。10分前で最後のベンチ回すか、といって回したところ数回に一回出るタマキのエラーに襲われて、これまたやばいとなったけどすぐに回し直したら正常に終了し、正の得点で終えることができた。ログを切った効果で若干スコアが上がり最終の4955となった。

まとめ

isucon4予選とは真逆な感じのアプリでいろいろ入り組んでいて面白かった。 基本的に地力がが足りていない感じだったので、来年までに鍛えておきたい。

Ionic Framework+coffeescript

Ionic Frameworkのインストール

# sudo npm install -g cordova ionic

ひな形作成

$ ionic start ionic-coffee blank
$ cd ionic-coffee/ionic-app-base-master/

gulpfile.jsとapp.jsの変換

coffee-scriptを入れる

$ npm install --save-dev coffee-script     

js2coffeeのインストール

# sudo npm install -g js2coffee

変換

$ js2coffee gulpfile.js > gulpfile.coffee
$ mkdir coffee
$ js2coffee www/js/app.js > coffee/app.coffee

gulpfile.jsの書き換え

$ vim gulpfile.js
require('coffee-script/register');
require('./gulpfile.coffee');

coffeescriptコンパイル

gulp-coffeeを入れる

$ npm install --save-dev gulp-coffee

gulpfile.coffeeの編集

~~~
coffee = require('gulp-coffee')
~~~
~~~
gulp.task 'coffee', ->
  gulp.src('./coffee/*.coffee')
  .pipe(coffee({bare: true}).on('error', gutil.log))
  .pipe(gulp.dest('./www/js/'))
~~~

ブラウザで確認

ripple emulator を入れる

# npm install -g ripple-emulator

確認

$ gulp coffee
$ ripple emulate --path www/

CentOSでDockerとChef - その2 -

Chefのインストール

  • Ruby

      wget cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.1.tar.gz
      tar -xvf ruby-2.1.1.tar.gz 
      cd ruby-2.1.1
      ./configure 
      make
      sudo make install
    
  • gem

      wget production.cf.rubygems.org/rubygems/rubygems-2.2.2.tgz
      tar -xvf rubygems-2.2.2.tgz 
      cd rubygems-2.2.2
      sudo /usr/local/bin/ruby setup.rb 
    
  • Chef

      sudo /usr/local/bin/gem install chef
      sudo /usr/local/bin/gem install berkshelf 
      sudo /usr/local/bin/gem install knife-solo
    

コンテナにchefのインストール

  • コンテナのIPアドレスの確認

      sudo docker ps
    
      CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                   NAMES
      d7e189271f40        sshd:latest         /bin/sh -c /usr/sbin   24 minutes ago      Up 24 minutes       0.0.0.0:49157->22/tcp   sharp_franklin    
    
      sudo docker inspect sharp_franklin | grep IPAddress
    
      "IPAddress": "172.17.0.2",
    
  • knife solo prepare

      knife solo prepare chef@172.17.0.2  
    

次はchefでnginxでも入れてみる

CentOSでDockerとChef - その1 -

Dockerのインストール

sudo yum install docker-io --enablerepo=epel
sudo /etc/init.d/docker start

ひな形の作成

  • ホストでの作業

  • パスフレーズなしで鍵を作る

      ssh-keygen -t rsa
    
  • Dockerfile

      FROM    centos
      MAINTAINER      nel215
    
      RUN     yum update -y
      RUN     yum install -y openssh-server
      RUN     yum install -y sudo
      RUN     yum install -y passwd
    
      # create user
      RUN     useradd chef
      RUN     passwd -u -f chef
    
      # sshd
      RUN     sed -i -e "s/^#RSAAuthentication yes/RSAAuthentication yes/g" /etc/ssh/sshd_config
      RUN     sed -i -e "s/^#PubkeyAuthentication yes/PubkeyAuthentication yes/g" /etc/ssh/sshd_config
      RUN     sed -i -e "s/^UsePAM yes/UsePAM no/g" /etc/ssh/sshd_config
      RUN     mkdir -p /home/chef/.ssh
      ADD     ./id_rsa.pub /home/chef/.ssh/authorized_keys
      RUN     chown -R chef /home/chef/.ssh
      RUN     chmod 700 /home/chef/.ssh
      RUN     chmod 600 /home/chef/.ssh/authorized_keys
      RUN     /etc/init.d/sshd start
      RUN     /etc/init.d/sshd stop
    
      RUN     echo "chef      ALL=(ALL) ALL" >> /etc/sudoers.d/chef
    
      EXPOSE  22
      CMD     /usr/sbin/sshd -D
    
    • 作った公開鍵を適当なところに置く
  • selinux無効化

      sudo vim /etc/selinux/config
    
      SELINUX=disabled
    
  • build->run

      sudo docker build -t sshd .
      sudo docker run -d -P sshd 
      sudo docker ps
    
      CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                   NAMES
      a8bf2a22c09d        sshd:latest         /bin/sh -c /usr/sbin   19 minutes ago      Up 19 minutes       0.0.0.0:49156->22/tcp   stoic_feynman    
    
  • sshで接続

      ssh chef@localhost -i ~/.ssh/id_rsa -p 49156  
    

続きは後日…

参考