Explicação detalhada do script Redis Lua das perguntas de entrevista de alta frequência do script LUA

Adquira o hábito de escrever juntos! Este é o sexto dia da minha participação no "Nuggets Daily New Plan · April Update Challenge", clique para ver os detalhes do evento .

O Redis lançou a função de script na versão 2.6, que pode ser escrita em linguagem Lua e passada para o Redis para execução.

Vantagens dos roteiros:

  1. Reduza a sobrecarga de rede: as 5 solicitações de rede originais podem ser concluídas com uma solicitação e a lógica de 5 solicitações originais é enviada ao servidor redis para ser concluída. Latência de ida e volta da rede reduzida, que é semelhante a pipes.
  2. Operação atômica: o Redis executará todo o script como um todo, sem a intervenção de outros comandos.
  3. Substituindo a função de transação do Redis: A função de transação que vem com o Redis é muito insípida, e o script lua do redis quase realiza a função de transação convencional. É oficialmente recomendado que, se você quiser usar a função de transação do redis, considere usando lua em vez disso.

Instruções de uso do script

Por meio do interpretador lua integrado, você pode usar EVALcomandos para aplicar scripts Lua. O formato do comando é o seguinte:

# 脚本格式
EVAL script numkeys key [key ...] arg [arg ...]
# 示例
127.0.0.1:6379> EVAL "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 k1 k2 a1 a2 
1) "k1"
2) "k2"
3) "a1"
4) "a2"
复制代码

Descrição do parâmetro:

O primeiro parâmetro de script é um script Lua, que será executado no contexto do servidor redis. Este script não é (e não deve) ser definido como uma função lua.

O segundo parâmetro numkeys é usado para especificar o número de parâmetros de nome de chave.

A partir do terceiro parâmetro (key name parameter key ), ele representa as chaves do Redis (chaves) usadas no script, que podem ser acessadas em Lua através do array de variáveis ​​globais a KEYSpartir 1do endereço base KEYS[1],KEYS[2].

No final do comando, parâmetros adicionais que não são parâmetros de nome de chave arg [arg ...]podem ser acessados ​​em lua por meio da variável global ARGVarray , e o subscrito também inicia em 1.

redis.call()As funções podem ser usadas em scripts Lua para executar comandos redis.

Exemplo de chamada de caso de inventário de dedução de Jedis:

try (Jedis jedis = jedisPool.getResource()) {
    // 初始化商品id为100的库存
    jedis.set("product_stock_100", "10000");
    // @formatter:off
    String script = "local count =  redis.call('get',KEYS[1]) " +
            "local a = tonumber(count) " + 
            "local b = tonumber(ARGV[1]) " + 
            "if a >= b then " + 
            "redis.call('set',KEYS[1],a-b) " + 
            "return 1 " + 
            "end " + 
            "return 0";
    // @formatter:on
    Object decrResult = jedis.eval(script, Arrays.asList("product_stock_100"), Arrays.asList("100"));
    System.out.println(decrResult);
}
复制代码

**Nota: **Não tenha loops infinitos e operações demoradas no script lua, caso contrário **redis bloqueará** e não aceitará outros comandos, então tome cuidado para não usar o acima.

O Redis é um script de execução de thread único de processo único e o pipeline não bloqueará o redis.

O Redis LUA Script executará a reversão do comando?

Usar um script lua pode atingir uma certa atomicidade ao executar uma série de comandos redis (nenhuma nova instrução será inserida durante a execução de várias instruções no script lua), mas não pode reverter os resultados anteriores quando a execução do comando falhar .

Usamos o seguinte trecho de código para verificar, limpamos os dados redis antes de executar o código.

127.0.0.1:6379> FLUSHALL
OK
127.0.0.1:6379> KEYS *
(empty array)
复制代码

Em seguida, execute o código a seguir, o código completo presta atenção na conta oficial e 一个程序猿的异常envia a palavra-chave LUAGet .

try (Jedis jedis = jedisPool.getResource()) {
    // @formatter:off
    String script = " redis.call('SET', 'success','100') " 
                    // 模拟redis 出现异常信息,-1索引在bitmap不存在会报错
                    + " redis.call('SETBIT', 'bit_test','-1','1')  "
                    + " redis.call('SET', 'fail','100') " 
                    + " return 1";
    // @formatter:on
    Object eval = jedis.eval(script);
    System.out.println(eval);
}
复制代码

Visualize os dados em redis após a execução:

127.0.0.1:6379> KEYS *
1) "success"
127.0.0.1:6379> get success
"100"
复制代码

Conclusão: O uso do script lua pode obter uma certa atomicidade ao executar uma série de comandos redis (nenhuma nova instrução será inserida durante a execução de várias instruções no script lua), mas não poderá reverter os resultados anteriores quando a execução do comando falhar .

Acho que você gosta

Origin juejin.im/post/7088963946534666271
Recomendado
Clasificación