Redis Lua脚本书写

在web项目中,可利用Redis的Lua脚本做级联操作来确定用户信息。博客介绍了级联缓存值、级联查询、级联更新、级联续期和级联删除的操作,给出了相应的Lua脚本语句和Redis运行示例,还提及了缓存数据类型的选择。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1. 级联缓存值

1.1 级联缓存session及相关信息

lua脚本语句

redis运行示例

2. 级联查询

2.1 级联查询session

lua脚本语句

redis运行示例

3. 级联更新

3.1 级联更新accountId对应的用户信息

lua脚本

redis运行示例

 4. 级联续期

4.1 刷新session时级联续期

 lua脚本

redis运行结果

5. 级联删除

5.1 级联删除session

 lua脚本语句

redis运行示例


场景介绍:

(1)web项目中一般会在redis中存sessionId对应的用户信息,保存sessionId—>userInfo的关联关系。

(2)实际开发中有需要根据accountId查询用户缓存的信息,而步骤1只保存了sessionId到userInfo的映射关系。那么如何通过acccountId找到redis中缓存的用户信息呢?要么根据accountId多存一份,但太浪费资源了。这时我们可以通过accountId——映射—>sessionId——映射—>userinfo的链路确定用户信息,利用redis的lua脚本做级联的操作。​

1. 级联缓存值


1.1 级联缓存session及相关信息

(1)缓存session值,即根据sessionId缓存用户信息字符串。
(2)待第一步成功后,缓存accountId,即key为accountId,值为sessionId。

lua脚本语句

local sessionkey = KEYS[1]
local userInfo = ARGV[1] 
local accountId = KEYS[2] 

redis.call('SET', sessionkey, userInfo) 
local result =redis.call('SET', accountId, sessionkey)

return result

注:第一个set执行完,恰好redis挂了,第二个set无法正常执行返回结果,代码中执行lua脚本需要考虑超时时间。

redis运行示例

eval "local sessionkey = KEYS[1] local userInfo = ARGV[1] local accountId = KEYS[2] redis.call('SET', sessionkey, userInfo) local result =redis.call('SET', accountId, sessionkey) return result" 2 aa cc qq

 注:这里2暂时理解为2个key,aa=sessionId,cc=accountId,qq=userInfo。即套用以下公式在redis中执行lua脚本。

EVAL script numkeys key [key …] arg [arg …]

2. 级联查询

2.1 级联查询session

(1)根据accountId查询sessionId

(2)根据sessionId查询用户信息,中间需要判断

lua脚本语句

local accountId = KEYS[1]

local sessionId = redis.call('GET', accountId)

if sessionId then
    local userInfoString = redis.call('GET', sessionId)
    return userInfoString
else
    return nil
end

redis运行示例

eval "local accountId = KEYS[1] local sessionId = redis.call('GET', accountId) if sessionId then local userInfoString = redis.call('GET', sessionId) return userInfoString else return nil end" 1 cc

根据accountId(值cc),找到sessionId(值aa)对应的用户信息qq。

 查找一个不存在的值.

3. 级联更新

3.1 级联更新accountId对应的用户信息

(1)先查询accountId是否存在对应的sessionId

(2)若存在,则更新缓存的用户信息,不存在则报错提示

lua脚本

local accountId = KEYS[1] 
local userInfoString = ARGV[1]

local sessionId = redis.call('GET', accountId) 

if sessionId then 
  redis.call('SET', sessionId, userInfoString) 
  return 1 
else 
return 0 
end

redis运行示例

eval "local accountId = KEYS[1] local userInfoString = ARGV[1] local sessionId = redis.call('GET', accountId) if sessionId then redis.call('SET', sessionId, userInfoString) return 1 else return 0 end" 1 cc newUserInfoString

正常情况更新一条信息

不正常没有更新对应的信息

 4. 级联续期

4.1 刷新session时级联续期

(1)为sessionId进行续期,查询到accountId

(2)再为accountId进行续期

redis lua脚本为不存在的值进行续期,返回0,不报错。因此考虑可以先不查询,直接续期。当然实际使用中,刷新session的用户信息缓存时,绝大部分存在key。

 lua脚本

local sessionId = KEYS[1] 
local ttl = tonumber(ARGV[1]) 

local accountId=redis.call('GET', sessionId)    

if accountId then
	local accountResult=redis.call('EXPIRE', accountId,ttl) 
	local sessionResult=redis.call('EXPIRE', sessionId,ttl) 
	
	return accountResult+sessionResult
end
return 0          

PS:实际上用户信息如果存字符串,以上的lua脚本考虑做字符串处理,从用户信息字符串获取accountId,再为accountId对应的sessionId映射续期。

redis运行结果

eval "local sessionId = KEYS[1] local ttl = tonumber(ARGV[1]) local accountId=redis.call('GET', sessionId) if accountId then local accountResult=redis.call('EXPIRE', accountId,ttl) local sessionResult=redis.call('EXPIRE', sessionId,ttl) return accountResult+sessionResult end return 0" 1 sessionId111 120

5. 级联删除

5.1 级联删除session

(1)删除sessionId对应的缓存的用户信息

(2)再根据accountId删除对应的映射关系

删除存在的key返回1,不存在的key返回0

 lua脚本语句

local sessionId = KEYS[1] 
local accountId = KEYS[2]
local sessionResult=redis.call('DEL', sessionId) 
local accountResult=redis.call('DEL', accountId) 
return sessionResult+accountResult

redis运行示例

eval "local sessionId = KEYS[1] local accountId = KEYS[2] local sessionResult=redis.call('DEL', sessionId) local accountResult=redis.call('DEL', accountId) return sessionResult+accountResult" 2 iii lll

 最后,实际缓存的用户信息并不一定是字符串。缓存字符串速度快,占用空间小,但需要在代码中序列化。缓存对象,占用空间大,速度较前者慢,使用时便捷无须转换。或考虑使用Hash的数据结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值