黄东旭解析 TiDB 的核心优势
1237
2023-05-11
Redis进阶应用:Redis+Lua脚本实现复合操作
一、引言
减少网络开销:本来N次网络请求的操作,可以用一个请求完成。原先N次请求的逻辑放在Redis服务器上完成,减少了网络往返时延; 原子操作:Redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。这是一个重要特性,一定要拿小本本记好。至于为什么是一个原子操作,我们以后再分析; 复用:客户端发送的脚本会永久存储在Redis中。这样其他客户端就可以复用这一脚本,而不需要使用代码完成同样的逻辑。
所以现在流传一句话:要想学好Redis,必会Lua Script。
3.1 Redis的EVAL
Redis 127.0.0.1:6379> EVAL script numkeys key [key ...] arg [arg ...]
script:参数是一段 Lua 5.1 脚本程序。脚本不必(也不应该)定义为一个Lua函数。numkeys:用于指定键名参数的个数。 key [key ...]:从 EVAL 的第三个参数开始算起,表示在脚本中所用到的Redis键(key)。在Lua中,这些键名参数可以通过全局变量 KEYS 数组,用1为基址的形式访问( KEYS[1] ,KEYS[2],依次类推)。 arg [arg ...]:附加参数,在Lua中通过全局变量ARGV数组访问,访问的形式和KEYS变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)。
这里借用一下官网的例子。
上述脚本直接返回了入参。
eval为Redis关键字; 第一个引号中的内容就是Lua脚本; 2为参数个数; key1和key2是KEYS[1]、KEYS[2]的入参; first和second是ARGV[1],ARGV[2]的入参。
大家可以简单地将KEYS[1],KEYS[2], ARGV[1],ARGV[2]理解为占位符。
3.2 执行脚本文件和缓存脚本
如果只能在命令行中写脚本执行,遇到复杂的脚本程序岂不是会抓狂?
下面我们来看一下,如何让Redis执行Lua脚本文件,同时也验证一下lua脚本的复用特性(以后我们再也不需要定期批量删除某些符合特定规则的key了)。
Redis 127.0.0.1:6379> SCRIPT LOAD script Redis 127.0.0.1:6379> EVALSHA sha1 numkeys key [key ...] arg [arg ...]
Redis提供了一个SCRIPTLOAD命令,命令后面的script即为Lua脚本。命令将脚本script添加到脚本缓存中,但并不立即执行这个脚本。执行命令后,Redis会返回一个SHA1串,第二个EVALSHA命令即可执行。
需要注意的是,脚本可以在缓存中保留无限长的时间,直到执行完SCRIPT FLUSH。我们来看一下效果。
Redis还支持直接执行Lua脚本文件。首先编写并存储一个Lua脚本。
然后调用Redis-cli –eval命令。
Redis-cli –eval命令语法基本与原eval语法相同。
if Redis.call('get', KEYS[1]) == ARGV[1] then Redis.call('set', KEYS[1], ARGV[2]); return 1 else return 0 end
下面我们来测试一下这个脚本。
在Redis中执行lua脚本。
读到这里,希望你已经对Redis+Lua有了一定的了解,并能使用脚本完成一些简单的复合操作。后续还会继续更新一些基于Lua脚本+java程序实现的分布式数据结构,如延迟队列、可重入锁等,感兴趣的小伙伴可以持续关注。
戳这里,看该作者更多好文
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。