从缓存中检索数据使用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
|