17
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

RubyのオブジェクトをMessagePack+LZMAでディスクに小さく保存する

Last updated at Posted at 2013-09-17

Rubyで中間データをディスクにダンプする場合

dump
require 'yaml'
File.open('hoge.yaml', 'w') { |f|
    f.write(hoge.to_yaml)
}

とやって保存したものを

load
require 'yaml'
hoge = YAML.load_file 'hoge.yaml'

などと書くことで、ディスクとメモリを容易に行き来できます。
yamlは人間の目にも比較的読みやすいため便利です。

MessagePack + LZMA圧縮

クローラなどで大規模なデータを処理する場合、ディスクの専有サイズが問題になることがよくあります。
そこでmsgpack+lzmaを使う事で従来より飛躍的にサイズを縮小することができます。
msgpackはJSONに近いセマンティクスを提供するオブジェクトのバイナリフォーマットです。バイナリである上、小さい数値データや真偽値などの保存に特に効果を発揮するフォーマットになっています。
lzmaは比較的最近開発された圧縮形式で、gzipよりは遅い圧縮速度と高い圧縮効率、圧縮効率の割に高速な展開速度を誇ります。(bz2の方が圧縮率では一枚上手だけど展開が遅すぎる)

msgpack, lzma共にRubyのネイティブエクステンションの形で提供されているため非常に高速です。

まずインストールは

$ gem install ruby-lzma
$ gem install msgpack

で行えます。そして

dump
require 'msgpack'
require 'lzma'
File.open('hoge.dump', "w") {|f|
  f.write LZMA.compress(hoge.to_msgpack)
}

のようにしてファイルに書き出せます。書いたものは

load
hoge = MessagePack.unpack(LZMA.decompress(File.read('hoge.dump')))

のように読み出せます。

サイズ比較

たまたま僕の手元に過去の一定時間のツイートを集めたjsonファイルが1MB近くあるのでこれを圧縮保存した物を比較します。

-rw-r--r--  1 kumagi kumagi 917013  9月 17 09:53 tweets.json # 元ファイル:ツイートのJSONデータ
-rw-r--r--  1 kumagi kumagi 962256  9月 17 09:57 tweets.yaml # ↑のデータをYAMLにしたもの
-rw-r--r--  1 kumagi kumagi  85998  9月 17 10:04 tweets.dump # ↑のデータをmsgpack+lzmaにしたもの

マーベラス。
大差ない記述量で使用するディスク領域が1/10以下になっています。
ダンプのデータを人間が目視で読めないという点を除いて、先に記述したYAMLの時と同様の使い勝手で利用できるのでおすすめです。

17
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?