Redisでデータをzip圧縮して格納するとどれくらいメモリ容量が減るか検証


圧縮するとメモリ容量を節約できるのはわかっていたんだけど、元のデータ量が大きいほど効果がありそうだったので、だいたいどれくらいかなって検証。

検証方法

  • ランダムな日本語(ひらがな)1〜100,000,000文字を生成してdict(hash)に格納したものを以下4つの方法でRedisに登録して、used_memoryの変化量を測定。
    • データそのままSET(これを基本値とする)
    • データそのままHSET
    • データをjsonエンコードしてSET
    • データをjsonエンコードしてから圧縮してSET
  • 各結果のused_memoryを基本値で割った値を目視。このとき、1より大きければ基本値より容量が増えており、1より小さければ容量が減っている。値が小さければ小さいほど、メモリ容量の節約効果が高いということになる。
  • 連続で処理を実行していると時々おかしな値が出ることがあるので(原因は不明)、 テストデータを3回生成×同じテストデータを3回登録してテスト結果をとり、他と比べて明らかに異常な値が出た結果は捨て、他とだいたい同傾向を示しているなかの、一番最後の値を検証値としてとる。(本当は平均とかとるべきなのかもだけど面倒くさい)
  • 以上をpythonとシェルスクリプトでゴリゴリ書いて実行。

検証環境

OS: Debian GNU/Linux 9 (stretch)
Redis: Version 3.2.6 (デフォルト設定のまま、localhostで稼働)
python: Python 3.5.3

その他細かいことはこちらに
https://github.com/robitan/redis-kensho/blob/kensho-compressed/result_compressed/run-info.txt

検証結果

文字数(日本語ひらがな) そのままHSET / そのままSET jsonをSET / そのままSET jsonを圧縮してSET / そのままSET
1 1.000649 1.000649 1.000649
10 1.000648 1.001081 1.000648
100 1.005793 1.008796 0.997640
1,000 1.005395 1.128072 0.961838
10,000 1.003097 1.763680 0.706436
100,000 1.000356 1.986330 0.364987
1,000,000 1.000036 2.793968 0.356083
10,000,000 1.000003 1.874999 0.375001
100,000,000 - - -
  • 100〜1,000文字は、多少軽くはなっているかなってくらい。
  • 10,000文字くらいだと3割減。
  • 100,000文字以上では半分以下になる。
  • 100,000,000文字はエラーが出たので結果なし。Redisの許容量を超えたっぽい。
  • 今回の検証には直接関係ないけれど、圧縮しないほうのjsonが10,000〜10,000,000文字でおかしな動きを見せている。謎。

まとめ

ある程度までは元のデータ容量が大きいほど削減効果がある感じ。削減効果は最大で6〜7割減くらいだった。今回は単純な文字列がひたすら並んでいるテストデータだったけれど、データのタイプによってはもう少しいけそうな気もする。

Redisの容量を削減したい場合、1つのキーあたりに格納するデータが 10KB〜100KBを超えるのを目安 にして、圧縮することを検討してもいいかもしれない。

検証コードなど

ここ。(よけいなものもまじってます)
https://github.com/robitan/redis-kensho/tree/kensho-compressed

検証結果のrawデータは以下。
https://github.com/robitan/redis-kensho/tree/kensho-compressed/result_compressed