isucon3 予選に参加して惨敗してきた話

選択言語は PHP。スコアは、FAIL でまくって 0。
完全に InnoDB Memcached の罠にはまってました。

PHP 使ったチームだと、 @dekokun が素敵なエントリを書いているので、それを読むのが良いと思う。
ISUCON予選にPHP実装で参加して3位になりましたーやったことなどまとめ


以下、メモ的にやったことを。

環境構築

  • webapp 以下を全て git に
  • screen 入れた
  • zsh 入れた

このへんは当たり前すぎて書き忘れてた。

php 5.5.4 に入れ替え

OpCache 使ってみたかった。
反省はしてない。

php-build でコンパイルして、 phpenv で管理。

curl https://raw.github.com/CHH/phpenv/master/bin/phpenv-install.sh | bash
mkdir $HOME/.phpenv/plugins
cd $HOME/.phpenv/plugins
git clone git://github.com/CHH/php-build.git

echo 'export PATH=$HOME/.phpenv/bin:$PATH' >> .zshrc
echo 'eval "$(phpenv init -)"' >> .zshrc

コンパイル時には --with-apxs2 付けないと apache2 モジュールがインストールされないのでした。

PHP_BUILD_CONFIGURE_OPTS='--with-apxs2' phpenv install 5.5.4 

このとき、システムの apxs が使われると、インストール時にパーミッションの関係上こけるので、
一時的に libphp5.so とそのディレクトリのパーミッションを変えてインストールしてから他所にコピーした。

nginx 利用

nginx で受けて、静的ファイル以外を apache + mod_php にリバースプロクシする形にしました
php-fpm 使った方が良かったのかも知れないけど、設定の仕方分からなかったのでした。

markdown 呼び出しを php Markdown

http://michelf.ca/projects/php-markdown/ こいつを使った。
いくつかサンプリングしてみて、同じ html を出力したので採用。
ベンチでこけたら別途考えようと。

user と is_private,created_at にインデックス追加

user, is_private, created_at すべてをまとめたマルチカラムインデックスはったらかえって遅くなったので、user と is_private,created_at は分離して張った。

memos.is_private = 0 の数を memcached に格納

初期化スクリプトで一度 SQL で入れた後は、 memcached (もどき) の increment で加算するようにした

1行目だけを格納したテーブル作った

初期化スクリプト内で memos.id と memos.content と SUBSTRING(memos.content, 0, INSTR(memos.content, '\n')) したものを格納するだけのテーブル作って、 INSERT SELECT で流し込み。

POST /memo で両方に追加するよう変更。

参照時は JOIN して取り出し。

今から考えると memos にカラム追加すれば良かったはずなのに、焦りのあまり訳の分からない実装した感ある。

まとめ

実質一人だったので時間無かった。というのは言い訳にすらならず、完全に計測と分析が足りなかった。

成長してないな−。自分。。。

2013/10/07

git とか、 php のインストール方法について追記した。