RedisTemplate无法执行Lua脚本

我正在为Kafka和GC PubSub工具编写基准测试,并希望看到有关最小,最大和平均传输速度的结果。在之前,我将每个条目设置为redis哈希。然后,我将redis哈希映射到Java映射,并在过程结束时对它们进行迭代以获取最小值,最大值。这似乎很慢,因为如果我调用100000个条目,则程序会对最小值,最大值和平均值进行三次迭代。因此,我尝试使用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打印。这里是有关脚本执行的日志输出和配置。这是我的class tree。请注意,RedisConfig类具有以下bean。

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

我正在自动连接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

那么可能出了什么问题?我无法弄清楚...

点赞
用户13551565
用户13551565

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

这是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;

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

2020-08-10 14:36:39