Redis 服务器端使用 lua 的 if-modified-since 缓存模式 - r4um


从缓存中检索数据使用if modified since类型可以节省大量网络带宽和计算周期。数据修改时间参考应该来自客户端,并作为请求的一部分发送,而不是基于非确认类型的方法假设在服务器端,就像客户端上次连接到服务器一样。这种模式可在Redis的服务器端的 lua on redis,实现在延迟方面非常少的开销。
我们可以将一个key的最后修改时间存储在一个散列中,并且只有当它比客户端发送的时间更新时才检索该值。
以下 Lua 片段根据名为MY_KEYSTIME的散列中键的修改时间进行存储/检索。
根据修改时间获取

local keys_mtime_hset = "MY_KEYSMTIME"
local key = KEYS[1]
local mtime = tonumber(ARGV[1])

local key_mtime = redis.call('HGET', keys_mtime_hset, key)
key_mtime = tonumber(key_mtime)
-- if missing key in the hash set return the value of the key.
-- or key mtime > mtime 
if not key_mtime or key_mtime > mtime then
    return redis.call('GET', key)
end

return nil 

设置和更新修改时间:
local keys_mtime_hset = "MY_KEYSMTIME"
local key = KEYS[1]
local value = ARGV[1]
local mtime = tonumber(ARGV[2])

redis.call('SET', key, value)
redis.call('HSET', keys_mtime_hset, key, mtime)

客户端在检索和设置key时发送修改时间。Redis Lua 脚本是原子的
以下 python 代码说明了一个完整的工作示例。

mtime_get=""" local keys_mtime_hset = "MY_KEYSMTIME" local key = KEYS[1] local mtime = tonumber(ARGV[1]) local key_mtime = redis.call('HGET', keys_mtime_hset, key) key_mtime = tonumber(key_mtime) -- if missing key in the hash set return the value of the key. -- or key mtime > mtime if not key_mtime or key_mtime > mtime then return redis.call('GET', key) end return nil """

mtime_set=
""" local keys_mtime_hset = "MY_KEYSMTIME" local key = KEYS[1] local value = ARGV[1] local mtime = tonumber(ARGV[2]) redis.call('SET', key, value) redis.call('HSET', keys_mtime_hset, key, mtime) """

m1 = int(time.time())
r = redis.Redis(host='localhost', port=6379)
MTGET=r.register_script(mtime_get)
MTSET=r.register_script(mtime_set)

t_k =
"Hello"
t_v =
"World"

r.delete(t_k)

print(MTGET(keys=[t_k], args=[m1]))

print(MTSET(keys=[t_k], args=[t_v, m1]))

print(r.get(t_k))

print(MTGET(keys=[t_k], args=[m1 - 100]))

print(MTGET(keys=[t_k], args=[m1 + 100]))

运行:

None
None
b'World'
b'World'
None