功能实现
约 621 字大约 2 分钟
2025-01-31
Lua 脚本
前言
Lua 是一门古老的语言。由于 Redis 的单个命令都是原子性,但是有时候我们希望能够组合多个 Redis 命令,并让这个组合也能够 原子性 的执行
简单语法
Lua 的几个常用的数据类型如下:
- nil:空
- boolean:布尔值
- number:数字
- string:字符串
- table:表
声明类型
--- 全局变量
name = 'hello'
--- 局部变量,使用local关键字
local age = 18判断
local a = 10
if a < 10 then
print('a小于10')
elseif a < 20 then
print('a小于20,大于等于10')
else
print('a大于等于20')
endRedis 使 用 Lua
EVAL 命令
EVAL luascript numkeys key argEVAL: 命令的关键字luascript:Lua 脚本numkeys:指定的 Lua 脚本需要处理键的数量,其实就是key数组的长度key:传递给 Lua 脚本零到多个键,空格隔开,在 Lua 脚本中通过KEYS[INDEX]来获取对应的值,其中1 <= INDEX <= numkeysarg:是传递给脚本的零到多个附加参数,空格隔开,在 Lua 脚本中通过ARGV[INDEX]来获取对应的值,其中1 <= INDEX <= numkeys
举例
设置和获取 Redis 值
EVAL "redis.call('set', KEYS[1], ARGV[1])" 1 mykey myvaluemykey:Redis 中的键myvalue:键对应的值- 命令作用:将
mykey的值设置为myvalue
增量操作
EVAL "return redis.call('incr', KEYS[1])" 1 counterredis.call('incr', KEYS[1]):调用 Redis 的INCR命令,对指定键的值进行递增1:表示脚本后面有 1 个键(counter)counter:这是我们想要递增的 Redis 键
注意:如果 counter 键在 Redis 中不存在,INCR 会将它初始化为 0,然后递增 1
检查并设置键值
EVAL "if redis.call('exists', KEYS[1]) == 0 then redis.call('set', KEYS[1], ARGV[1]) end" 1 mykey myvalueredis.call('exists', KEYS[1]):检查键mykey是否存在- 如果
mykey不存在,则执行set命令,将mykey设置为myvalue - 这条命令确保只有在
mykey不存在时,才会执行SET操作
SpringBoot 集成
用 Lua 脚本检查并设置一个值
@Service
public class RedisService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
public String executeLuaScript() {
// Lua脚本: 如果key存在,返回"exists",否则设置它的值并返回"set"
String luaScript = "if redis.call('exists', KEYS[1]) == 1 then " +
" return 'exists'; " +
"else " +
" redis.call('set', KEYS[1], ARGV[1]); " +
" return 'set'; " +
"end";
// 创建DefaultRedisScript对象
DefaultRedisScript<String> redisScript = new DefaultRedisScript<>();
redisScript.setScriptText(luaScript); // 设置脚本
redisScript.setResultType(String.class); // 设置返回值类型
// 执行脚本
String result = redisTemplate.execute(redisScript, Collections.singletonList("myKey"), "myValue");
return result; // 返回执行结果
}
}版权所有
版权归属:haipeng-lin