Выполнение Lua скрипта с RedisTemplate никогда не работает - PullRequest
0 голосов
/ 14 июля 2020

В настоящее время я работаю над эталонным инструментом для kafka и G C PubSub. Я хочу увидеть результаты примерно по мин. максимальная и средняя скорость передачи. Раньше я устанавливал для каждой записи значение reddis ha sh. После этого я сопоставил хэши Reddis с картой java и повторял их в конце процесса для минимальных, максимальных значений. Это кажется таким медленным, потому что, если я вызываю 100000 записей, программа повторяет x3 для min, max и avg. Поэтому я попытался сделать это с помощью сценария Lua. После публикации сообщения я установил время начала на карту ha sh, и когда слушатель получит сообщение, я беру время начала сообщения из ha sh и вычисляю разницу с System.currentTimeMillis. После этого шага я пытаюсь выполнить Lua Script, который сравнивает текущее значение со старым значением и устанавливает его. Но когда я выполняю сценарий, кажется, что программа останавливается на этом. Я попытался просто вернуть истину из сценария Lua, но я не получил ответа.

 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 и конфигурация выполнения скрипта. А вот и мое дерево классов . Обратите внимание, что класс 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;"

edit; вот мой первый сценарий, если он поможет.

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

Так что может go не так? Я так и не понял ...

1 Ответ

0 голосов
/ 10 августа 2020

Я решил проблему. Это странно, но кажется, что причиной сбоя является неправильный путь к классам. Я внес некоторые изменения в свой код, так что посмотрите.

Вот определение 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.

...