Get started quickly with Lua scripting language (for redis)

Table of contents

basic introduction

aim of design

Lua features

lua basic syntax 

variable

process control 

Redis executes lua script - EVAL instruction 

Case 1: Basic Case

Case 2: Dynamic parameter passing

 Case 3: Execute the redis class library method

Case 4: Dynamically pass parameters to redis class library methods

Case 5: The use of pcall function (understand) 

Performance optimization - EVALSHA instruction


basic introduction

Lua is a lightweight and compact scripting language , written in standard C language and open in the form of source code, designed to be embedded in applications, thus providing flexible extension and customization functions for applications

aim of design

It is designed to be embedded in applications, thus providing flexible extension and customization functions for applications.


Lua features

  1. Lightweight: It is written in standard C language and opened in the form of source code. After compilation, it only costs more than 100 K, and can be easily embedded in other programs.
  2. Extensible: Lua provides a very easy-to-use extension interface and mechanism: these functions are provided by the host language (usually C or C++), and Lua can use them as if they were built-in functions.
  3. Other features:
  • Supports procedure-oriented programming and functional programming; automatic memory management; only provides a general type of table (table), which can be used to implement arrays, hash tables, collections, and objects;
  • Language built-in pattern matching; closure (closure); function can also be regarded as a value; provide multi-threading (cooperative process, not the thread supported by the operating system) support;
  • Some key mechanisms required by object-oriented programming can be easily supported through closures and tables, such as data abstraction, virtual functions, inheritance and overloading, etc.

lua basic syntax 

Here we only introduce some syntax that may be used in redis.

variable

a = 5 -- 全局变量
local b = 5 -- 局部变量, redis只支持局部变量
a, b = 10, 2*x -- 等价于 a=10; b=2*x

process control 

if( 布尔表达式 1)
then
--[ 在布尔表达式 1 为 true 时执行该语句块 --]
elseif( 布尔表达式 2)
then
--[ 在布尔表达式 2 为 true 时执行该语句块 --]
else
--[ 如果以上布尔表达式都不为 true 则执行该语句块 --]
end

Redis executes lua script - EVAL instruction 

In redis, the lua script needs to be executed through the eval command.
Format:

EVAL script numkeys key [key ...] arg [arg ...]
script:lua脚本字符串,这段Lua脚本不需要(也不应该)定义函数。
numkeys:lua脚本中KEYS数组的大小
key [key ...]:KEYS数组中的元素
arg [art ...]:ARGV数组中的元素

Case 1: Basic Case

EVAL "return 10" 0

Output: (integer) 1 

Case 2: Dynamic parameter passing

EVAL "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 5 10 20 30 40 50 60 70 80 90
# 输出:10 20 60 70
EVAL "if KEYS[1] > ARGV[1] then return 1 else return 0 end" 1 10 20
# 输出:0
EVAL "if KEYS[1] > ARGV[1] then return 1 else return 0 end" 1 20 10
# 输出:1

Two parameters 10 and 20 are passed in, and the length of KEYS is 1, so there is an element 10 in KEYS, and the remaining 20 is the element of the ARGV array. 

The redis in redis.call() is a Lua script library provided in redis, which can only be used in the redis environment.

 Case 3: Execute the redis class library method

set aaa 10 -- 设置一个aaa值为10
EVAL "return redis.call('get', 'aaa')" 0
## 通过return把call方法返回给redis客户端,打印:"10"

NOTE: All keys used in the script should be passed in the KEYS array. But it is not mandatory, the price is that the script written in this way cannot be compatible with Redis cluster. 

Case 4: Dynamically pass parameters to redis class library methods

EVAL "return redis.call('set', KEYS[1], ARGV[1])" 1 bbb 20

After learning here, you can basically cope with the script knowledge required by redis distributed locks.

Case 5: The use of pcall function (understand) 

-- 当call() 在执行命令的过程中发生错误时,脚本会停止执行,并返回一个脚本错误,输出错误信息
EVAL "return redis.call('sets', KEYS[1], ARGV[1]), redis.call('set', KEYS[2],
ARGV[2])" 2 bbb ccc 20 30
-- pcall函数不影响后续指令的执行
EVAL "return redis.pcall('sets', KEYS[1], ARGV[1]), redis.pcall('set',
KEYS[2], ARGV[2])" 2 bbb ccc 20 30

Note: The set method is written as sets, and an error will definitely be reported.

Performance optimization - EVALSHA instruction

The EVAL command requires you to send the script body each time the script is executed. Redis has an internal caching mechanism, so it doesn't recompile the script every time, but in many cases, paying unnecessary bandwidth to transmit the script body is not the best choice. In order to reduce bandwidth consumption, Redis implements the EVALSHA command, which functions like EVAL and is used to execute lua scripts, but the first parameter it accepts is not the script, but the SHA1 encoding of the script.
The performance of the EVALSHA command is as follows:
if the server has a script corresponding to the SHA1 encoding, then this script will be executed; if the server does not have a script corresponding to the SHA1 encoding, then a special error will be returned to remind the user to use EVAL instead of EVALSHA

-- script load会对redis脚本进行sha1加密生成加密字符串,无论脚本多长,密文长度固定,会以密文为key缓存lua基本
SCRIPT LOAD "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}"
-- 通过密文方式执行缓存的lua脚本
EVALSHA a42059b356c875f0717db19a51f6aaca9ae659ea 2 aa bb cc dd
-- 判断缓存中是否存在某个lua脚本,有返回1,无返回0
SCRIPT EXISTS a42059b356c875f0717db19a51f6aaca9ae659ea
-- 删除缓存中的lua脚本
SCRIPT FLUSH

Guess you like

Origin blog.csdn.net/m0_62436868/article/details/130471646