使用 RedisTemplate 执行 Lua 脚本永远不起作用
Executing Lua Script with RedisTemplate never works
我目前正在为 kafka 和 GC PubSub 开发一个基准测试工具。我想查看有关分钟的结果。最大和平均传输速度。之前,我将每个条目都设置为 reddis 哈希。之后,我将 reddis 哈希映射到 java 映射,并在过程结束时对它们进行迭代以获得最小值、最大值。它看起来很慢,因为如果我调用 100000 个条目,程序将迭代 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);
}
在这里我看到之前但我看不到打印之后。这里是log output and configuration about script executing. And here is my class tree。请注意RedisConfig
class 有下面的bean。
@Bean
public DefaultRedisScript<Boolean> redisscript(){
DefaultRedisScript defaultRedisScript = new DefaultRedisScript<>();
defaultRedisScript.setLocation(new ClassPathResource("statistics.lua"));
defaultRedisScript.setResultType(Boolean.class);
return defaultRedisScript;
}
我正在 class 中自动装配 DefaultRedisScript
实例,它拥有 calculateSetANDLogAgain
方法。脚本文件只有“return true;
”
编辑;如果有帮助,这是我的第一个脚本。
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;
最后我的脚本在资源文件夹中,我在构造函数中注入了重新模板。
我目前正在为 kafka 和 GC PubSub 开发一个基准测试工具。我想查看有关分钟的结果。最大和平均传输速度。之前,我将每个条目都设置为 reddis 哈希。之后,我将 reddis 哈希映射到 java 映射,并在过程结束时对它们进行迭代以获得最小值、最大值。它看起来很慢,因为如果我调用 100000 个条目,程序将迭代 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);
}
在这里我看到之前但我看不到打印之后。这里是log output and configuration about script executing. And here is my class tree。请注意RedisConfig
class 有下面的bean。
@Bean
public DefaultRedisScript<Boolean> redisscript(){
DefaultRedisScript defaultRedisScript = new DefaultRedisScript<>();
defaultRedisScript.setLocation(new ClassPathResource("statistics.lua"));
defaultRedisScript.setResultType(Boolean.class);
return defaultRedisScript;
}
我正在 class 中自动装配 DefaultRedisScript
实例,它拥有 calculateSetANDLogAgain
方法。脚本文件只有“return true;
”
编辑;如果有帮助,这是我的第一个脚本。
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;
最后我的脚本在资源文件夹中,我在构造函数中注入了重新模板。