lua 菜鸟教程:https://www.runoob.com/lua/lua-tutorial.html
在 Redis 使用 lua 脚本的好处:
EVAL
:将脚本 script 添加到脚本缓存中,并且立即执行这个脚本
EVAL script numkeys key [key …] arg [arg …]
EVAL "return redis.call('set', 'name', 'bob')" 0
EVAL "return redis.call('set', KEYS[1], ARGV[1])" 1 name jack
EVALSHA
:根据给定的 sha1 校验码,执行缓存在服务器中的脚本。将脚本缓存到服务器的操作可以通过 SCRIPT LOAD
命令进行。这个命令的其他地方,比如参数的传入方式,都和 EVAL
命令一样
EVALSHA sha1 numkeys key [key ...] arg [arg ...]
SCRIPT LOAD
:将脚本 script 添加到脚本缓存中,但并不立即执行这个脚本。 在脚本被加入到缓存之后,通过 EVALSHA
命令,可以使用脚本的 SHA1
校验和来调用这个脚本。SCRIPT LOAD script
。SCRIPT EXISTS
:校验指定的脚本是否已经被保存在缓存当中
SCRIPT EXISTS sha1 [sha1 ...]
SCRIPT FLUSH
:清除 Redis 服务端所有 lua 脚本缓存SCRIPT KILL
:用于杀死当前正在运行的 lua 脚本,当且仅当这个脚本没有执行过任何写操作时,这个命令才生效。这个命令主要用于终止运行时间过长的脚本,比如一个因为 BUG 而发生无限循环的脚本案例:
redis 127.0.0.1:6379> SCRIPT LOAD "return 'hello moto'" # 载入一个脚本
"232fd51614574cf0867b83d384a5e898cfd24e5a"
redis 127.0.0.1:6379> SCRIPT EXISTS 232fd51614574cf0867b83d384a5e898cfd24e5a
1) (integer) 1
redis 127.0.0.1:6379> SCRIPT FLUSH # 清空缓存
OK
redis 127.0.0.1:6379> SCRIPT EXISTS 232fd51614574cf0867b83d384a5e898cfd24e5a
1) (integer) 0
基于 Redis 的分布式锁
释放锁的流程:
unlock.lua 如下:resources/unlock.lua
-- 比较线程标示与锁中的标示是否一致
if(redis.call('get', KEYS[1]) == ARGV[1]) then
-- 释放锁 del key
return redis.call('del', KEYS[1])
end
return 0
在 Java 中调用:
// 初始化 lua 脚本文件
private static final DefaultRedisScript<Long> UNLOCK_SCRIPT;
static {
UNLOCK_SCRIPT = new DefaultRedisScript<>();
//lua脚本位置
UNLOCK_SCRIPT.setLocation(new ClassPathResource("unlock.lua"));
//返回值类型
UNLOCK_SCRIPT.setResultType(Long.class);
}
// 使用 lua 脚本释放锁
public void unlock(String lockKey,String lockValue){
// 调用lua脚本
redisTemplate.execute(
UNLOCK_SCRIPT,
Collections.singletonList(lockKey),
lockValue);
}