以前 LVS + Ultra Monkey で負荷分散 (設定編) - 酒日記 はてな支店 で書いたように、Apache を LVS で負荷分散したのですが、この際にアクセスログを一つに (時系列を保って) まとめるにはどうすればいいか、ちょっと悩みました。
結局 Apache からパイプ経由で logger コマンドを起動して syslogd でログ取得ホストに飛ばす、ということをしたのですが、いくつか問題が。
- ログの先頭に syslogd の日付 (Jan 24 18:33:30 www1 logger: ) が付く → 集計の邪魔
- syslog は 1メッセージ 1024 byte までしか記録できないので、尻切れになる行が (稀にだけど) 発生する
- Linux の syslogd は書き込みの際に頻繁に sync するので、DISK IO が大量に発生して重い
特に最後のは、秒間数百リクエストを超えるような場合に結構負荷として効いてくるようで、なんとかしたいなと。
まず思いついたのは、syslogd から syslog-ng に乗り換えること。
ただ、運用中のサーバの syslog を入れ替えるのはちょっと億劫。現在 syslog で取っているログをすべて切り替えるのは面倒だし、Apache 以外のログはそれほど大量に発生するわけではないし。
で、スケーラブルWEBサイト を読んでいたら、The Spread toolkit を使うといいよ! みたいなことが書いてあったので実験してみた。
しかし、最近出てきた技術でもないのに、ググっても日本語の情報がさっぱり見つからないのは何故なんだろう。
おおざっぱに言うとこんな感じの構成になります。
- すべてのホストに spread デーモンが起動。一つのクラスタを構成する
- Apache は mod_log_spread (またはパイプ経由で外部プログラム) を使用し、localhost の spread にログをメッセージとして出力
- spread はマルチキャスト (またはブロードキャスト) で、クラスタにメッセージを流す
- spreadlogd (デーモン) は localhost の spread からメッセージを受信し、ファイルに書き込む
上記「localhost の」の部分は実は localhost でなくても構わないのだけど、話を単純にするためそうします。
クラスタ内に何台のホストがあっても、その間の spread のメッセージはマルチ(ブロード)キャストで流れるため、通信量が少なくて済む、というメリットがあるそうな。