Webサーバのログをどうするか

  • ログは重要な営業資源だが、冗長度が高くて、場所を食う
  • ログの出力は、httpdのデータの流れとしては負荷が比較的低いほう

ということから、ログを処理しやすいカタチにどんどんいじってしまってよいのではないか、という流れで考えてみる。

  • ログを解析処理が容易な形式にリアルタイムで出力してしまうようなapacheのモジュールが欲しい>作れ>もしくはLogFormatディレクティブを工夫するだけでかなりイケるかも
  • rotateを工夫する。Yahooとかでは、最初からrotateはせずに、httpdを停止、再起動、キャッシュ読み込みする負荷(キャッシュ性能低下)を避けているが、前述のログ処理モジュールが出力先を随時変更していくのであればそれで十分である。(逆に、httpdの共有データとかがメモリリークなどで肥大していってメモリを圧迫する問題があるので、定期的に再起動はしなくちゃいけないことも多いんだけど(汗
  • 荒業として、ログをmemcachedに出力できないか?UserAgentとかrefererとかはhash値だけを記録するようにして(実際のUAとの対応を記録するテーブルは別に保存してもいい)レコードサイズの上限をだいたい決められないだろうか?メモリしか持たないでネットワークブートするマシンなら、NFSでログ領域を持つことになるが、NFSよりはmemcachedのほうが速くない?あ、そうか、pureなmemcachedはdumpできないんだっけか。単純にappendするだけなら、メモリ上にマップしたファイルをいじるdaemonを作るだけでいいのではないか?Tokyo Tyrantみたいなものも候補?
  • 10秒に一回、ダミーのアクセスをかますことにして、時刻(28バイト)は秒の差分(1バイト)だけしか記録しないとか、、できないか?
  • IP4アドレス(7から15バイト)は32ビット(4バイト)のintegerに変換
  • メソッド(GET/POST等)やステータスコードと転送バイト数はバイナリにする
  • referer, useragent, cookieなんかは、結局はユーザ、セッションの特定のためにあるわけで、ユーザ、セッションを認識して、そのツリー構造のポインタと、ユーザ・セッションの一覧だけを記録しとけばいいんではないだろうか?ロードバランサーで完全に振り分けられちゃうと厳しいけど、legacyなスクリプトでセッションを維持させたいなら、セッションが途切れないようなロードバランスが望ましいわけで、サーバをまたいでセッションをリアルタイムに追跡する必要は無いと思う。それこそkeepaliveの間だけでも、データをまとめちゃえればいいのではなかろうか。

調べていたら、mixiのエンジニアブログでmemcachedのプロトコル改変の動き(バイナリプロトコルへ)っていう記事を見つけました。へー、アスキーの文字列をparseする負荷が比較的デカいから、最初から内部表現でやりとりしたい、ってことですか。

(追記)
今となっては古臭いけど、Analogの内部データフォーマットとか、チェックしてみてもいいかもしれないな。