使用RedisTemplate执行Lua脚本永远不会起作用



我目前正在为kafka和GC PubSub开发一个基准测试工具。我想看看关于最小-最大和平均传输速度的结果。在之前,我将每个条目都设置为reddis散列。之后,我将reddis散列映射到java映射,并在过程结束时对它们进行迭代,以获得最小值、最大值。它看起来很慢,因为如果我调用100000条目,程序会对min、max和avg进行x3迭代。所以我尝试用Lua脚本来实现这一点。发布消息后,我将开始时间设置为哈希映射,当侦听器收到消息时,我从哈希中获取消息开始时间,并计算与System.currentTimeMillis的差值。在这一步之后,我试图执行Lua脚本,将当前值与旧值进行比较并设置它。但当我执行脚本时,程序似乎停止了。我试着从Lua的脚本中返回true,但没有得到任何回应。

private void calculateSetANDLogAgain(User user){
long startTime = ((long) redisTemplate.opsForHash().get("times", user.getId()));
logger.info("Received message -> " + user.toString());
long duration = 0L;
duration = System.currentTimeMillis() - startTime;
Object[] args = new Object[1];
args[0] = duration;
System.out.println("BEFORE");
boolean a = redisTemplate.execute(statisticScript, Collections.singletonList("a"),args);
System.out.println("AFTER: " + a);
}

在这里我看到了BEFORE,但我看不到AFTER打印。以下是关于脚本执行的日志输出和配置。这是我的家谱。注意,RedisConfig类具有下面的bean。

@Bean
public DefaultRedisScript<Boolean> redisscript(){
DefaultRedisScript defaultRedisScript = new DefaultRedisScript<>();
defaultRedisScript.setLocation(new ClassPathResource("statistics.lua"));
defaultRedisScript.setResultType(Boolean.class);
return defaultRedisScript;
}

我正在拥有calculateSetANDLogAgain方法的类中自动连接DefaultRedisScript实例。脚本文件只有"CCD_ 5";

编辑;如果有帮助的话,这是我的第一个剧本。

local difference = tonumber(ARGV[1])
local max = tonumber(redis.call("GET","max"))
local min = tonumber(redis.call("GET","min"))
if max == nil then
redis.call("SET","max",difference)
elseif difference > max then
redis.call("SET","max",difference)
end
if min == nil then
redis.call("SET","min",difference)
elseif difference < min then
redis.call("SET","min",difference)
end

那么可能出了什么问题呢?我想不通。。。

我解决了这个问题。这很奇怪,但失败的原因似乎是错误的类路径。我在代码中做了一些更改,所以请看一下。

这是Bean的定义。

@Bean
public DefaultRedisScript<Boolean> redisscript() {
DefaultRedisScript defaultRedisScript = new DefaultRedisScript<Boolean>();
defaultRedisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("statistics.lua")));
defaultRedisScript.setResultType(Boolean.class);
return defaultRedisScript;
}

这是calculateSetANDLogAgain函数。

private void calculateSetANDLogAgain(User user) {
long startTime = ((long) redisTemplate.opsForHash().get("times", user.getId()));
logger.info("Received message -> " + user.toString());
Long duration = null;
duration = System.currentTimeMillis() - startTime;
Object[] args = new Object[1];
args[0] = duration;
try {
redisTemplate.execute(statisticScript, null, args);
} catch (Exception e) {
finalLogger.info("Error while executing script -> " + e.getLocalizedMessage());
}
}

这是剧本;

local difference = tonumber(ARGV[1])
local max = tonumber(redis.call("GET","max"))
local min = tonumber(redis.call("GET","min"))
if max == nil then
redis.call("SET","max",tostring(difference));
elseif difference > max then
redis.call("SET","max",tostring(difference));
end
if min == nil then
redis.call("SET","min",tostring(difference));
elseif difference < min then
redis.call("SET","min",tostring(difference));
end
return nil;

最后,我在resources文件夹中的脚本和构造函数中注入了redistemplate。

最新更新