【问题标题】:RedisTemplate + Lua script: command arguments must be strings or integersRedisTemplate + Lua 脚本:命令参数必须是字符串或整数
【发布时间】:2022-08-20 11:38:47
【问题描述】:

我想以原子方式插入或更新一个键,将此键插入索引,并可选择增加一个计数。为此,我编写了以下 Lua 脚本。在这个脚本中,KEYS[1] 是元素键,KEYS[2] 是索引键,ARGV[1] 是存储在KEYS[1] 的对象,ARGV[2] 是分数。

if not redis.call(\'EXISTS\', KEYS[1]) then
  redis.call(\'INCR\', KEYS[2] .. \":num\");
end
redis.call(\'SET\', KEYS[1], ARGV[1]);
redis.call(\'ZADD\', KEYS[2] .. \":idx\", tonumber(ARGV[2]), KEYS[1]);

为了访问 Redis,我使用了一个 RedisTemplate<String, Object> 实例,它使用 GenericFastJsonRedisSerializer 来序列化值。一个小的工作示例:

public class Main {
    public static void main(String[] args) {
        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
        configuration.setHostName(\"localhost\");
        configuration.setPort(6379);
        LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(configuration);
        connectionFactory.afterPropertiesSet();

        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setDefaultSerializer(new GenericFastJsonRedisSerializer());
        template.setDefaultSerializer(new GenericFastJsonRedisSerializer());
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericFastJsonRedisSerializer());
        template.setHashKeySerializer(new GenericFastJsonRedisSerializer());
        template.setHashValueSerializer(new GenericFastJsonRedisSerializer());
        template.setConnectionFactory(connectionFactory);
        template.afterPropertiesSet();

        RedisScript<Object> script = RedisScript.of(new PathResource(Paths.get(\"my-script.lua\"))); // <- above script
        template.execute(script, Arrays.asList(\"value-key\", \"index-key\"), new Object(), 1.0);
    }
}

但是,当我运行 Lua 脚本时,出现以下错误:

@user_script: 14: Lua redis() command arguments must be strings or integers

我想,这是因为序列化器也序列化了分数,所以 Lua 不能再把它读成数字了。因此,如何避免将序列化程序应用于所有参数,并且只将我的对象转换为 JSON?

  • Lua 脚本本身很好,如果你运行它会产生预期的结果:redis-cli evalsha $(cat test.lua | redis-cli -x script load) 2 key1 key2 10 11 所以尝试检查它是如何在 Java 中序列化的

标签: java spring-boot redis lua


【解决方案1】:

这是我解决问题的方法。

前:

template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new JdkSerializationRedisSerializer());

后:

template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericToStringSerializer<>(String.class));

【讨论】:

    猜你喜欢
    • 2020-05-05
    • 2017-05-06
    • 2019-11-04
    • 2020-09-11
    • 1970-01-01
    • 2018-08-31
    • 2019-05-14
    • 2020-10-27
    • 1970-01-01
    相关资源
    最近更新 更多