JAVA 通过 lua 脚本原子执行批量的 Redis插入操作 rpush
-
先声明一下cluster模式下操作多个key时不推荐使用lua脚本,因为执行路程脚本时会连接到指定的slot中,这样会获取不到其他slot中的key值,导致操作失败…贼坑 开始首先是lua脚本
local values = ARGV
local result
for k,v in ipairs(values) do
result = redis.call(RPUSH,KEYS[1],v)
end
return result
--return cjson.encode(result) 也可以根据具体需求将返回结果转成json格式
再来Java代码
@Slf4j
public class Temp {
private static final RedisTemplate<String, Object> REDIS_TEMPLATE = SpringContextHolder.getBean("redisTemplate", RedisTemplate.class);
public static String rPush(String key, List<String> list) {
String result = "";
try {
DefaultRedisScript<String> redisScript = new DefaultRedisScript<>();
// 这里需要单独设置返回值,不然会报错
redisScript.setResultType(String.class);
// 将脚本放到resources目录下
redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/R_PUSH.lua")));
// key要转成list, value要转成数组
result = REDIS_TEMPLATE.execute(redisScript, Collections.singletonList(key), list.toArray());
// 打印一下返回结果的日志
log.info("{}", result);
} catch (Exception e) {
log.warn("rPush error", e);
}
return result;
}
}
接下来是测试代码
@GetMapping("/a/{i}")
public String a(@PathVariable(name = "i") int i) {
List<String> valueList = new ArrayList<>();
for (int j = 0; j < 10; j++) {
// 循环放入十个值,或者将对象转成json格式存储
valueList.add("redisValue" + j);
}
Temp.rPush("redis:key", valueList);
return "" + i;
}
然后是返回结果的日志,可以在脚本中组装成自己需要的json格式
插入的结果
说明 通过以上的步骤就可以原子执行大批量的插入数据操作了,这样可以避免多次请求redis,减少服务开支,提高效率。 redis官网对使用lua脚本的介绍
