luaでのjsonデコードのオーバーヘッドが無視できないレベルだったのでMessagePackを採用したらスループットが3.6倍になった


とあるAPIサーバをluaで実装していたら思うようにスループットが伸びなかったので、デバッグしてみたところ、jsonデコードの部分で遅くなっていた模様。

結果、json4lua -> lua-cjson -> mpluaという風にライブラリを変えてデバッグしてみたところ、mpluaを使った場合が一番スループットが高かったのでjsonを止めてMessagePackを採用したところリファクタリング始める前に比べると3.6倍までスループットが向上した。

広告

環境

  • OS: CentOS 6.3(64bit)
  • Lua: 5.1.4

インストール

lua-cjson

lua4json -> lua-cjsonにするだけでも2.5倍弱程度スループットが向上した。
efelix/lua-cjson · GitHub

lua-cjsonのインストールはすんなり行くのと、ライブラリのAPI自体もlua4jsonと変わらないので割愛します。

mplua

libmessagepackのlua bindingであるmpluaを使ってみました。
nobu-k/mplua · GitHub

libmsgpack.hppが必要になるので、下記をDLし、コレ自体もインストールしておきます。
msgpack-0.5.7.tar.gz

./configure && make && make install

コンパイル、インストールまでは上記でいけるんですが、msgpack.soが/msgpack.soに出来てしまうため(特にreadmeには書いてなかったけど、prefixなどが指定できたんだろうか。。。)、移すのとlibmsgpack.so.3を配置し直す。

# mv /msgpack.so /usr/lib64/lua/5.1/
# ln -snf /usr/local/lib/libmsgpack.so.3 /usr/lib64/

これで、lua側から正常に読み込める様になったと思います。

local mp = require('msgpack')
local packed = mp.pack({ hoge = 'aaa', foo = {1,2} })
local unpacked = mp.unpack(packed)

感想

lua-cjsonにすることで元々の2.5倍弱になったが、MessagePackで3.6倍程度まで向上した。

初めてキャッシュのデータとしてMessagePackを使ってみたけど、キャッシュする側(今回はPerlのData::MessagePackを使用)も利用する側も苦労すること無く利用することができ、jsonからのリプレイスも比較的簡単なのでオススメ。

ただ、1点ハマったところとして、これはMessagePackが悪いわけではなく、MessagePackのデータをRedisから取ろうとしたところクライアントライブラリがバイナリセーフではなく、うまくデコード出来なかったところ。コレは次回書く。(はず

追記: 2013.05.10 11:55
バイナリセーフの問題は、ライブラリ側でオプションで対応されてたので自分が説明をちゃんと読んでいなかったのだ問題だったorz

追記: 2013.05.10 18:49
一部jsonデコードしている部分が残っており、全てMessagePackに変更したところ最初から3.6倍まで向上した!

関連記事