Spring Boot 集成Redis 的Lua脚本详解

1. 对比Lua脚本方案与Redis自身事务

对比表格
对比维度 Redis事务(MULTI/EXEC) Lua脚本方案
原子性 事务命令序列化执行,但中间可被其他命令打断,不保证原子性 Lua脚本在Redis单线程中原子执行,不可中断
计算能力 仅支持Redis内置命令,无法复杂计算 支持Lua脚本,可实现复杂逻辑运算
性能 需多次网络交互,性能较低 通过SHA1复用脚本,减少网络传输,性能更高
适用场景 简单命令序列化执行 需要原子性且涉及复杂计算的场景

2. 两种运行Lua脚本的方法示例

方法1:直接发送Lua脚本(不缓存)
lua 复制代码
  
-- Lua脚本:将key1的值加1,并返回新值  
local value = tonumber(redis.call('GET', KEYS[1]))  
redis.call('SET', KEYS[1], value + 1)  
return value + 1  

Java代码:

java 复制代码
  
// 直接执行Lua脚本,每次传递脚本内容  
RedisScript<Long> script = new DefaultRedisScript<>(  
    "local v=tonumber(redis.call('GET', KEYS[1])); " +  
    "redis.call('SET', KEYS[1], v+1); return v+1", Long.class);  
Long result = redisTemplate.execute(  
    script, Arrays.asList("key1"), new Object[]{});  
方法2:先缓存SHA1后调用
lua 复制代码
  
-- 先执行以下脚本缓存到Redis  
// 第一次执行时缓存脚本  
String script = "...(同上)...";  
String sha1 = redisTemplate.execute(new DefaultRedisScript<>(script, Object.class)).getSha();  // 获取SHA1  

// 后续调用时仅传SHA1和参数  
redisTemplate.execute(  
    new DefaultRedisScript<Long>(sha1, Long.class),  
    Arrays.asList("key1"), new Object[]{});  

3. RedisScript接口及子类详解

RedisScript接口方法说明
方法名 作用描述
getSha() 返回脚本的SHA1哈希值(若已缓存)
getArgsCount() 返回脚本需要的参数数量
getNumberParams() 是否需要参数(已废弃,建议用getArgsCount()
getBody() 返回脚本的原始内容(若未缓存)
DefaultRedisScript类
  • 构造方法

    java 复制代码
    new DefaultRedisScript<>(scriptContent, returnType); // 传入脚本内容  
    new DefaultRedisScript<>(sha1, returnType);         // 传入SHA1  
  • 关键方法

    java 复制代码
    // 设置脚本内容  
    script.setScriptText("lua script content");  
    // 设置SHA1(需确保脚本已缓存)  
    script.setSha("computed_sha1");  
    // 设置参数数量  
    script.setArgsCount(2);  

4. RedisTemplate的execute()方法对比

方法1:默认序列化器
java 复制代码
  
// 使用默认序列化器(如StringRedisSerializer)  
public <T> T execute(RedisScript<T> script, List<K> keys, Object... args) { ... }  

// 示例:执行计数器脚本  
RedisScript<Long> script = new DefaultRedisScript<>(  
    "return tonumber(redis.call('INCR', KEYS[1]))", Long.class);  
Long result = redisTemplate.execute(  
    script, Arrays.asList("counter_key"), new Object[]{});  
方法2:自定义序列化器
java 复制代码
  
// 自定义参数和结果的序列化方式  
public <T> T execute(RedisScript<T> script,  
    RedisSerializer<?> argsSerializer,  
    RedisSerializer<T> resultSerializer,  
    List<K> keys, Object... args) { ... }  

// 示例:处理JSON参数和结果  
RedisScript<MyObject> script = ...;  
MyObject result = redisTemplate.execute(  
    script,  
    Jackson2JsonRedisSerializer.class,  // 参数序列化器  
    new Jackson2JsonRedisSerializer<>(MyObject.class), // 结果序列化器  
    Arrays.asList("key"),  
    new MyParamObject() // 自定义参数对象  
);  
对比表格
方法版本 参数序列化器 结果序列化器 适用场景
默认方法 使用RedisTemplate默认配置 使用RedisTemplate默认配置 简单类型(如String、Long)
自定义方法 可指定任意RedisSerializer 可指定任意RedisSerializer 复杂对象(如JSON、POJO)
相关推荐
一 乐36 分钟前
婚纱摄影网站|基于ssm + vue婚纱摄影网站系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot·后端
期待のcode3 小时前
前后端分离项目 Springboot+vue 在云服务器上的部署
服务器·vue.js·spring boot
ProgramHan4 小时前
Spring Boot 3.2 新特性:虚拟线程的落地实践
java·jvm·spring boot
悟能不能悟5 小时前
怎么使用postman批量的给api做测试
测试工具·lua·postman
小北方城市网5 小时前
分布式锁实战指南:从选型到落地,避开 90% 的坑
java·数据库·redis·分布式·python·缓存
源码获取_wx:Fegn08955 小时前
基于 vue智慧养老院系统
开发语言·前端·javascript·vue.js·spring boot·后端·课程设计
ohoy5 小时前
RedisTemplate 使用之Zset
java·开发语言·redis
毕设源码_郑学姐5 小时前
计算机毕业设计springboot基于HTML5的酒店预订管理系统 基于Spring Boot框架的HTML5酒店预订管理平台设计与实现 HTML5与Spring Boot技术驱动的酒店预订管理系统开
spring boot·后端·课程设计
不吃香菜学java5 小时前
spring-依赖注入
java·spring boot·后端·spring·ssm
南部余额5 小时前
Spring Boot 整合 MinIO:封装常用工具类简化文件上传、启动项目初始化桶
java·spring boot·后端·文件上传·工具类·minio·minioutils