使用lua语言编写脚本传到redis中执行的好处:
1.减少网络开销(一个脚本只发送一个请求)
2.原子操作
3.可复用
Lua语言
高效的轻量级脚本语言(IOS游戏经常使用,通过修改脚本来实现相映功能,减少上线次数,要审核的)
一、数据类型
二、变量
脚本只能使用局部变量local,不能使用全局变量,默认值nil
–声明一个局部变量c,默认值nil
local c
–同时声明多个局部变量
local e,f=1,2
三、注释
单行注释:–
多行注释:–[[ ]]
四、操作符
数学操作符(如果是字符串会自动转为数字):+,-,*,/,%,^
比较操作符(如果是字符串不会自动转为数字):==,~=,<,>,<=,>=
逻辑操作符(操作数不是nil或false,都为真;支持短路):not,and,or
连接操作符:…
例:
print(‘hello’ …’’…‘world!’) --hello world!
五、取长度操作符
#
例:
print(#‘hello’) --5
六、if语句
if 条件表达式 then
语句块
elseif 条件表达式 then
语句块
else
语句块
end
七、循环语句
while语句:
while 条件表达式 do
语句块
end
repeat语句:
repeat
语句块
until 条件表达式
for语句:
for 变量=初值,终值,步长(或省) do
语句块
end
for 变量1,变量2,…,变量n in 迭代器
do
语句块
end
八、表类型
表定义(索引从1开始):a={} --将变量a赋值为一个空表
例:
people={
name=‘mm’,
age=29
}
print(people.name)
a[1]=‘dkidk’
print(a[1])
遍历:
for index,value in ipairs(a) do
print(index)
其中ipairs(a)类似#a
for i=1,#a do
print(i)
九、函数
function(参数列表)
函数体
end
local function 变量名称(参数列表)
函数体
end
例:
local square=function(num)
return num*num
end
Lua标准库
1.String库
获得字符串长度:string.len(s)
转换大小写:
string.lower(s)
string.upper(s)
获取子字符串:
string.sub(s,start,end)
例:string.sub(‘hello’,2) --ello
2.Table库
数组转为字符串:table.concat(table[,sep[,i[,j]]])
print(‘table,concat({1,2,3}) --123
print(‘table,concat({1,2,3},’,’,2) --2,3
向数组中插入元素:
table,insert(table,[pos,],value)
a={1,2,4}
table,insert(a,3,4)
print(talbe,concat(a,’,’))
–,2,4,4
删除一个元素并弹出:table.remove(table[,pos])
3.Math库
math.rando(n,m)
其它库:
cjson库和cmsgpack库对JSON和MessagePack进行支持
people={
name=‘mm’,
age=29
}
– 使用cjson序列化成字符串:
local json_people_str = cjson.encode(people)
– 使用cmsgpack序列化成字符串:
local msgpack_people_str = cmsgpack.pack(people)
– 使用cjson将序列化后的字符串还原成表:
local json_people_obj = cjson.decode(people)
print(json_people_obj.name)
– 使用cmsgpack将序列化后的字符串还原成表:
local msgpack_people_obj = cmsgpack.unpack(people)
print(msgpack_people_obj.name)
在脚本中调用redis命令
redis.call(…),函数后将5种类型的回复转换成对应的lua数据类型(nil对应lua的faluse)
例如:
redis.call(‘set’,‘num’,‘aa’)
脚本相关命令
执行脚本 :
eval 脚本内容 参数数量 [key…] [arg…]
evalsha:通过调用脚本内容的SHA1摘要来执行脚本,eval命令会计算脚本SHA1摘要并记录在脚本缓存中,执行evalsha时,redis会根据摘要从脚本缓存中查找相应的脚本内容,找不到会报错。
例:
127.0.0.1:6379> eval “return redis.call(‘SET’,KEYS[1],ARGV[1])” 1 foor bar
OK
127.0.0.1:6379> get foor
“bar”
沙盒:
redis脚本禁止使用lua标准库中与文件或系统调用相关的函数禁用脚本的全局变量保证每个脚本相对隔离,对随机数产生的随机结果做控制,对无序数组做控制 :smembers,hkeys都会先进行排序再执行lua脚本。
目的:保证脚本执行结果只与脚本本身和传参有头,执行结果可重现。
其他脚本相关命令:
1.将脚本加入缓存:script load
例:script load “return 1”
2.判断脚本是否已经被缓存:script exixts
3.清空脚本缓存:script flush
4.强制终止当前脚本的执行:script kill