Introdução
Neste laboratório, você explorará o Redis Lua Scripting, focando na execução de scripts Lua diretamente dentro do Redis para realizar operações complexas de forma eficiente. Este laboratório cobre o uso do comando EVAL para executar scripts, passando argumentos para scripts, carregando scripts com SCRIPT LOAD e executando scripts carregados com EVALSHA.
Começaremos executando um script Lua simples que incrementa um contador Redis usando EVAL, demonstrando como especificar o script, o número de chaves que ele acessa e os nomes das chaves. Em seguida, aprenderemos como carregar scripts no Redis e executá-los usando seu hash SHA1, melhorando o desempenho ao evitar a transmissão repetida de scripts.
Executar Script Lua com EVAL
Nesta etapa, exploraremos como executar scripts Lua diretamente dentro do Redis usando o comando EVAL. Isso permite que você execute operações complexas em seus dados em uma única solicitação, reduzindo a latência da rede e melhorando o desempenho.
Antes de começarmos, vamos entender os conceitos básicos do EVAL. O comando EVAL recebe dois argumentos principais:
- O próprio script Lua, como uma string.
- O número de chaves que o script acessará, seguido pelos nomes reais das chaves e quaisquer argumentos adicionais que você deseja passar para o script.
Aqui está um exemplo simples para você começar. Criaremos um script Lua que incrementa um contador Redis e retorna o novo valor.
Abra seu terminal e conecte-se ao servidor Redis usando a interface de linha de comando do Redis (
redis-cli).redis-cliAgora, vamos executar um script Lua usando
EVAL. Este script incrementará um contador chamadomycountere retornará o valor incrementado.EVAL "local current = redis.call('INCR', KEYS[1]); return current" 1 mycounterVamos detalhar este comando:
EVAL "local current = redis.call('INCR', KEYS[1]); return current": Este é o próprio script Lua. Ele usaredis.call('INCR', KEYS[1])para incrementar o valor da chave especificada emKEYS[1]. O arrayKEYScontém os nomes das chaves passadas para o script. Finalmente, ele retorna o valor incrementado.1: Isso indica que o script acessará uma chave.mycounter: Este é o nome da chave que o script acessará.
Você deve ver uma saída semelhante a esta:
(integer) 1Se você executar o mesmo comando novamente, verá o contador incrementando:
EVAL "local current = redis.call('INCR', KEYS[1]); return current" 1 mycounterSaída:
(integer) 2Vamos verificar o valor da chave
mycounterusando o comandoGET:GET mycounterSaída:
"2"Como você pode ver, o script Lua incrementou com sucesso o contador.
Agora, vamos tentar outro exemplo. Desta vez, criaremos um script que define uma chave para um valor específico se ela ainda não existir.
EVAL "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('SET', KEYS[1], ARGV[1]); return 1 else return 0 end" 1 mykey myvalueNeste comando:
EVAL "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('SET', KEYS[1], ARGV[1]); return 1 else return 0 end": Este é o script Lua. Ele verifica se a chaveKEYS[1]existe. Se não existir, ele define a chave para o valorARGV[1]e retorna1. Caso contrário, ele retorna0.1: Isso indica que o script acessará uma chave.mykey: Este é o nome da chave.myvalue: Este é o valor a ser definido se a chave não existir.
Você deve ver uma saída semelhante a esta:
(integer) 1Isso indica que a chave
mykeyfoi definida comomyvalue.Vamos verificar o valor de
mykey:GET mykeySaída:
"myvalue"Se você executar o comando
EVALnovamente:EVAL "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('SET', KEYS[1], ARGV[1]); return 1 else return 0 end" 1 mykey myvalueSaída:
(integer) 0Desta vez, o script retornou
0porque a chave já existia.Saia do
redis-cli. Isso é importante para que as alterações sejam registradas.exit
Passar Argumentos para o Script com EVAL
Na etapa anterior, aprendemos como executar scripts Lua com EVAL e acessar chaves. Agora, vamos explorar como passar argumentos para esses scripts. Isso permite scripts mais dinâmicos e reutilizáveis.
Lembre-se de que o comando EVAL recebe os seguintes argumentos:
- O próprio script Lua, como uma string.
- O número de chaves que o script acessará.
- Os nomes das chaves.
- Quaisquer argumentos adicionais que você deseja passar para o script. Esses argumentos são acessados dentro do script Lua usando o array
ARGV.
Vamos começar com um exemplo. Criaremos um script Lua que adiciona um valor a um contador Redis. A chave do contador e o valor a ser adicionado serão passados como argumentos.
Conecte-se ao servidor Redis usando a interface de linha de comando do Redis (
redis-cli).redis-cliAgora, vamos executar um script Lua usando
EVALque incrementa um contador por uma quantidade especificada.EVAL "local current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current" 1 mycounter 5Vamos detalhar este comando:
EVAL "local current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current": Este é o script Lua. Ele usaredis.call('INCRBY', KEYS[1], ARGV[1])para incrementar o valor da chave especificada emKEYS[1]pela quantidade especificada emARGV[1].1: Isso indica que o script acessará uma chave.mycounter: Este é o nome da chave que o script acessará.5: Este é o argumento que será passado para o script e acessado comoARGV[1].
Você deve ver uma saída semelhante a esta (assumindo que
mycounterestava em 2 na etapa anterior):(integer) 7O script incrementou a chave
mycounterem 5.Vamos verificar o valor da chave
mycounterusando o comandoGET:GET mycounterSaída:
"7"Agora, vamos tentar outro exemplo com argumentos de string. Criaremos um script que define uma chave para um valor, onde tanto a chave quanto o valor são passados como argumentos.
EVAL "redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]" 1 mynewkey mynewvalueNeste comando:
EVAL "redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]": Este é o script Lua. Ele define a chaveKEYS[1]para o valorARGV[1]e retorna o valor.1: Isso indica que o script acessará uma chave.mynewkey: Este é o nome da chave.mynewvalue: Este é o valor a ser definido.
Você deve ver uma saída semelhante a esta:
"mynewvalue"Vamos verificar o valor de
mynewkey:GET mynewkeySaída:
"mynewvalue"O script definiu com sucesso a chave
mynewkeypara o valormynewvalue.Você pode passar vários argumentos para o script. Por exemplo, vamos criar um script que concatena duas strings passadas como argumentos e define o resultado para uma chave.
EVAL "local result = ARGV[1] .. ARGV[2]; redis.call('SET', KEYS[1], result); return result" 1 combinedkey hello worldNeste comando:
EVAL "local result = ARGV[1] .. ARGV[2]; redis.call('SET', KEYS[1], result); return result": Este é o script Lua. Ele concatenaARGV[1]eARGV[2]usando o operador.., define a chaveKEYS[1]para o resultado e retorna o resultado.1: Isso indica que o script acessará uma chave.combinedkey: Este é o nome da chave.hello: Este é o primeiro argumento de string.world: Este é o segundo argumento de string.
Você deve ver uma saída semelhante a esta:
"helloworld"Vamos verificar o valor de
combinedkey:GET combinedkeySaída:
"helloworld"Saia do
redis-cli. Isso é importante para que as alterações sejam registradas.exit
Carregar Script com SCRIPT LOAD
Nas etapas anteriores, executamos scripts Lua diretamente usando o comando EVAL. Embora isso seja útil para scripts simples, pode se tornar complicado para scripts maiores e mais complexos. O Redis fornece o comando SCRIPT LOAD para carregar scripts no cache de scripts do servidor Redis. Isso permite que você execute o script várias vezes sem ter que enviar o script inteiro a cada vez, melhorando o desempenho.
O comando SCRIPT LOAD recebe um único argumento: o próprio script Lua. Ele retorna o hash SHA1 do script, que você pode usar para executar o script usando o comando EVALSHA (que abordaremos na próxima etapa).
Vamos ver como funciona.
Conecte-se ao servidor Redis usando a interface de linha de comando do Redis (
redis-cli).redis-cliAgora, vamos carregar um script Lua usando
SCRIPT LOAD. Usaremos o mesmo script da etapa anterior que incrementa um contador por uma quantidade especificada.SCRIPT LOAD "local current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current"Este comando carregará o script no cache de scripts do servidor Redis e retornará o hash SHA1 do script. Você deve ver uma saída semelhante a esta:
"6b1e8dd2999cb08546e74339c0c9489f9f89a84b"Este é o hash SHA1 do script. Anote este hash, pois você precisará dele na próxima etapa. O valor exato do hash pode ser diferente.
Agora, vamos carregar o script que define uma chave para um valor, onde tanto a chave quanto o valor são passados como argumentos.
SCRIPT LOAD "redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]"Você deve ver uma saída semelhante a esta:
"a8b2b3648969459a8198262a9166e945e890987c"Novamente, anote este hash.
Vamos carregar o script que concatena duas strings passadas como argumentos e define o resultado para uma chave.
SCRIPT LOAD "local result = ARGV[1] .. ARGV[2]; redis.call('SET', KEYS[1], result); return result"Você deve ver uma saída semelhante a esta:
"d2a800a974ca96849295220424f9a0664a495345"Anote este hash também.
Você pode verificar se os scripts estão carregados usando o comando
SCRIPT EXISTS. Este comando recebe um ou mais hashes SHA1 como argumentos e retorna um array de 0s e 1s, onde 1 indica que o script com o hash correspondente está carregado e 0 indica que não está.Por exemplo, para verificar se o primeiro script que carregamos ainda está carregado, use o seguinte comando, substituindo o hash pelo que você obteve na etapa 2:
SCRIPT EXISTS 6b1e8dd2999cb08546e74339c0c9489f9f89a84bSaída:
1) (integer) 1Isso indica que o script está carregado.
Se você tentar verificar um script que não está carregado:
SCRIPT EXISTS 0000000000000000000000000000000000000000Saída:
1) (integer) 0Isso indica que o script não está carregado.
Saia do
redis-cli. Isso é importante para que as alterações sejam registradas.exit
Executar Script Carregado com EVALSHA
Na etapa anterior, aprendemos como carregar scripts Lua no cache de scripts do servidor Redis usando o comando SCRIPT LOAD. Agora, aprenderemos como executar esses scripts carregados usando o comando EVALSHA.
O comando EVALSHA recebe os seguintes argumentos:
- O hash SHA1 do script carregado.
- O número de chaves que o script acessará.
- Os nomes das chaves.
- Quaisquer argumentos adicionais que você deseja passar para o script.
Usar EVALSHA é mais eficiente do que EVAL quando você precisa executar o mesmo script várias vezes, pois evita enviar o script inteiro para o servidor a cada vez.
Vamos ver como funciona.
Conecte-se ao servidor Redis usando a interface de linha de comando do Redis (
redis-cli).redis-cliAgora, vamos executar o script Lua que incrementa um contador por uma quantidade especificada usando
EVALSHA. Lembra-se do hash SHA1 que você obteve na etapa anterior para o scriptlocal current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current? Caso contrário, você precisará carregar o script novamente usandoSCRIPT LOAD. Para este exemplo, assumiremos que o hash é6b1e8dd2999cb08546e74339c0c9489f9f89a84b.EVALSHA 6b1e8dd2999cb08546e74339c0c9489f9f89a84b 1 mycounter 5Vamos detalhar este comando:
EVALSHA 6b1e8dd2999cb08546e74339c0c9489f9f89a84b: Isso especifica que queremos executar o script com o hash SHA16b1e8dd2999cb08546e74339c0c9489f9f89a84b.1: Isso indica que o script acessará uma chave.mycounter: Este é o nome da chave que o script acessará.5: Este é o argumento que será passado para o script e acessado comoARGV[1].
Você deve ver uma saída semelhante a esta (assumindo que
mycounterestava em 12 na etapa anterior):(integer) 17O script incrementou a chave
mycounterem 5.Vamos verificar o valor da chave
mycounterusando o comandoGET:GET mycounterSaída:
"17"Agora, vamos executar o script que define uma chave para um valor usando
EVALSHA. Lembra-se do hash SHA1 que você obteve na etapa anterior para o scriptredis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]? Caso contrário, você precisará carregar o script novamente usandoSCRIPT LOAD. Para este exemplo, assumiremos que o hash éa8b2b3648969459a8198262a9166e945e890987c.EVALSHA a8b2b3648969459a8198262a9166e945e890987c 1 anotherkey anothervalueVocê deve ver uma saída semelhante a esta:
"anothervalue"Vamos verificar o valor de
anotherkey:GET anotherkeySaída:
"anothervalue"Se você tentar executar um script com um hash SHA1 inválido, receberá um erro:
EVALSHA 0000000000000000000000000000000000000000 1 mykey myvalueSaída:
(error) NOSCRIPT No matching script. Please use EVAL.Isso indica que o script com o hash SHA1 especificado não está carregado.
Saia do
redis-cli. Isso é importante para que as alterações sejam registradas.exit
Resumo
Neste laboratório, você explorou a criação de scripts Lua no Redis, com foco na execução de scripts diretamente usando o comando EVAL. Aprendemos que EVAL recebe o script Lua como uma string, o número de chaves acessadas e os próprios nomes das chaves como argumentos. Praticamos o incremento de um contador Redis usando um script Lua dentro de EVAL, observando como o script acessava e modificava a chave especificada.
Além disso, aprendemos como passar argumentos para scripts Lua, carregar scripts no Redis usando SCRIPT LOAD e executar scripts carregados usando EVALSHA. Lembre-se de sair do redis-cli após cada etapa para garantir que seus comandos sejam registrados corretamente. Isso permite uma execução mais eficiente de scripts complexos.


