Mastering Redis Lua Scripting: Essential Syntax and Best Practices
This article explains how Redis introduced Lua scripting to combine multiple commands atomically, covers Lua basics, data types, control structures, script execution with EVAL/EVALSHA, script management commands, and practical tips for writing efficient, safe Redis Lua scripts.
1. Introduction
Redis is a high‑performance in‑memory KV store that can do more than simple caching; developers often need to combine several Redis commands into a single atomic operation, which Redis supports via Lua scripts introduced in version 2.6.
2. Lua
Lua is a lightweight, embeddable language originally popular in game development (e.g., World of Warcraft plugins) and widely used as a scripting layer for C/C++ applications because of its small footprint.
Even Nginx supports Lua, enabling many useful extensions.
3. Lua Is Easy
Redis documentation advises against writing overly complex logic inside Lua scripts.
For developers familiar with Java, using a lightweight subset of Lua inside Redis is straightforward. The essential Lua types used in Redis scripts are: nil – null boolean – true/false number – numeric values string – text table – array‑like or dictionary‑like structure (similar to Java HashMap).
Variable Declaration
Variables are declared without explicit types:
--- global variable
name = 'felord.cn'
--- local variable
local age = 18Prefer local variables for better performance; avoid global variables in scripts.
Table Type
The table type can act as an array or a map. Example of an array:
arr_table = {'felord.cn','Felordcn',1}
print(arr_table[1]) -- felord.cn
print(arr_table[3]) -- 1
print(#arr_table) -- 3Example of a map:
arr_table = {name='felord.cn', age=18}
print(arr_table['name']) -- felord.cn
print(arr_table.name) -- felord.cn
print(arr_table[1]) -- nil
print(arr_table['age']) -- 18
print(#arr_table) -- 0Be cautious when using # to get a table’s length; mixed tables may give inaccurate results. Avoid nil elements and use loops to compute real length.
Conditional Statements
local a = 10
if a < 10 then
print('a小于10')
elseif a < 20 then
print('a小于20,大于等于10')
else
print('a大于等于20')
endArray Loop
local arr = {1,2,name='felord.cn'}
for i, v in ipairs(arr) do
print('i = '..i)
print('v = '..v)
end
print('-------------------')
for i, v in pairs(arr) do
print('p i = '..i)
print('p v = '..v)
endOutput demonstrates iteration order for numeric indices and key‑value pairs.
4. Redis Lua
EVAL Command
Execute a Lua script directly:
EVAL luascript numkeys key [key ...] arg [arg ...] EVAL– command keyword. luascript – the Lua code. numkeys – number of keys the script will access (length of the KEYS array). key – one or more keys, accessed in the script via KEYS[INDEX]. arg – additional arguments, accessed via ARGV[INDEX].
Example retrieving the value of key hello:
set hello world
get hello -> "world"
EVAL "return redis.call('GET',KEYS[1])" 1 hello -> "world"The numkeys argument is mandatory; omitting it leads to errors.
redis.call vs redis.pcall
redis.call()throws an error on failure, while redis.pcall() returns a table containing the error, similar to Java exception handling.
EVAL "return redis.call('no_command')" 0 -> error
EVAL "return redis.pcall('no_command')" 0 -> error tableValue Conversion
Data transferred between Lua and Redis may lose precision (e.g., floating‑point numbers). Converting to string with tostring() preserves the exact value.
EVAL "return 3.14" 0 -> integer 3
EVAL "return tostring(3.14)" 0 -> "3.14"Passing strings and integers is safe; other types require careful verification.
Atomic Execution
Lua scripts run atomically: while a script is executing, all other client commands are blocked until the script finishes.
Script Management
SCRIPT LOAD
Load a script into the server cache and obtain its SHA1 identifier for later reuse with EVALSHA.
SCRIPT LOAD "return 'hello'"
# returns SHA1 hash
EVALSHA <sha> 0 -> "hello"SCRIPT FLUSH
Clears all cached scripts; not recommended in production because it removes every script.
SCRIPT EXISTS
Check whether one or more cached scripts exist by their SHA1 hashes.
SCRIPT EXISTS <sha1> <sha2>
# returns 1 for existing, 0 otherwiseSCRIPT KILL
Attempts to abort a running script, but cannot guarantee termination; for forced termination, a server shutdown without persistence may be required.
Additional Tips
Thoroughly test Lua scripts; partial execution is not rolled back on errors.
Avoid random functions inside scripts.
Do not define functions; the whole script is already a function body.
Declare all variables with local.
When using Redis Cluster, ensure all accessed keys belong to the same slot (e.g., via Redis hash tags).
Keep scripts simple and efficient to avoid blocking other clients.
5. Summary
The article covered the scenarios where Redis Lua scripting is useful, introduced the essential Lua syntax required for writing Redis scripts, demonstrated practical examples, and highlighted important considerations for safe and performant script development.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
