圧縮転送 - MessagePack-RPC for Ruby 0.3.0
高速な非同期メッセージングライブラリ MessagePack-RPC for Ruby をアップデートしました。互換性はだいたい維持されています。
gem install msgpack-rpc
今回の目玉は、圧縮転送のサポートです。メッセージをdeflate(zlib)を使って圧縮します。
使い方
いつも通りにKey-valueストアを作ってみました。
↓このように、Client#overメソッドを使って、圧縮オプションを指定します。
require 'msgpack/rpc' # gem install msgpack-rpc cli = MessagePack::RPC::Client.new('127.0.0.1', 9090) # テキスト(HTML)ファイルを読み込む http://preferred.jp/index.html を使用 text = File.read("index.html") # テキスト圧縮なし cli.call(:set, "k1", text) # 6608バイト -> <- 5バイト cli.call(:get, "k1") # 11バイト -> <- 6601バイト # テキスト圧縮あり cli.over(:tx_deflate).call(:set, "k2", text) # 2609バイト -> <- 5バイト cli.over(:rx_deflate).call(:get, "k2") # 11バイト -> <- 2604バイト cli.over(:rx_deflate).call(:get, "k2") # 11バイト -> <- 68バイト # 画像(PNG)ファイルを読み込む http://preferred.jp/labslogo_small.png を使用 image = File.read("labslogo_small.png") # 画像圧縮なし cli.call(:set, "k3", image) # 7753バイト -> <- 5バイト cli.call(:get, "k3") # 11バイト -> <- 7746バイト # 画像圧縮あり cli.over(:tx_deflate).call(:set, "k4", image) # 7716バイト -> <- 5バイト cli.over(:rx_deflate).call(:get, "k4") # 11バイト -> <- 7710バイト cli.over(:rx_deflate).call(:get, "k4") # 11バイト -> <- 78バイト cli.close
ここではデータを set するときは送信するデータを圧縮し、get するときは受信するデータを圧縮しています。
まずテキストの圧縮率を見てみると、圧縮無しでは6608バイトだったデータが、圧縮を有効化すると2609バイトまで縮んでいます。
setに対して、getは2回行っています。1回目は2604バイトですが、2回目はさらに68バイトまで縮んでいます。
これはTCPコネクションを1本まるまる圧縮しているためです。2回目は1回目の圧縮で作成された辞書を使って圧縮するので、圧縮率が高くなります。
この特徴があるので、場合によっても画像ファイルでも縮みます。
画像ファイルだと1回目の送信では7753バイトから7716バイトにしか縮みませんが、2回目のgetだと、78バイトまで縮んでいます。
同じデータを2回続けて送るというケースは稀かもしれませんが、1つのデータのエントロピーが小さくても、複数のデータの間で傾向が似ていれば圧縮率が高くなるという仕組みです。
サーバ側は何も変わりません。圧縮の有効化・無効化は、クライアント側で指定します。
require 'msgpack/rpc' # gem install msgpack-rpc class KVServer def initialize @hash = Hash.new end def get(key) @hash[key] end def set(key, val) @hash[key] = val nil end end svr = MessagePack::RPC::Server.new svr.listen '0.0.0.0', 9090, KVServer.new svr.run