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:
- 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.
- Operação atômica: o Redis executará todo o script como um todo, sem a intervenção de outros comandos.
- 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 EVAL
comandos 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 KEYS
partir 1
do 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 ARGV
array , 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 LUA
Get .
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 .