本文介绍SpringBoot如果通过Lua指令码去执行Redis,介绍简单用法例子,如对Lua指令码还不了解的可以先参考我这边文章Lua指令码快速入门更深层次的用法请参考Redis官网
1. 新增依赖
org.springframework.boot
spring-boot-starter-data-redis
org.springframework.boot
spring-boot-starter-web
2. 编写Lua指令码
---
--- Created by Gjing.
--- DateTime: 2019/6/21 10:49
---
--- 获取key
local key = KEYS[1]
--- 获取value
local val = KEYS[2]
--- 获取一个引数
local expire = ARGV[1]
--- 如果redis找不到这个key就去插入
if redis.call("get", key) == false then
--- 如果插入成功,就去设定过期值
if redis.call("set", key, val) then
--- 由于lua指令码接收到引数都会转为String,所以要转成数字型别才能比较
if tonumber(expire) > 0 then
--- 设定过期时间
redis.call("expire", key, expire)
end
return true
end
return false
else
return false
end
3. 编写配置
/**
* @author Gjing
**/
@Configuration
public class LuaConfiguration {
@Bean
public DefaultRedisScript redisScript() {
DefaultRedisScript redisScript = new DefaultRedisScript();
redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("script/Test.lua")));
redisScript.setResultType(Boolean.class);
return redisScript;
}
}
4. 呼叫测试
/**
* @author Gjing
**/
@RestController
public class LockController {
@Resource
private DefaultRedisScript redisScript;
@Resource
private StringRedisTemplate stringRedisTemplate;
@GetMapping("/lua")
public ResponseEntity lua() {
List keys = Arrays.asList("testLua", "hello lua");
Boolean execute = stringRedisTemplate.execute(redisScript, keys, "100");
assert execute != null;
return ResponseEntity.ok(execute);
}
}
5. 返回结果
执行成功控制台输出
执行失败控制台输出
Redis中内容
6. Redis使用Lua的好处
1.减少网络开销:本来5次网络请求的操作,可以用一个请求完成,原先5次请求的逻辑放在redis服务器上完成。使用指令码,减少了网络往返时延。
2.原子操作:Redis会将整个指令码作为一个整体执行,中间不会被其他命令插入。
3.复用:客户端传送的指令码会永久储存在Redis中,意味着其他客户端可以复用这一指令码而不需要使用程式码完成同样的逻辑。
7. Redis使用Lua的注意点
1.Lua指令码的bug特别可怕,由于Redis的单执行绪特点,一旦Lua指令码出现不会返回(不是返回值)得问题,那么这个指令码就会阻塞整个redis例项。
2.Lua指令码应该尽量短小实现关键步骤即可。(原因同上)
3.Lua指令码中不应该出现常量Key,这样会导致每次执行时都会在指令码字典中新建一个条目,应该使用全域性变数阵列KEYS和ARGV, KEYS和ARGV的索引都从1开始
4.传递给lua指令码的的键和引数:传递给lua指令码的键列表应该包括可能会读取或者写入的所有键。传入全部的键使得在使用各种分片或者丛集技术时,其他软件可以在应用层检查所有的资料是不是都在同一个分片里面。另外丛集版redis也会对将要访问的key进行检查,如果不在同一个服务器里面,那么redis将会返回一个错误。(决定使用丛集版之前应该考虑业务拆分),引数列表无所谓。。
5.lua指令码跟单个redis命令和事务段一样都是原子的已经进行了资料写入的lua指令码将无法中断,只能使用SHUTDOWN NOSAVE杀死Redis服务器,所以lua指令码一定要测试好。
点选了解更多关注我们下,十几年的架构师分享经验!!!