LoginSignup
2
1

More than 5 years have passed since last update.

redis-objects de Hash

Posted at

redis-objectsでHashを扱う場合のちょっとしたメモ書きです。

Redis::Objects

Redisで扱えるデータ型

REDIS_CLASS_NAMES = [:Counter, :HashKey, :List, :Lock, :Set, :SortedSet, :Value]

https://github.com/nateware/redis-objects/blob/master/lib/redis/objects.rb

https://github.com/nateware/redis-objects/blob/master/lib/redis/objects/hashes.rb
のおかげでRedis::Objectsをincludeすれば
簡単にRedisのHashを扱えるようになります。
実際のredisへの操作は
https://github.com/nateware/redis-objects/blob/master/lib/redis/hash_key.rb
で行うようです

HashKey

Redis::Helpers::CoreCommandsをincludeしていますので、
storeメソッドでredisのHSETコマンドを実行して、Hashを登録したり、
valuesメソッドでredisのHVALSコマンドを実行して、Hashの値を取得できたりします。

また、Enumerableをincludeしていますので、

...
    def all
      h = redis.hgetall(key) || {}
      h.each{|k,v| h[k] = unmarshal(v, options[:marshal_keys][k]) }
      h
    end
...
    def each(&block)
      all.each(&block)
    end
...

eachメソッドを使った際にkeyとvalueのペアがhashの配列として
取得できたりします。(たぶん)

Redisクライアント(redis-cli)で接続して確認

キーの一覧
>hkeys [hash name]
hashのキー一覧
>hvals [hash name]
hashの値一覧
>HGETALL [hash name]
hashのキーと値を交互に出力

ちなみに、
ActiveRecordを介して登録した場合は
モデル名:ID:指定したキー
という形になります。
https://github.com/nateware/redis-objects#option-1-model-class-include

また、プロジェクトや環境ごとにキーを区別したいときは
redis-namespace
も一緒に使うといいと思います。

ziplistとhashtable

hash-max-ziplist-entriesとhash-max-ziplist-value
を設定することでziplistを使うための閾値をあげることができます。

ziplistを使う

下記をredis.confに設定

hash-max-ziplist-entries 512
hash-max-ziplist-value 64

>redis-cli INFO memory

used_memory:1007360
used_memory_human:983.75K
used_memory_rss:4890624
used_memory_rss_human:4.66M
used_memory_peak:5134560
used_memory_peak_human:4.90M
total_system_memory:8589934592
total_system_memory_human:8.00G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:4.85
mem_allocator:libc

keyが500のhashを登録してみます。
>hashes=""
>for i in {1..500} ; do hashes="$hashes field-name-$i field-value-$i" ; done
>redis-cli HMSET hash01 $hashes

used_memory:1023840
used_memory_human:999.84K
used_memory_rss:4907008
used_memory_rss_human:4.68M
used_memory_peak:5134560
used_memory_peak_human:4.90M
total_system_memory:8589934592
total_system_memory_human:8.00G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:4.79
mem_allocator:libc

すると
1023840 - 1007360 = 16480 bytes

ziplistを使わない

下記をredis.confに設定

hash-max-ziplist-entries 50
hash-max-ziplist-value 5

>redis-cli flushall
>redis-cli INFO memory

used_memory:1007520
used_memory_human:983.91K
used_memory_rss:1974272
used_memory_rss_human:1.88M
used_memory_peak:1007520
used_memory_peak_human:983.91K
total_system_memory:8589934592
total_system_memory_human:8.00G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:1.96
mem_allocator:libc

>hashes=""
>for i in {1..500} ; do hashes="$hashes field-name-$i field-value-$i" ; done
>redis-cli HMSET hash01 $hashes

used_memory:1075664
used_memory_human:1.03M
used_memory_rss:2048000
used_memory_rss_human:1.95M
used_memory_peak:1075664
used_memory_peak_human:1.03M
total_system_memory:8589934592
total_system_memory_human:8.00G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:1.90
mem_allocator:libc

1075664 - 1007232 = 68432 bytes

ziplistを使った場合の16480bytesに対して、
使わない場合は68432bytesとなりました。
少ないデータ量の場合はziplistを使ったほうがメモリ効率はよいようです。

データ件数を増やしてみましょう

ziplistを使わない

for j in {1..10000} ; do 
  hashes=""
  for i in {1..500} ; do 
    hashes="$hashes field-name-$i field-value-$i"
  done
  redis-cli HMSET "hash$j" $hashes 
done
used_memory:1007392
used_memory_human:983.78K
used_memory_rss:3211264
used_memory_rss_human:3.06M
used_memory_peak:2322992
used_memory_peak_human:2.22M
total_system_memory:8589934592
total_system_memory_human:8.00G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:3.19
mem_allocator:libc
used_memory:1279824
used_memory_human:1.22M
used_memory_rss:2285568
used_memory_rss_human:2.18M
used_memory_peak:1279824
used_memory_peak_human:1.22M
total_system_memory:8589934592
total_system_memory_human:8.00G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:1.79
mem_allocator:libc

ziplistを使う



redis-objectsを使う場合は

2
1
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
2
1