ログをLTSVやJSONで保存した場合のサイズ比較

追記(2/17)

変換スクリプトを見せてほしい、という要望があったので、 https://gist.github.com/stanaka/4967403 に上げておきました。ltsvを読み込んでオプションで指定したフォーマット(デフォルト JSON)に変更します。

追記ここまで

LTSVの盛り上りも収束してきていますが、サイズに関する懸念があがっていたので、確認してみました。

手近にあったアクセスログ 186万件ほどを対象に、

  • ssv .. Combined Log Formatの拡張で、ラベルなし (レスポンス時間とか10個ぐらいのフィールドを拡張しています)
  • json .. ラベルあり
  • ltsv .. ラベルあり

の3パターンで試してみました。

まずは行数を確認しておきます。

% wc -l access_log.json
1861706 access_log.json

未圧縮だと、

access_log.ssv    818,729,505 (781M)
access_log.json 1,282,452,709 (1.2G)
access_log.ltsv 1,111,017,347 (1.1G)

でした。1G前後でそれなりのサイズのログですね。ssvとltsvの差は300M程度。jsonにするとさらに150Mぐらいでかくなってます。

最初にgz圧縮してみると、

access_log.ssv.gz  136,835,984 (131M)
access_log.json.gz 152,432,366 (146M)
access_log.ltsv.gz 146,072,000 (140M)

131M〜146Mでだいぶ差が縮まりました。1割程度の差を問題視するかどうかはポリシー次第ですが、最近では1割程度は誤差なんじゃないかと思います。

さらにbz2圧縮してみると、

access_log.ssv.bz2   93,621,212 (90M)
access_log.json.bz2 100,358,979 (96M)
access_log.ltsv.bz2  98,269,135 (94M)

と差は5%とさらに縮まりました。スペースを気にしつつ、bz2の圧縮時間に耐えられるなら、これもアリだと思います。

ついでなので、7z圧縮してみました。manの例にも載ってた推奨(?)のオプションでやってみました。

7z a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=on access_log.ltsv.7z access_log.ltsv

結果は、

access_log.ssv.7z  71,518,534 (69M)
access_log.json.7z 79,827,214 (77M)
access_log.ltsv.7z 77,032,835 (74M)

という感じで、さらに小さくなりました。差はbzip2に比べると、むしろ広がってますね。

まとめ

伝統的なCombine Log Formatの拡張、JSON, LTSVで比べてみましたが、JSON, LTSVともに圧縮すれば1割程度の増加で済むので、JSONにせよLTSVにせよ、気にせずにラベルを付けて、使い勝手重視で行くのがよいんじゃないでしょうか。