【更新】SpringBoot自带RedisTemplate执行lua脚本以及预加载lua脚本到Redis集群

本文介绍如何使用RedisTemplate执行Lua脚本,包括引入Lua脚本、预加载Lua脚本到Redis,以及如何避免集群环境下因key值分布不均导致的错误。深入探讨了execute方法的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. RedisTemplate执行lua脚本
  • 引入lua脚本。
        DefaultRedisScript<List> redisScript = new DefaultRedisScript<List>();
        //放在和application.yml 同层目录下
        redisScript.setLocation(new ClassPathResource("test.lua"));
        redisScript.setResultType(List.class);
  • 运行lua脚本,keyList为传入的key值列表,需要加前缀,以确保在同一节点上,d为参数数组。
        List<String> list = new ArrayList<>();
        list.add("{pre}:door");
        list.add("{pre}:dog");

        String [] d = new String[10];
        d[0] = String.valueOf(12);
        d[1] = "22";

        List<String> result = redisUtils.getRedisTemplate().execute(redisScript,list,d);
  • 这里可以通过查看execute方法最后执行的源码可以看出:首先直接传sha值,如果在Redis中找不到预加载的lua脚本导致报错,则catch住该错误,把整个脚本序列化后传入Redis进行执行:
protected <T> T eval(RedisConnection connection, RedisScript<T> script, ReturnType returnType, int numKeys, byte[][] keysAndArgs, RedisSerializer<T> resultSerializer) {
        Object result;
        try {
            result = connection.evalSha(script.getSha1(), returnType, numKeys, keysAndArgs);
        } catch (Exception var9) {
            if (!ScriptUtils.exceptionContainsNoScriptError(var9)) {
                throw var9 instanceof RuntimeException ? (RuntimeException)var9 : new RedisSystemException(var9.getMessage(), var9);
            }

            result = connection.eval(this.scriptBytes(script), returnType, numKeys, keysAndArgs);
        }

        return script.getResultType() == null ? null : this.deserializeResult(resultSerializer, result);
    }
  • 注意:excute方法必须明确传key值,否则报:Lua script attempted to access a non local key in a cluster node错误。因为RedisTemplate操作的是集群,redis需要通过key值确定槽和节点。多个key的话,key值前都需要加{前缀}:,以确保都在同一个节点上的槽。

      2.RedisTemplate预加载lua到redis

  • Lua脚本运行之前都需要加载一次,为了减少网络开销,可在初始化时就将lua脚本预加载到redis中。通过redisTemplate 预加载lua脚本。返回的字符串为sha值。运行下面的代码后,再执行 redisUtils.getRedisTemplate().execute(redisScript,list,d)方法,源码中执行的就是第一步,是直接通过sha值运行Redis中提前加载好的lua脚本。
  • String s =redisUtils.getRedisTemplate().getConnectionFactory().getClusterConnection().scriptLoad(redisScript.getScriptAsString().getBytes());

     

 

 

原创不易,有用请点个赞。。

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值