首页 > 解决方案 > 使用 lua 脚本缓存数据,但通过访问集群节点中的非本地键获得 RedisCommandExecutionException

问题描述

我有一个地图数据要在springboot项目中使用lua脚本缓存在redis集群中,例如:

{
    "demoKey:{1}":"value1",
    "demoKey:{2}":"value2",
    "demoKey:{3}":"value3"
}

lua 脚本如下:

local addMap = cjson.decode(ARGV[1]);

for fieldKey, fieldValue in pairs(addMap) do
    redis.call("SET", fieldKey, fieldValue);
end

JAVA代码:

final DefaultRedisScript<?> redisScript = new DefaultRedisScript<>();
redisScript.setScriptSource(LUA_SCRIPT);
redisClient.execute(redisScript, new ArrayList<>(), JsonUtil.toString(addMap));

我已经设置了hash tagin redis 键,但是在运行程序时仍然出现异常。

org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisCommandExecutionException: ERR Error running script (call to f_7cce57ffe5b0b94fa78680955c993e808ffa5f16):
 @user_script:7: @user_script: 7: Lua script attempted to access a non local key in a cluster node

感谢任何帮助。

标签: javaspring-bootredisredis-cluster

解决方案


LUA 脚本不允许我们访问不在运行 LUA 脚本的同一台 Redis 机器上的密钥。

一种解决方案是标记 KEYS,使其位于正确的 Redis 节点上,标记密钥意味着所有密钥都属于同一个 Redis 实例。

看来您已经使用 完成了标记,{1}但是所有这些都可能散列到不同的 Redis 实例,从而导致错误。您的标签应该是相同的,例如,您可以使用,等作为标签。{2}{3}userIdrecordId

对于您的示例,如果您可以将地图更改为下方,它应该可以正常工作。

{
    "demoKey_1:{demoKey}":"value1",
    "demoKey_2:{demoKey}":"value2",
    "demoKey_3:{demoKey}":"value3"
}

推荐阅读