Writing Lua Scripts for a Redis Server
Traducciones al EspañolEstamos traduciendo nuestros guías y tutoriales al Español. Es posible que usted esté viendo una traducción generada automáticamente. Estamos trabajando con traductores profesionales para verificar las traducciones de nuestro sitio web. Este proyecto es un trabajo en curso.
Redis is an open source NoSQL database that offers low-latency in-memory storage of data structures. Web application developers find Redis a powerful ally for application caching, messaging, and many other operations.
Redis uses Lua for scripting, letting you consolidate more complicated tasks in an efficient way. Script logic gets executed on the database server, allowing them to be reused, and often increasing performance.
In this tutorial learn what Redis’ Lua scripting has to offer and how you can start using it on your Redis database. The tutorial covers the pros and cons of Redis scripting, creating and deploying scripts, and managing cached scripts.
Before You Begin
If you have not already done so, create a Linode account and Compute Instance. See our Getting Started with Linode and Creating a Compute Instance guides.
Follow our Setting Up and Securing a Compute Instance guide to update your system. You may also wish to set the timezone, configure your hostname, create a limited user account, and harden SSH access.
Follow the instructions in our How to Install a Redis Server guide to install a Redis server and command line interface (CLI). Be sure to use the drop-down menu at the top of the page to select your Linux distribution and view the appropriate steps.
sudo
. If you’re not familiar with the sudo
command, see the
Users and Groups guide.Why Use Lua Scripting on a Redis Server?
Scripting allows you to execute complex tasks within Redis. A Redis script allows you to use programming tools like control structures, while having access to almost all Redis commands.
So why would you use a Redis script over executing commands directly, or from your application itself? Because with scripts:
Tasks are executed directly on the database server, often increasing their performance substantially.
Logic lives directly on the database server, which can be useful for logic used across multiple applications.
Steps get executed atomically, meaning that the server prevents other actions while a script is still running.
Lua is the language for Redis scripting. The Lua language offers simplicity and conciseness, making it an effective language for scripting tasks.
However, scripts are not suited to all cases. Because the Redis server blocks other operations while a script is running, lengthy scripts may actually result in negative performance impacts.
Scripting also executes logic on the database. Doing so can lead to bad architectural and design practices when developers rely on it to implement application logic rather than data-level logic.
How to Write Lua Scripts for a Redis Server
Basic Redis scripts can be executed using the EVAL
command. The command executes scripts directly from the Redis CLI:
EVAL "return 'Hello, world!'" 0
"Hello, world!"
Redis’ Lua implementation has access to the redis.call
method, allowing you to execute most Redis commands from the Lua script. In this example, the Lua script executes the SET
command:
EVAL "redis.call('SET', KEYS[1], ARGV[1])" 1 example_key "Example Value"
The EVAL
command has a minimum of two arguments, and more if the second argument is greater than zero.
The first argument is the script itself. The Lua code for the script is wrapped in quotation marks.
The second argument is the number of keys. This is
1
in the example above, indicating that one key-value pair is used in the script. That key is identified withKEY[1]
in the script itself. Its corresponding value is indicated withARGV[1]
.The third argument contains key names. This is
example_key
in the example above. When the number of keys is greater than one, you need to provide a number of keys here equal to the number of keys argument.The fourth argument contains values. Above, this is
"Example Value"
. As with the key names argument, you need to provide an array of values equal to the number of keys.
A similar script with multiple keys and value could be:
EVAL "redis.call('SET', KEYS[1], ARGV[1]); redis.call('SET', KEYS[2], ARGV[2])" 2 example_key_1 example_key_2 "Example Value 1" "Example Value 2"
You do not always need to provide a value. For example, when using a read command like GET
:
EVAL "return redis.call('GET', KEYS[1])" 1 example_key_1
"Example Value 1"
More advanced usage leverages the capabilities of the Lua language. Here is a simple example to give you an idea:
EVAL "local key_name = 'example_key'; for iterated_value=0,4 do redis.call('hmset', KEYS[1], key_name .. tostring(iterated_value), iterated_value) end; return redis.call('hgetall', KEYS[1])" 1 example_hash
1) "example_key0"
2) "0"
3) "example_key1"
4) "1"
5) "example_key2"
6) "2"
7) "example_key3"
8) "3"
9) "example_key4"
10) "4"
How to Store Lua Scripts on a Redis Server
Redis scripts can be pre-loaded into memory for later execution. This feature is useful especially for scripts that need to be executed numerous times. This feature still allows you to provide different parameters for each script execution.
Using the SCRIPT LOAD
command stores a given script in Redis’ cache. Notice that you do not provide the script with parameters at this time. Instead, you provide the parameters whenever you call the script, as you can see further on:
SCRIPT LOAD "redis.call('set', KEYS[1], ARGV[1]); return redis.call('get', KEYS[1])"
"5afd00504d9d21a8fc37cd1b4400872d2e69296a"
Redis provides you with an SHA1 identifier for the new script. You can use that identifier with the EVALSHA
command to execute the script. The command takes the SHA1 identifier and the arguments for the script just as the EVAL
command would:
EVALSHA 5afd00504d9d21a8fc37cd1b4400872d2e69296a 1 example_key "Another example value"
"Another example value"
The script cache is volatile and not persisted. Thus, after some time or certain server events, the EVALSHA
command may return an error, indicating that the identified script has been purged from the cache:
(error) NOSCRIPT No matching script. Please use EVAL.
How to Use the Script Command to Manage Lua Scripts
Redis provides several SCRIPT
commands that give you a degree of control over scripts stored in the cache, such as the SCRIPT LOAD
command in the previous section.
The following list shows the other SCRIPT
commands used to manage scripts in cache.
SCRIPT EXISTS
lets you verify whether a script with a given SHA1 identifier exists. Above, you can see that theEVALSHA
command inherently indicates whether a script exists or not. But you can achieve cleaner and clearer code in some cases by using theSCRIPT EXISTS
command to explicitly check for a script:SCRIPT EXISTS "5afd00504d9d21a8fc37cd1b4400872d2e69296a"
1) (integer) 1
This response indicates that the script exists. A
0
response would indicate that the script does not exist in cache. Multiple SHA1 identifiers can be provided to the command, in which case the command returns multiple values of1
and/or0
, corresponding to each identifier.SCRIPT DEBUG
can be used to enable/disable debugging mode for Lua scripts. When debugging is enabled,EVAL
commands use the Lua debugger built into Redis.The debugging mode comes with two options. It can be run asynchronously using
SCRIPT DEBUG YES
. This has debugging operate on a separate session where it does not block Redis operations. With this option, changes are rolled back when the script finishes. Alternatively, debugging mode can be run synchronously usingSCRIPT DEBUG SYNC
. The script in this case blocks other Redis operations and saves changes just like scripts in normal mode.Most often, asynchronous debugging is preferable, as it lets you run scripts without significant consequence.
Redis recommends script debugging not be used in production environments. Using a testing or development server instead can prevent unforeseen consequences and performance impacts.
SCRIPT DEBUG YES EVAL "redis.call('set', KEYS[1], ARGV[1])" 1 another_example_key "A value" SCRIPT DEBUG NO
SCRIPT KILL
provides the only way to interrupt a running script, other than restarting the server. The command is used to stop scripts that have run over the maximum execution time. However, this command only works for scripts that have not yet modified any data:SCRIPT KILL
SCRIPT FLUSH
clears Redis’ script cache. This can be especially useful when working in a test environment, allowing you to clear out the cache for a new set of scripts to test:SCRIPT FLUSH
Conclusion
You are now prepared to step into the realm of Lua scripting on your Redis server. This tutorial covers everything you need to get started, from writing scripts to deploying and managing them.
Want to continue learning about Redis to get the most effective use out of your server? We have plenty of guides on using Redis that can help you navigate Redis data types, configurations, and more.
More Information
You may wish to consult the following resources for additional information on this topic. While these are provided in the hope that they will be useful, please note that we cannot vouch for the accuracy or timeliness of externally hosted materials.
This page was originally published on