在使用redis的过程中,发现有时候操作redis命令需要原子性,redis的lua脚本正好可以实现这个功能。本文主要介绍lua脚本在redis中的简单使用,有需要的朋友可以参考一下。
:
目录
1.背景2。使用lua脚本3。lua和redis 4之间的数据类型转换。lua脚本5中的输出日志。一个简单的限流盒6。lua脚本7的调试。参考文件
一、背景
在使用redis的过程中,发现有时候操作redis命令需要原子性,redis的lua脚本正好可以实现这个功能。比如:扣库存、限流等。
虽然redis的流水线化划线也可以一次执行一组命令,但是如果在这组命令的执行过程中需要根据上一步的结果进行一些判断,就无法实现。
二、使用lua脚本
Redis使用Lua 5.1的脚本规范,我们写脚本时不需要定义Lua函数。同时不能使用全局变量等等。
1.lua脚本的格式及注意事项
1.格式
EVAL文数字密钥[密钥.arg [arg.]
127 . 0 . 0 . 1:6379 eval ' return { KEYS[1],ARGV[1],ARGV[2]}' 1 key1 arg1 arg2
1)“按键1”
2)“arg 1”
3)“arg 2”
127.0.0.1:6379
2.有关注意事项
Lua脚本中redis操作的键最好通过键传递,而不是写死。否则,Redis集群可能会出现问题。
1.写得好
127 . 0 . 0 . 1:6379 eval ' return redis . call(' set ',KEYS[1],'张三')' 1用户名
好
127.0.0.1:6379获取用户名
张三
redis命令操作的密钥是通过KEYS获得的。
2.拙劣的写作
127 . 0 . 0 . 1:6379 eval ' return redis . call(' set ',' username ','张三')' 0
好
127.0.0.1:6379获取用户名
张三
redis命令操作的键是直接写的。
2.将脚本加载到redis中
要求:这里定义了一个lua脚本,返回输入参数的值1。
注意:
当我们将lua脚本加载到redis中时,这个脚本不会立即执行,而是会被缓存并返回sha1校验和。稍后,我们可以通过EVALSHA执行这个脚本。
在这里,我们记住了这个脚本加载后返回的哈希值,这个哈希值将在下次执行时使用。
127.0.0.1:6379脚本加载“return tonumber(KEYS[1]) 1”
' ef 424d 378d 47 e 7a 8 b 725259 CB 717d 90 a 4 b 12 a 0 de '
127.0.0.1:6379
3.执行lua脚本
1.通过评估执行
127 . 0 . 0 . 1:6379 eval ' return to number(key[1])1 ' 1 100
(整数)101
127.0.0.1:6379
2.通过evalsha执行
ef 424d 378d 47 e 7 a 8 b 725259 CB 717d 90 a 4b 2 a 0 de的值是在上一步通过脚本加载加载脚本后得到的。
127 . 0 . 0 . 1:6379 eval sha ef 424d 378d 47 e 7a 8 b 725259 CB 717d 90 a 4 b 12 a 0 de 1 100
(整数)101
127.0.0.1:6379
通过evalsha执行的好处是可以节省带宽。如果我们的lua脚本比较长,那么在程序执行过程中发送lua脚本到redis服务器可能会消耗更多的带宽,但是如果发送哈希值,消耗的带宽会比较少。
4.确定该脚本是否在redis服务器缓存中。
127.0.0.1:6379脚本加载“return tonumber(KEYS[1]) 1”
' ef 424d 378d 47 e 7a 8 b 725259 CB 717d 90 a 4 b 12 a 0 de '
127.0.0.1:6379脚本存在ef 424d 378d 47 e 7a 8 b 725259 CB 717d 90 a 4 b 12 a 0 de
1)(整数)1
127.0.0.1:6379脚本存在不存在-sha1
1)(整数)0
127.0.0.1:6379
5.清除服务器上的脚本缓存。
注意:
我们无法清除某个脚本的缓存,只能清除所有的缓存。一般不需要清除它们,因为即使有大量的脚本,也不会占用太多的服务器内存。
127.0.0.1:6379脚本加载“return tonumber(KEYS[1]) 1”
' ef 424d 378d 47 e 7a 8 b 725259 CB 717d 90 a 4 b 12 a 0 de '
127.0.0.1:6379脚本存在ef 424d 378d 47 e 7a 8 b 725259 CB 717d 90 a 4 b 12 a 0 de
1)(整数)1
127.0.0.1:6379脚本刷新
好
127.0.0.1:6379脚本存在ef 424d 378d 47 e 7a 8 b 725259 CB 717d 90 a 4 b 12 a 0 de
1)(整数)0
6.杀死行书。
127.0.0.1:6379脚本删除
注意:
这个命令只能终止正在运行的只读脚本。
此命令不能终止已修改数据的脚本,只能使用shutdown nosave命令。
脚本执行的默认超时时间为5分钟,可以通过重定向。会议配置文件的月球时间限制配置项修改。
脚本即使到达了超时时间,也不会停止执行,因为这违反了月亮!月亮脚本的原子性。
三、lua和redis数据类型转换
月亮!月亮的数据类型和再说一遍的数据类型存在一对一的转换关系,如果将再说一遍类型转换成月亮!月亮类型,然后在转换成再说一遍类型,那么结果和初试值是一致的。
1 .{ 1 }类型转换
重定向到Lua换算表.
redis整数回复-月亮数-重复整数回复-月球编号
redis批量回复-月亮串-重复批量回复-月球字串
Redis多批量回复-月表(可能有其它雷迪斯数据类型嵌套)
重定向状态应答-包含单个好的字段的月表包含状态
重复错误响应-包含错误的单个错误字段的月球表
Redis无批量回复和nil多批量回复-Lua假布尔类型
月亮要折回表。
卢娜数-雷迪斯整数响应(数字转换为整数)
Lua字符串- Redis批量回复(字符串-重定向批量响应)
Lua表(数组)重定向多批量响应(截断到Lua阵列内的第一个零,如果有)
月台带有单好的场-里兹状态应答
带有单个错误字段的月表-重复错误响应
布尔型false - Redis Nil批量回复。
2 ._额外的转换规则
月亮!月亮的布尔类型,月亮的真的吗会转换成再说一遍的一
三、3个重要规则
1.数字类型
在月亮!月亮中,只有一个号码(数字)类型,整数和浮点数之间没有区别,如果我们在月亮!月亮中返回一个浮点数,实际返回的是一个整数,如果要返回浮点数,需要以字符串的方式返回。
127.0.0.1:6379评估版返回3.98' 0
(整数)3
127.0.0.1:6379评估版返回' 3.98'' 0
" 3.98 "
2.月亮!月亮数组存在尼罗州
当再说一遍将月亮!月亮数组转换为再说一遍协议时,如果遇到尼罗州,则转换会停止。即尼罗州后的值都不会返回。
127.0.0.1:6379 eval 'return {1,2,' data ',nil,'不能返回值,' v'}' 0
1(整数)1
2)(整数)2
3)'日期
127.0.0.1:6379
3.月亮!月亮的表。表类型包含建和值
出现这种情况返回的再说一遍的是一个空数组
127 .0 .0 .1:6379 eval ' return { key 1=' value 1 ',key2='value2'}' 0
(空数组)
127.0.0.1:6379
四、lua脚本中输出日志
这个一般调试我们的脚本的时候比较有用。
重做日志(日志级消息)
日志级别(日志级别)的取值范围:
再说一遍LOG_DEBUG(日志调试)
再说一遍日志_详细
再说一遍. LOG_NOTICE(日志通知)
再说一遍LOG_WARNING(日志警告)
举例:
五、一个简单限流的案例
1 .{ 1 }需求
在一秒钟之内,方法最大的并发只能是5个。
一秒钟和5当作参数传递。
2 ._实现步骤
1 .{ 1 }编写月亮!月亮脚本
-输出用户传递进来的参数
对于我,v(成对的关键点)
重做日志(重做日志)。日志_通知,”限制:关键点"-什么一、导言-什么'='-什么(五)
结束了
对于一、五成对(ARGV) do
重做日志(重做日志)。日志_通知,”限制:argv "-什么一、导言-什么'='-什么(五)
结束了
-限流的关键点
局部limitKey=tostring(KEYS[1])
-限流的次数
局部限制=无级(ARGV[1])
-多长时间过期
本地过期=强调(ARGV[2])
-当前已经执行的次数
本地当前=非成员(redis。调用(' get ',limitKey)或' 0 ')。
-设置一个断点
重定向断点()
重做日志(重做日志)。日志_通知,”限制密钥:"-什么tostring(limitKey)什么'我不知道在[.]-什么tostring(过期)什么]毫秒内已经访问了'我不知道-什么tostring(当前)-什么'我不知道次,最多可以访问:"-什么极限值-什么'我不知道次)
-限流了
如果(电流1限值)则
返回{ true }
结束了
-未达到访问限制
-访问次数一
重复呼叫(' incrby ',limitKey,' 1 ')"
如果(电流==0)则
-设置过期时间
重复呼叫(' can expir ',limitKey,expirems)
结束了
返回{ false }
2 ._程序中执行月亮!月亮脚本
完整代码:339吉提。com/Huan 1993/春云-父母/树/主人/春开机/春开机-redis-moon
六、lua脚本的debug
当我们编写好了月亮!月亮脚本后,如果在执行的过程中发生了错误,那么我们如何该如何解决呢?此处我们来了解下如何月球调试脚本。
一月脚本中的几个小命令
在脚本中打一个断点
重定向断点()
2 ._断点调试
1 .{ 1 }执行命令
redis-cli - ldb -评估限制.呼叫的月球,1000
limit.lua需要调试的lua文件。
被调用的是在lua脚本中传递给键的值。
1和1000是在lua脚本中传递给ARGV的值。
,它分隔KEYS和ARGV的值。
2.一些调试说明
帮助:列出了可用的调试命令。
或者s n:运行到当前行停止(当前行还没有执行)。
c:运行到下一个断点,也就是lua脚本中redis.breakpoint()方法存在的地方。
List:列出当前行周围的一些源代码。
p:打印出所有局部变量的值。
P var:打印特定局部变量的值。
r:执行redis命令
-例如:
r设置键值
r获取密钥
3.调试运行结果
七、参考文档
https://redis.io/topics/ldb
https://redis.io/commands/eval
关于redis中lua脚本的简单使用的这篇文章就到这里了。关于在redis中使用lua脚本的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望大家以后能多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。