0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Redisの挙動を実験

Posted at

はじめに

RailsでRedisを使うために挙動を確認しました。
Railsで使ってはいるのですが、薄めのラッパー関数でRedisのコマンドをほぼそのまま呼び出すだけなので、Redisに直接実行してるのと変わらないかと思います。

Redisはdockerで動かしています。

バージョン

  • Redis: v7.2
  • Rails: v7.0
  • redis-client(gem): v0.22.2

初期化

initializerでredisインスタンスを作ります。

redis_config = RedisClient.config(host: "redis", port: 6379, db: 1)
REDIS_DATA_STORE = redis_config.new_pool(timeout: 3, size: Integer(ENV.fetch("RAILS_MAX_THREADS", 5)))

基本構文

pry(main)> REDIS_DATA_STORE.call("SET", "id1", "some value")
=> "OK"
pry(main)> REDIS_DATA_STORE.call("GET", "id1")
=> "some value"

ハッシュ

基本的な使い方

pry(main)> hash1 = { "key1" => "value1", "key2" => "value2" }
=> {"key1"=>"value1", "key2"=>"value2"}

pry(main)> REDIS_DATA_STORE.call("HSET", "hid1", hash1)
=> 2

pry(main)> REDIS_DATA_STORE.call("HGETALL", "hid1")
=> {"key1"=>"value1", "key2"=>"value2"}

キーにシンボル使った場合、自動でstringのキーになる。

pry(main)> hash2 = { key1: "value1", key2: "value2" }
=> {:key1=>"value1", :key2=>"value2"}

pry(main)> REDIS_DATA_STORE.call("HSET", "hid2", hash2)
=> 2

pry(main)> REDIS_DATA_STORE.call("HGETALL", "hid2")
=> {"key1"=>"value1", "key2"=>"value2"}

一部を指定すれば、一部だけ更新される。

pry(main)> REDIS_DATA_STORE.call("HSET", "hid1", {"key1" => "new value1"})
=> 0

pry(main)> REDIS_DATA_STORE.call("HGETALL", "hid1")
=> {"key1"=>"new value1", "key2"=>"value2"}

ハッシュの中にハッシュは入れられない。

リストも同様に使えないので、使いたい場合はjsonにしてstringとして保存するか、内側のハッシュを別のキーで保存して、そのキーをトップのハッシュのvalueに保存する。

pry(main)> sub_hash = { subkey1: "sub value" }
=> {:subkey1=>"sub value"}

pry(main)> main_hash = { key1: "value1", key2: sub_hash }
=> {:key1=>"value1", :key2=>{:subkey1=>"sub value"}}

pry(main)> REDIS_DATA_STORE.call("HSET", "hid3", main_hash)
TypeError: Unsupported command argument type: Hash

Expire

3秒後に消える設定をした場合

def expire_test
  REDIS_DATA_STORE.call("SET", "expire_key1", "value1")
  REDIS_DATA_STORE.call("EXPIRE", "expire_key1", 3)

  4.times do |i|
    p "#{i} sec passed"
    p REDIS_DATA_STORE.call("GET", "expire_key1")
    sleep 1
  end
end
pry(main)> expire_test
"0 sec passed"
"value1"
"1 sec passed"
"value1"
"2 sec passed"
"value1"
"3 sec passed"
nil

途中でデータupdateした場合

EXPIREされないので、新たに設定が必要

def expire_test2
  REDIS_DATA_STORE.call("SET", "expire_key1", "value1")
  REDIS_DATA_STORE.call("EXPIRE", "expire_key1", 3)

  8.times do |i|
    p "#{i} sec passed"
    p REDIS_DATA_STORE.call("GET", "expire_key1")
    sleep 1

    REDIS_DATA_STORE.call("SET", "expire_key1", "updated value1") if i == 1
  end
end
pry(main)> expire_test2
"0 sec passed"
"value1"
"1 sec passed"
"value1"
"2 sec passed"
"updated value1"
"3 sec passed"
"updated value1"
"4 sec passed"
"updated value1"
"5 sec passed"
"updated value1"
"6 sec passed"
"updated value1"
"7 sec passed"
"updated value1"

ハッシュをupdateした場合

ハッシュをupdateした場合は、expireは更新されず、削除もされない。

def expire_test3
  hash = { "key1" => "value1", "key2" => "value2" }
  REDIS_DATA_STORE.call("HSET", "expire_key2", hash)
  REDIS_DATA_STORE.call("EXPIRE", "expire_key2", 3)

  5.times do |i|
    p "#{i} sec passed"
    p REDIS_DATA_STORE.call("HGETALL", "expire_key2")
    sleep 1

    REDIS_DATA_STORE.call("HSET", "expire_key2", {"key1": "updated value1"}) if i == 1
  end
end
pry(main)> expire_test3
"0 sec passed"
{"key1"=>"value1", "key2"=>"value2"}
"1 sec passed"
{"key1"=>"value1", "key2"=>"value2"}
"2 sec passed"
{"key1"=>"updated value1", "key2"=>"value2"}
"3 sec passed"
{}
"4 sec passed"
{}

同じキーに違うデータタイプを割り当てる

違うタイプに同じキーは使えない。

pry(main)> REDIS_DATA_STORE.call("SET", "id4", "value4")
=> "OK"
pry(main)> REDIS_DATA_STORE.call("HSET", "id4", {"key4" => "hash value4"})
RedisClient::WrongTypeError: WRONGTYPE Operation against a key holding the wrong kind of value

まとめ

バージョンによって挙動が異なるかもしれないので、実験してみるのが大事です。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?