Redis集群模式使用Lua脚本的限制

2023-11-09

问题复现:

ERR bad lua script for redis cluster, all the keys that the script uses should be passed using the KEYS array, and KEYS should not be in expression
堆栈信息:

org.springframework.dao.InvalidDataAccessApiUsageException: ERR bad lua script for redis cluster, all the keys that the script uses should be passed using the KEYS array, and KEYS should not be in expression; nested exception is redis.clients.jedis.exceptions.JedisDataException: ERR bad lua script for redis cluster, all the keys that the script uses should be passed using the KEYS array, and KEYS should not be in expression
at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:69)
at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:42)
at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:44)
at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:42)
at org.springframework.data.redis.connection.jedis.JedisConnection.convertJedisAccessException(JedisConnection.java:187)

由于前段时间自己写的redis定长队列使用了lua脚本,测试好好的,线上就报错了,还好不是什么大问题。因为目前测试环境单个实例,线上环境使用的是redis集群模式,所以已经踩了不少坑
起初写的脚本如下:

private static final String LIMIT_OFFER_LUA =
            "local key = KEYS[1]" +
            "local num = tonumber(ARGV[1])" +
            "local val = ARGV[2]" +
            "if (redis.call('llen', key) >= num) then redis.call('rpop', key) end " +
            "redis.call('lpush', key, val)";

其中key和arg都用lua变量,因为好几处使用了,正常来讲申明变量没什么问题,可是阿里集群对Lua脚本进行了限制,再通过错误信息,意思为,key的位置必须为数组,不能使用脚本变量

解决办法

修改lua脚本,去掉key的local变量,改为KEYS[i]数组的形式,将数组直接传入进去
修改脚本如下:

private static final String LIMIT_OFFER_LUA =
            "local num = tonumber(ARGV[1])" +
            "local val = ARGV[2]" +
            "if (redis.call('llen', KEYS[1]) >= num) then redis.call('rpop', KEYS[1]) end " +
            "redis.call('lpush', KEYS[1], val)";

集群中Lua脚本的限制

Redis Cluster对使用Lua脚本增加了一些限制,在此基础上,Redis集群版对使用Lua脚本存在如下额外限制:

  • 小版本限制,若无法执行EVAL的相关命令,并报错ERR command eval not support for normal user时,请升级小版本后重试,具体操作请参见升级小版本。
  • 所有Key必须在一个slot上,否则报错-ERR eval/evalsha command keys must be in same slot\r\n。
    您可以通过CLUSTER KEYSLOT命令获取目标Key的哈希槽(Hash Slot)进行确认。
  • 对单个节点执行SCRIPT LOAD命令时,不保证将该Lua脚本存入至其他节点中。
  • 不支持发布订阅命令,包括PSUBSCRIBE、PUBSUB、PUBLISH、PUNSUBSCRIBE、SUBSCRIBE和UNSUBSCRIBE。
  • 不支持UNPACK函数。

代理模式(Proxy)执行Lua的额外限制

  • 所有key都应该由KEYS数组来传递,redis.call/pcall中调用的Redis命令,key的位置必须是KEYS array,且不能使用Lua变量替换KEYS,否则直接返回错误信息:
  • 调用必须要带有key,否则直接返回错误信息:
  • 不支持在MULTI、EXEC事务中使用EVAL、EVALSHA、SCRIPT系列命令。
  • 不支持在Lua中执行跨Redis节点的命令,例如KEYS、SCAN等。为了保证Lua执行的原子性,Proxy会根据KEYS参数将Lua发送到一个Redis节点执行并获取结果,从而导致该结果与全局结果不一致。

