Redis获取密钥或设置为默认值(如果不存在)

时间:2016-05-13 09:35:43

标签: redis

redis中是否有命令可以设置密钥的默认值(如果密钥不存在)?

例如,如果get hello返回(nil),我希望将其默认为world。但是如果密钥hello已经存在,我想返回这个值。

4 个答案:

答案 0 :(得分:4)

您可以使用Lua脚本执行此操作:

local value = redis.call("GET", KEYS[1])
if (not value) then
    redis.call("SET", KEYS[1], ARGV[1])
    return ARGV[1]
end
return value

将其另存为script.lua,并将其命名为:

$ redis-cli eval "$(cat script.lua") 1 myKey defaultValue

答案 1 :(得分:1)

您也可以使用SETNX设置默认值,然后执行正常的GET。

答案 2 :(得分:1)

简单的Get应该是最快的事情

// practically Get would suffer a miss only the first time
value = Get key
if value not nil
  return value

// Get did not find key => setNX
saved = SetNX key default
if saved 
  return default

// SetNX discovered key value was already set by someone else => Get it
return Get key

答案 3 :(得分:0)

虽然您可以在其他答案中看到,但要注意,根据您的用例,发出2个请求的速度可能更快。有两个原因。首先是它迫使您“计算”输出,这是您首先要避免使用高速缓存时要避免的输出。其次,您将发送脚本和每个请求的计算数据,这会减慢流量,如果您的数据在一段时间内保持不变,则只会发送一个简单的get请求。

这就是为什么在应用程序或驱动程序级别实现get-or-set会更好的原因。我不知道您使用的语言,但这是一个伪代码版本:

function get_or_set(key, callback_function)
  value = REDIS.get(key)
  if value.nil?
    value = callback_function(REDIS) # pass REDIS to the anonymous function just in case
    value_str = pack(value) # could be JSON or MsgPack
    REDIS.set(key, value_str)
  else
    unpack(value)
  end
end

之所以简化,是因为它只处理字符串(打包以确保它们是字符串)并且没有实现过期,但是您明白了。

虽然听起来有些矫kill过正,但却可以使您获得更好的性能。否则,肯定已经是Redis功能了。