【发布时间】: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