参考链接
RedisLua脚本的基本语法与使用规范_云数据库 Redis 版-阿里云帮助中心

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Redis集群模式使用Lua脚本的限制 的相关文章

  • 如何像java中的make一样程序化生成塞尔达传说

    我将如何用java制作程序生成的地图 游戏本身就像塞尔达传说是程序生成的 有帮助吗 不久前的 塞尔达传说 地图使用等距平铺视图 您需要做的第一件事是将等距图块集加载到您的程序中 我确信您可以找到塞尔达图块集 然后 您需要决定如何按程序生成地
  • Jsch:命令输出不可用

    我正在尝试使用 jsch 连接到远程交换机并运行一些命令并提取输出 我可以使用 连接到交换机 但是命令输出在输入流中不可用 也许我没有以正确的方式做这件事 这是代码 session jsch getSession user 10 0 0 0
  • 搜索栏小部件未启动可搜索活动

    我正在尝试使用操作栏中的搜索栏小部件在我的 Android 应用程序上实现搜索 我正在关注 http developer android com guide topics search search dialog html http dev
  • 如何使用户输入与变量相关?

    我不知道如何准确地表达这个问题 但这就是我想要实现的目标 我正在使用堆栈实现河内塔插图 这是里面的main 功能 System out println Type the source pole number and the destinat
  • 从java程序调用SVN命令

    我想从 java 程序调用 SVN 命令 update commit 有什么帮助吗 SVN 乌龟SVN 环境 java程序将在jBoss服务器内运行 从应用程序服务器内使用 GUI SVN 客户端是一个非常非常糟糕的主意 而Tortoise
  • IntelliJ IDEA 中的自动错误检测

    我是 Java 编程语言和 IntelliJ IDEA 2017 1 IDE 的新手 我刚刚安装了 IDE 并激活了所有各种检查 但每当我犯了错误 例如省略括号或分号 时 IDE 都无法检测到错误 此图像显示激活的检查 This is a
  • springdoc-openapi:如何添加POST请求的示例?

    Controller有以下方法 ApiResponses value ApiResponse responseCode 200 GetMapping value API URI PREFIX PRODUCTS URI produces Me
  • 块作用域变量

    这将编译 class X public static void main String args int a 2 int a 3 这不会 class X public static void main String args int a 2
  • 使用 setcap 功能运行时 JLI_InitArgProcessing 的 Java“符号查找错误”

    我们在服务器上安装了 Java 11 旨在监视网络接口的流量 初始安装后 yum install java 11 openjdk devel x86 64 the java命令对两者都适用root and a 普通用户 但是 我们的 Jav
  • 如何在运行时获取类名,但仅获取类名?

    如何在运行时获取类名 但仅获取实际的类名而不是整个 com xyz etc 我的意思只是最后一个句点之后的名字部分 您必须将以下代码片段用于对象 yourObject getClass getSimpleName 或供课堂使用 yourCl
  • 使用 Spring Security 滑动过期

    我正在使用 Spring Security 我注意到 当用户登录时 身份验证 cookie 的有效期约为一天 它似乎并没有 刷新 这个过期日期 cookie 在一天后过期 即使在当天结束前 5 分钟我已经通过安全 URL 向服务器发出了请求
  • Java 中的冒号是什么意思?

    Java 中的冒号是什么意思 我有这个 public static List
  • java中如何查找两个时间戳的差异?

    我有一个ArrayList包括多个时间戳 目的是找到第一个和最后一个元素的差异ArrayList String a ArrayList get 0 String b ArrayList get ArrayList size 1 long d
  • 找不到元素“ehcache”的声明

    我正在我的 Web 应用程序中实现 url 缓存 运行时 ehcache xml 文件出现错误 我正在使用 spring 2 5 jar 文件 ehcache xml
  • 如何从 Ant 构建文件设置 Eclipse 构建路径和类路径?

    关于 Ant 和 Eclipse 有很多讨论 但之前的答案似乎对我没有帮助 事情是这样的 我正在尝试构建一个可以从命令行使用 Ant 成功编译的 Java 程序 更令人困惑的是 我尝试编译的程序是 Ant 本身 我真正想做的是将这个项目引入
  • 重写方法的返回类型可以不同吗?

    重写方法可以有不同的返回类型 Java supports covariant return types for overridden methods This means an overridden method may have a mo
  • 在 Transport.send(message) 上获取 ParseException

    由于某种原因 当我在 MimeMessage 上调用 Transport send 时 出现 javax mail internet ParseException 以前 当它只是一封纯文本电子邮件时 这是有效的 但是当我将其更改为同时包含文
  • Spring MVC 中拦截器和过滤器的区别

    我有点困惑Filter and Interceptor目的 据我从文档中了解到 Interceptor在请求之间运行 另一方面Filter在渲染视图之前运行 但在控制器渲染响应之后运行 那么两者的区别在哪里postHandle 在拦截器和d
  • 在Java中,如何在每次进入或退出给定对象的监视器时记录一条消息?

    我正在尝试调试一些使用一些自定义引用计数 锁定的 C Java 绑定 我想让 JVM 在每次给定对象进入或退出其监视器时打印一条消息 有什么办法可以做到这一点吗 基本上 我想要这个 synchronized lock System out
  • 如何解决消息有效负载类型为:Mule 中的 BufferInputStream 异常

    我已经转换为字节数组 但我不断收到此错误 ERROR 2015 02 25 11 12 30 517 ESR HTTP Request Listener worker 01 org mule exception DefaultMessagi

