F.Ko-Jiの「一秒後は未来」

10年に1度の台風 vs 電車遅延なう負荷対策

10年に1度の大型台風が通勤ラッシュを直撃したために電車遅延なうのサイトが繋がりにくい状態になっていました。

これまでにも何度か台風等によるアクセス増はあったので、その都度チューニングをしたり、処理の見直しをしたりしていましたが、今回の負荷は過去最大のものだったようで。

というわけで昨日は朝からせっせと負荷対策をやっていました。

ちなみに、電車遅延なうのサーバ環境は「さくらのVPS」の1G、Web サーバは Apache のみで、プログラムは PHP、データベースは利用しておらず、色々なデータのキャッシュに memcached を使用しています。

CSS と画像ファイルを Amazon S3 へ

まずサイトにアクセスしてみると、HTML はなんとか表示されても CSS や画像ファイルが読み込めない状態になっていたので、CSS と画像ファイルを Amazon S3 に置くように変更しました。

amazon-s3-traindelay.jpg

↑ バケットを作ってファイルをアップロードして、アクセス権を「Public」にすればOK。ファイルの URL は「Properties」で確認できます。

時間があれば nginx を入れてもよかったのですが、今回は時間がないのと、同じサーバに別のサービスがいくつか相乗りしているという理由で、手っ取り早く S3 にしておきました。

Apacheの設定をチューニング

静的ファイルへのアクセスはほぼ無くなりましたが、まだ Apache のプロセスが溜まり気味だったので MaxClients や MaxRequestsPerChild の値を増やすことに。

ロードアベレージとメモリの使用量を確認しつつ、最終的な設定値は以下のようになりましたが、あくまで参考程度に。

<IfModule prefork.c>
StartServers      10
MinSpareServers    5
MaxSpareServers   15
ServerLimit      256
MaxClients        40
MaxRequestsPerChild  3500
</IfModule>

相乗りしてるサービスのcronを一時停止

サーバのプロセスを確認してみると、別のサービスのバッチプログラムが作動している時にロードアベレージが上昇気味だったので、しばらくの間停止しておくことに。

リソースを共有しているので仕方ありません。

テキスト解析をYahoo!のAPIからMecabに変更

今回最も効果が高かったのは、テキスト解析処理を Yahoo! の API から Mecab に変更したことでした。

ざっくり電車遅延なうの処理の流れを説明すると、

  • Twitter の API から検索結果を取得
  • 取得したツイートをテキスト解析 API で解析
  • 解析結果の中から路線名を探す

という流れなのですが、調べてみるとテキスト解析の処理のところで時間がかかり、Apacheのプロセスが溜まるという状態になっていました。

テキスト解析処理をスキップすれば表示は軽くなるのですが、解析しないと遅延路線の抽出ができなくなるので、自前で形態素解析ができる Mecab を導入することにしました。

まずは Mecab 本体と IPA辞書をインストール。

$ cd /var/tmp/
$ wget https://mecab.googlecode.com/files/mecab-0.996.tar.gz
$ tar xvzf mecab-0.996.tar.gz
$ cd mecab-0.996
$ ./configure --enable-utf8-only
$ make
$ sudo make install
$ cd ../
$ wget https://mecab.googlecode.com/files/mecab-ipadic-2.7.0-20070801.tar.gz
$ tar xvzf mecab-ipadic-2.7.0-20070801.tar.gz
$ cd mecab-ipadic-2.7.0-20070801
$ ./configure --with-charset=utf8
$ make
$ sudo make install

それから PHP から Mecab を使うために php-mecab もインストールしておきます。

$ cd
$ git clone git://github.com/rsky/php-mecab.git
$ cd php-mecab/mecab/
$ phpize
$ ./configure
$ make
$ sudo make install

そして /etc/php.d/mecab.ini に「extension=”mecab.so”」と書いて保存。

$ sudo vim /etc/php.d/mecab.ini

Apache を再起動しておきます。

$ sudo /etc/init.d/httpd graceful

プログラム中では以下のようにすれば簡単に Mecab を使えます。

$mecab = new Mecab_Tagger();
$words = $mecab->split("解析したい文章。");

結果、テキスト解析処理がかなり高速に。。

ただ、Mecab の場合はユーザ辞書登録をしないと上手く路線名を抽出できないというトレードオフがあって、そこだけちょっと大変です。Yahoo! の API は路線名もほぼ認識して抽出してくれるので便利です。

ちなみに Mecab のユーザー辞書を使う場合は、まず以下のような CSV ファイル(一例)を作成して、

$ cat dicts/user.csv
東西線,,,3000,名詞,固有名詞,一般,*,*,*,東西線,トウザイセン,トウザイセン
副都心線,,,3000,名詞,固有名詞,一般,*,*,*,副都心線,フクトシンセン,フクトシンセン

この CSV ファイルを以下のコマンドで辞書ファイルに変換します。

$ /usr/local/libexec/mecab/mecab-dict-index \
 -d /usr/local/lib/mecab/dic/ipadic \
 -u dicts/user.dic -f utf-8 -t utf-8 dicts/user.csv

ファイルのパスは適宜自分の環境にあわせて置き換えてください。

あとは「/usr/local/etc/mecabrc」ファイル内にある「userdic」に、生成した辞書ファイル(.dic)のパスを指定すればOKです。

こんな感じで色々と負荷対策をした結果、 Google アナリティクスのリアルタイム解析で 2,000 ユーザーくらいのアクセスも難なくさばけるようになりましたが、しばらくすると通勤ラッシュも台風も去ったため、アクセス数も通常状態に落ち着きました。

これであと10年は大丈夫ですかね。。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

著者について

fkoji

F.Ko-Ji

Webエンジニアやってます。最近は ドットインストール の開発がお仕事です。その傍ら、個人で Meity電車遅延なう梅酒.in#グラドル自画撮り部 の部室といったネットサービスを開発・運営してます。梅酒と草野球とリアル脱出ゲームが好きです。

» 詳しいプロフィールや運営サービスの一覧など