Redis使用Lua脚本
本文内容纲要:
-1.基本用法
-2.主要优势
-3.实战
-4.脚本的安全性
-参考
1.基本用法
1.1EVALscriptnumkeyskey[key...]arg[arg...]
numkeys是key的个数,后边接着写key1key2...val1val2....,举例
127.0.0.1:6379>eval"return{KEYS[1],KEYS[2],ARGV[1],ARGV[2]}"2key1key2val1val2
1)"key1"
2)"key2"
3)"val1"
4)"val2"
1.2SCRIPTLOADscript
把脚本加载到脚本缓存中,返回SHA1校验和。但不会立马执行,举例
127.0.0.1:6379>SCRIPTLOAD"return'helloworld'"
"5332031c6b470dc5a0dd9b4bf2030dea6d65de91"
1.3EVALSHAsha1numkeyskey[key...]arg[arg...]
根据缓存码执行脚本内容。举例
127.0.0.1:6379>SCRIPTLOAD"return{KEYS[1],KEYS[2],ARGV[1],ARGV[2]}"
"a42059b356c875f0717db19a51f6aaca9ae659ea"
127.0.0.1:6379>EVALSHA"a42059b356c875f0717db19a51f6aaca9ae659ea"2key1key2val1val2
1)"key1"
2)"key2"
3)"val1"
4)"val2"
1.4SCRIPTEXISTSscript[script...]
通过sha1校验和判断脚本是否在缓存中
1.5SCRIPTFLUSH
清空缓存
127.0.0.1:6379>SCRIPTLOAD"return'hellojihite'"
"3a43944275256411df941bdb76737e71412946fd"
127.0.0.1:6379>SCRIPTEXISTS"3a43944275256411df941bdb76737e71412946fd"
1)(integer)1
127.0.0.1:6379>SCRIPTFLUSH
OK
127.0.0.1:6379>SCRIPTEXISTS"3a43944275256411df941bdb76737e71412946fd"
1)(integer)0
1.6SCRIPTKILL
杀死目前正在执行的脚本
2.主要优势
减少网络开销:多个请求通过脚本一次发送,减少网络延迟
原子操作:将脚本作为一个整体执行,中间不会插入其他命令,无需使用事务
复用:客户端发送的脚本永久存在redis中,其他客户端可以复用脚本
可嵌入性:可嵌入JAVA,C#等多种编程语言,支持不同操作系统跨平台交互
3.实战
直接在redis-cli中直接写lua脚本,这样非常不方便编辑,通常情况下我们都是把luascript放到一个lua文件中,然后执行这个lua脚本,
**示例:活跃用户判断:**判断一个游戏用户是否属于活跃用户,如果符合标准,则活跃用户人数+1
ifredis.call("EXISTS",KEYS[1])==1then
returnredis.call("INCRBY",KEYS[1],ARGV[1])
else
returnnil
end
存储位置:
/Users/jihite/activeuser.lua
执行
$redis-cli--eval/Users/jihite/activeuser.luauser,1
(integer)1
127.0.0.1:6379>getuser
"1"
127.0.0.1:6379>exit
$redis-cli--eval/Users/jihite/activeuser.luauser,1
(integer)2
$redis-cli
127.0.0.1:6379>getuser
"2"
127.0.0.1:6379>exit
$redis-cli--eval/Users/jihite/activeuser.luauser,4
(integer)6
4.脚本的安全性
如生成随机数这一命令,如果在master上执行完后,再在slave上执行会不一样,这就破坏了主从节点的一致性
为了解决这个问题,Redis对Lua环境所能执行的脚本做了一个严格的限制——所有脚本都必须是无副作用的纯函数(purefunction)。所有刚才说的那种情况压根不存在。Redis对Lua环境做了一些列相应的措施:
- 不提供访问系统状态状态的库(比如系统时间库)
- 禁止使用loadfile函数
- 如果脚本在执行带有随机性质的命令(比如RANDOMKEY),或者带有副作用的命令(比如TIME)之后,试图执行一个写入命令(比如SET),那么Redis将阻止这个脚本继续运行,并返回一个错误。
- 如果脚本执行了带有随机性质的读命令(比如SMEMBERS),那么在脚本的输出返回给Redis之前,会先被执行一个自动的字典序排序,从而确保输出结果是有序的。
- 用Redis自己定义的随机生成函数,替换Lua环境中
math
表原有的math.random函数和math.randomseed函数,新的函数具有这样的性质:每次执行Lua脚本时,除非显式地调用math.randomseed
,否则math.random
生成的伪随机数序列总是相同的。
参考
https://www.runoob.com/redis/redis-scripting.html(基本使用)
https://www.cnblogs.com/Don/articles/5731856.html(实例)
https://www.cnblogs.com/huangxincheng/p/6230129.html
https://redisbook.readthedocs.io/en/latest/feature/scripting.html#lua(安全性)
本文内容总结:1.基本用法,2.主要优势,3.实战,4.脚本的安全性,参考,
原文链接:https://www.cnblogs.com/kaituorensheng/p/11098194.html