随机推荐

  • 2.5mnist手写数字识别之优化算法精讲(百度架构师手把手带你零基础实践深度学习原版笔记系列)

    2 5mnist手写数字识别之优化算法精讲 百度架构师手把手带你零基础实践深度学习原版笔记系列 目录 2 5mnist手写数字识别之优化算法精讲 百度架构师手把手带你零基础实践深度学习原版笔记系列 设置学习率 学习率的主流优化算法 设置学习
  • 机器学习——决策树剪枝

    目录 一 决策树剪枝策略 1 1剪枝目的 1 2剪枝策略 1 3判断决策树泛化性能是否提升的方法 二 预剪枝 prepruning 2 1概述 2 2预剪枝优缺点 2 3代码实现 三 后剪枝 postpruning 3 1概述 3 2后剪枝
  • MinIo 安装及其集成到java中上传下载图片信息

    MinIo 安装及其集成到java中上传下载图片信息 win 下安装 下载链接 https min io download windows 下载好后cmd打开控制台 输入 minio exe server D MinIo data 注 D
  • [轻量级RTSP服务]Linux

    背景 随着国产操作系统的推进 传统行业对Linux平台的呼声和需求越来越大 之前几年 我们发布了Linux平台运营商级的RTSP转RTMP推送模块 RTMP推送模块和RTSP RTMP播放模块 前段时间 有开发者问我们 是不是可以在Linu
  • eclipse中springboot项目如何打包成jar文件

    eclipse中springboot项目如何打包成jar包 前提 第一步 清除项目中之前的打包内容 第二步 打jar包 第三步 测试 4 注意事项 前提 在项目的pom xml中配置相关的内容 其中finalName中内容表示jar war
  • 树莓派mqtt协议连接阿里云物联网平台,手机端获取数据并控制

    树莓派C语言mqtt协议连接阿里云物联网平台 一 阿里云后台配置树莓派设备 阿里云添加链接描述 注册 登录 打开控制台 选择产品与服务 物联网平台 进入后 选择设备管理 产品 点击创建产品 产品名称随便写 品类自定义 直连设备 其他默认 最
  • 【设计模式】建造者模式

    建造者模式 Builder Pattern 使用多个简单的对象一步一步构建成一个复杂的对象 这种类型的设计模式属于创建型模式 它提供了一种创建对象的最佳方式 一个 Builder 类会一步一步构造最终的对象 该 Builder 类是独立于其
  • 【概率论与数理统计】猴博士 笔记 p15-16 一、二维连续型求概率

    一维连续型求概率 题型如下 解题步骤如下 其实就是求积分 举例1的例子 例2 解 例3 解 注意 要把Y变为X计算 且要分类讨论y是否大于0 例4 解 去掉max和min的方法 去掉多余项的方法 假设要求AB两项同时发生的概率 当多余项 A
  • kafka使用_使用多线程增加kafka消费能力

    原创 小姐姐味道 微信公众号ID xjjdog 欢迎分享 转载请保留出处 前提 本例适合那些没有顺序要求的消息主题 kafka通过一系列优化 写入和读取速度能够达到数万条 秒 通过增加分区数量 能够通过部署多个消费者增加并行消费能力 但还是
  • order by产生的 Using temporary的优化

    今天遇到一个慢查询的sql sql如下 EXPLAIN SELECT tas f year tc pk id tas f sex tas f rank score tas f age tas f km five tas f km ten t
  • filter过滤器实现权限访问控制以及同一账号只能登录一台设备

    需求 如题目所意 未登录用户不能浏览访问项目内部的资源 对访问的请求和响应进行拦截 且一个用户只能在一台设备登录 权限访问控制功能可以通过过滤器或者拦截器去实现 在这里我用的是过滤器 过滤器可以过滤全部action请求 拦截器则更有针对性
  • unity通过键盘控制物体移动,大小的缩放

    拖动距离 private float distance 10 缩放量 float scale 0 2f 通过键盘 Q 或者 E 控制物体的缩放 通过键盘 w s a d 控制物体上下左右的移动 private void Update if
  • PWM实现线性调光

    1 PWM调光原理 PWM全称为脉宽调制技术 是通过高精度的计数器对方波的占空比进行编码 就是这个东西 其实很好理解 高电平的时候才会做功 低电平的时候肯定不亮啊 PWM就是调制高电平的占比 其实一般是低电平才有效 因为会外接一个12V的电
  • XFocus Windows Internet 服务器安全配置

    Windows 2003版本区别 1 Windows Server 2003 Standard Edition 标准版 针对中小型企业的核心产品 他也是支持双路处理器 4GB的内存 它除了具备 Windows Server 2003 Web
  • Revit SDK下载地址

    20190325更新 共享了如下sdk REVIT 2014 SDK exe REVIT2015SDK SubscriptionRelease msi REVIT 2016 SDK msi Revit 2017 1 SDK Update O
  • 树莓派OpenWrt SD扩展问题

    树莓派OpenWrt磁盘扩展 1 查看问题 前几天给树莓派4B刷了OpenWrt当做软路由来使用 发现树莓派的SD卡空间没有完全被使用 有一部分未分区 已用大概只有2GB df h查看 2 fdisk 命令查看磁盘 3 按p查看分区情况 发
  • ansible自动化运维工具上部署lnmp架构

    ansible自动化运维工具上部署lnmp架构 ansible安装 通过ansible连接到192 168 228 20配置nginx安装 本地也要安装nginx 步骤略 安装mysql 安装PHP ansible自动化运维工具上部署lnm
  • Spring默认使用的JSON工具--Jackson

    Spring默认使用的JSON工具 Jackson 一 Jackson介绍 我们常用的json转换工具包括fastJson Gson Jackson等 其中Gson是Google所维护 功能全 fastJson特点是快 但是爆出几次的重大b
  • 2021最新版IDEA右侧Maven模块以及View下的Maven Project不见了解决方法

    问题描述 重新启动了一下IDEA后发现许多jar包找不到 想使用Maven进行依赖刷新 却找不到项目右侧的Maven Project 网上搜索了很多解决方法 如清除IDEA缓存 重启电脑 删除隐藏文件等等 都没有效果 将正确的解决方法记录在
  • Redis集群模式使用Lua脚本的限制

    问题复现 ERR bad lua script for redis cluster all the keys that the script uses should be passed using the KEYS array and KE