Using Lua scripts in Redis can achieve atomic operations, reduce network overhead, and improve execution efficiency.
Redis's principle of executing Lua scripts
Redis has a built-in Lua interpreter that can execute Lua scripts directly on the server side. When executing Lua scripts, Redis will execute the script as a whole to ensure that the script will not be inserted by other commands during execution, thereby achieving atomic operations.
Basic usage method
Execute Lua scripts using the EVAL command
The EVAL command is used to execute Lua scripts in Redis, and its basic syntax is as follows:
EVAL script numkeys key [key ...] arg [arg ...]
script: The Lua script to be executed.
numkeys: The number of keyname parameters used in the script.
key [key ...]: key name parameter list.
arg [arg ...]: List of other parameters.
redis-cli EVAL "return ('SET', KEYS[1], ARGV[1])" 1 mykey myvalue
The function of the script return ('SET', KEYS[1], ARGV[1]) is to call the SET command of Redis and set the value of ARGV[1] to the corresponding key of KEYS[1].
1 means that the number of key name parameters used in the script is 1.
mykey is the key name parameter.
myvalue is another parameter.
Execute preloaded scripts using the EVALSHA command
To avoid transmitting the entire script content every time the script is executed, you can use the SCRIPT LOAD command to load the script into Redis, get a SHA1 hash value, and then use the EVALSHA command to execute the script through the hash value.
# Load the script and get the SHA1 hash valueredis-cli SCRIPT LOAD "return ('SET', KEYS[1], ARGV[1])" # Output example: "a1b2c3d4e5f6..." # Use the EVALSHA command to execute scriptsredis-cli EVALSHA "a1b2c3d4e5f6..." 1 mykey myvalue
Using Lua scripting in Go Redis
Here is an example of executing Lua scripts using the Go language and the go-redis library
package main import ( "context" "fmt" "/go-redis/redis/v8" ) func main() { rdb := (&{ Addr: "localhost:6379", Password: "", DB: 0, }) ctx := () // Define Lua scripts script := ` local key = KEYS[1] local value = ARGV[1] return ('SET', key, value) ` // Execute Lua scripts result, err := (ctx, script, []string{"mykey"}, "myvalue").Result() if err != nil { ("Failed to execute Lua script:", err) return } ("Script execution result:", result) }
Redis API in Lua scripts
In Lua scripts, you can use and functions to call the Redis command:
: Call the Redis command. If the command execution error occurs, the script will terminate and return an error message.
: Call the Redis command. If the command execution error occurs, the script will not terminate, but will return a Lua table containing the error message.
Call example:
package main import ( "context" "fmt" "/go-redis/redis/v8" ) func main() { rdb := (&{ Addr: "localhost:6379", Password: "", DB: 0, }) ctx := () // Define Lua scripts script := ` ('SET', KEYS[1], ARGV[1]) local value = ('GET', KEYS[1]) return value ` // Execute Lua scripts result, err := (ctx, script, []string{"mykey"}, "myvalue").Result() if err != nil { ("Failed to execute Lua script:", err) return } ("Script execution result:", result) }
pcall example:
package main import ( "context" "fmt" "/go-redis/redis/v8" ) func main() { rdb := (&{ Addr: "localhost:6379", Password: "", DB: 0, }) ctx := () // Define the Lua script that contains script := ` local result = ('GET', 'nonexistent_key') if type(result) == 'table' and then return 'Error: ' .. else return result end ` // Execute Lua scripts result, err := (ctx, script, []string{}).Result() if err != nil { ("Failed to execute Lua script:", err) return } ("Script execution result:", result) }
Things to note
Atomicity: Lua scripts are executed atomically in Redis, but be careful that the execution time of the script should not be too long, otherwise it will block requests from other clients.
Performance: Using Lua scripts rationally can reduce network overhead and improve execution efficiency, but if the scripts are too complex, it may affect performance.
Data type: The data type in the Lua script and the data type of Redis need to be converted appropriately.
Lua Comments
Single line comments
In Lua, use two hyphens -- to enable single-line comments. After -- the content until the end of the line will be considered a comment and will not be executed by the Lua interpreter.
-- This is a single line comment
local num = 10 -- Define a variable num and assign a value of 10
Multi-line comments
Multi-line comments start with --[[ and end with ]]. Everything between these two tags belongs to comments, no matter how many lines it spans.
--[[
This is a multi-line comment
Can contain many lines of content
Used to provide detailed description of code blocks
]]
local str = "Hello, World!"
Lua Basic Syntax
variable
Lua is a dynamically typed language, and variables do not need to be declared in advance. Common variable types are nil, boolean, number, string, table, function, thread, and userdata.
Global variables: By default, variables are global variables. The value of the unassigned global variable is nil.
-- Define a global variable
message = "Hello, Lua!"
print(message)
Local variables: Declare local variables using the local keyword, and their scope is limited to the code blocks that declare it.
do
local num = 20
print(num) -- Can be accessed within the code block
end
-- print(num) -- An error occurs here because num is a local variable, out of scope
Data Type
1. Boolean type
There are only two values: true and false. In conditional judgment, except for false and nil, all other values are considered true.
local isEnabled = true if isEnabled then print("Enabled") end
2. Number type (number)
The number type in Lua is a double-precision floating point number by default.
local num1 = 10 local num2 = 3.14 print(num1 + num2)
3. String type (string)
Single or double quotes can be used to represent strings.
local str1 = 'Hello' local str2 = "World" print(str1 .. " " .. str2) -- use .. Do string stitching
4. Table type (table)
The most powerful data type in Lua can be used as arrays, dictionaries, etc. The table is created using curly braces {}.
-- Used as an array local fruits = {"apple", "banana", "cherry"} print(fruits[1]) -- Index from 1 start -- Used as a dictionary local person = {name = "John", age = 30} print()
Control structure
1. if-else statement
local score = 80 if score >= 90 then print("A") elseif score >= 80 then print("B") else print("C") end
2. for loop
Numerical for loop: used to traverse a numerical range.
for i = 1, 5 do print(i) end
Generic for loop: used to traverse iterators, such as arrays or tables.
local fruits = {"apple", "banana", "cherry"} for index, value in ipairs(fruits) do print(index, value) end
3. while loop
local count = 0 while count < 3 do print(count) count = count + 1 end
function
Functions are defined using the function keyword, and can have parameters and return values.
function add(a, b) return a + b end local result = add(3, 5) print(result)
This is the article about the principles and basic usage of lua scripts in redis. For more related contents of using lua scripts, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!