本文介绍 SpringBoot 如果通过 Lua 脚本去执行 Redis, 只介绍了简单用法例子, 更深层次的用法请参考 Redis 官网
1. 添加依赖
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-Redis</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
2. 编写 Lua 脚本
- ---
- --- Created by Gjing.
- --- DateTime: 2019/6/21 10:49
- ---
--- 获取 key
- local key1 = KEYS[1]
- local key2 = KEYS[2]
- local key3 = KEYS[3]
--- 设置 key 和 value
Redis.call("SET",key1,key2)
--- 设置 key 的过期时间
Redis.call("EXPIRE",key1,key3)
--- 执行完返回 true
return true
3. 编写配置
- /**
- * @author Gjing
- **/
- @Configuration
- public class LuaConfiguration {
- @Bean
- public DefaultRedisScript<Boolean> redisScript() {
- DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>();
- redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("script/Test.lua")));
- redisScript.setResultType(Boolean.class);
- return redisScript;
- }
- }
4. 调用测试
- /**
- * @author Gjing
- **/
- @RestController
- public class LuaTest {
- @Resource
- private DefaultRedisScript<Boolean> redisScript;
- @Resource
- private StringRedisTemplate stringRedisTemplate;
- @GetMapping("/ex")
- public ResponseEntity ex() {
- List<String> list = Arrays.asList("testLua", "hello lua", "100");
- Boolean execute = stringRedisTemplate.execute(redisScript, list, "1");
- 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 脚本一定要测试好.
以上为个人理解, 如有误欢迎各位指正
来源: https://yq.aliyun.com/articles/706121