前言
在实际工作过程中,可以使用lua脚本来解决一些需要保证原子性的问题,而且lua脚本可以缓存在redis服务器上,势必会增加性能。
然而在redis的官网上洋洋洒洒的大概提供了200多个命令,貌似看起来很多,但是这些都是别人预先给你定义好的,但你却不能按照自己的意图进行定制,
所以是不是感觉自己还是有一种被束缚的感觉,有这个感觉就对了。。。
一:Lua脚本
说来也巧,redis的大老板给了你解决这种问题的方法,那就是Lua脚本,而且redis的最新版本也支持Lua Script debug,这应该也是未来Redis的一
个发展趋势,要想学好Redis,必会Lua Script。。。
有趣的是,官网上还提供了一个视频教程教你如何进行Debug操作。。。 【https://redis.io/topics/ldb】 youtube上面的视频,要是被墙了,记得
上VPN哦。。。淘宝上不知道有没有售卖这种同款的吸顶灯~~~
二:使用Redis-Cli Lua Script 解决几个灵活性问题
1. Lua语法的问题
lua是一门编程语言,所以这个就已经超出了redis本身的范畴,如果大家想好好学习一下,可以看下http://www.lua.org/ 的官网,然后下载一下玩一玩。
比如这里我下载了一个windows版本的lua 编译器,具体语法上就不细说了。。有了这个主题,我们再进行下一个环节。
2. Eval的使用
EVAL script numkeys key [key ...] arg [arg ...]
首先大家一定要知道eval的语法格式,其中:
<1> script: 你的lua脚本
<2> numkeys: key的个数
<3> key: redis中各种数据结构的替代符号
<4> arg: 你的自定义参数
ok,可能乍一看模板不是特别清楚,下面我可以用官网的小案例演示一下:
eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 username age jack 20
上面这一串代码大概是什么意思呢? 第一个参数的字符串就是script,也就是lua脚本。2表示keys的个数,KEYS[1] 就是 username的占位符, KEYS[2]就是
age的占位符,ARGV[1]就是jack的占位符,ARGV[2]就是20的占位符,,以此类推,,,所以最后的结果应该就是:{return username age jack 20} 是不
是有点像C#中的占位符:{0}呢???下面我在Redis中给大家演示一下:
[root@localhost Desktop]# redis-cli 127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 username age jack 20 1) "username" 2) "age" 3) "jack" 4) "20" 127.0.0.1:6379>
通常境况下,我们不要在redis-cli中直接写lua脚本,这样非常不方便编辑,通常情况下我们都是把lua script放到一个lua文件中,然后执行这个lua脚本,比如
下面这样:
然后我们通过下面命令执行,这种方式和前面介绍的不一样,参数 --eval script key1 key2 , arg1 age2 这种模式,key和value用一个逗号隔开就好了,
最后我们也看到了,数据都出来了,对吧。
[root@localhost Desktop]# redis-cli --eval /usr/redis/sbin/1.lua username age , jack 20 1) "username" 2) "age" 3) "jack" 4) "20" [root@localhost Desktop]#
三:实战
下面我可以构思几个小案例通过lua解决。
1. 通过lua脚本获取指定的key的List中的所有数据
local key=KEYS[1] local list=redis.call("lrange",key,0,-1); return list;
这里面的redis.call就是用来执行redis中list的lrange命令,接下来我通过lpush给person塞入三条数据,如下:
[root@localhost Desktop]# redis-cli 127.0.0.1:6379> lpush person mary jack peter (integer) 3 127.0.0.1:6379>
然后我们来执行这个lua脚本,效果如下图,是不是很牛逼的感觉???
有了这个1+1的效果,就可以玩些更复杂的操作。比如:
2.根据外面传过来的IDList 做“集合去重”的lua脚本逻辑:
local key=KEYS[1]; local args=ARGV local i=0; local result={}; for m,n in ipairs(args) do local ishit=redis.call("sismember",key,n); if(ishit) then table.insert(result,1,n); end end return result;
2. 找到hash中age小于指定值的所有数据,lua脚本如下:
local result={}; local myperson=KEYS[1]; local nums=ARGV[1]; local myresult =redis.call("hkeys",myperson); for i,v in ipairs(myresult) do local hval= redis.call("hget",myperson,v); redis.log(redis.LOG_WARNING,hval); if(tonumber(hval)<tonumber(nums)) then table.insert(result,1,v); end end return result;
大家可以试着看下这段脚本,然后按照这个逻辑自己玩一玩,很有意思的,还是那句话,学好redis,必会Lua。。。。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对小牛知识库的支持。
主要内容:第一个Lua脚本命令,为什么使用Lua脚本,常用脚本命令,基本命令应用从 Redis 2.6 版本开始,Redis 使用内置的 Lua 解释器执行脚本,这意味着我们可以直接在 Redis 客户端执行Lua 脚本 ,于此同时 Redis 还非常贴心地提供了用于编写 Lua 脚本的 命令。 第一个Lua脚本命令 Lua 是一种轻量小巧、开源的脚本语言,用标准 C语言编写。其设计目的就是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。它被广泛的应用于:游戏开发
主要内容:Redis Lua脚本的引入,开源软件的可扩展性,Redis的扩展性脚本,Redis Lua脚本的基本使用,通过EVAL命令执行Lua脚本,通过脚本与Redis交互,Java中调用Redis Lua脚本,Java调用Lua脚本的方式,Redis Lua脚本的使用建议,脚本缓存,脚本缓存稳定性,脚本参数化,脚本超时处理,Redis集群中Lua脚本的使用,其他限制,Redis 7 Functions,,,Redis Lua脚本的详细介绍以及使用入门。 本次的主要分享主题是:Redis Lu
问题内容: 是否可以使一个Redis Lua脚本命中多个数据库?我目前在DB 0中拥有一种类型的信息,而在DB 1中具有另一种类型的信息。我的正常工作流程是基于API调用以及来自DB 0的元信息对DB 1进行更新。 Lua脚本,但无法弄清楚如何打多个数据库。我正在使用redis-py在Python中执行此操作: 由于客户端暗示一个特定的数据库,所以我被困住了。有想法吗? 问题答案: 将相关数据放入
问题内容: 我正在设置将使用Redis和APCu的PHP标记的缓存实现。由于APC是键值存储,因此我将使用Redis进行键标记关系,并与APC上的每个Web服务器进行同步。 我当前的问题仅涉及Redis。可能您知道实现,但需要明确说明:键可以具有与之关联的标签。在以后的某个时间点,您可以通过某些标签删除缓存的密钥。有很多键,但没有那么多标签,并且键和标签之间存在n对n的关系。 由组成: 因为设置后
问题内容: 我创建了一个redis lua脚本来执行基于关键数据类型的命令: 每次执行时,它都会返回null。请帮助纠正脚本。 问题答案: 对响应的返回形式如下表:(如果类型为字符串,则返回) 因此,为了正确检查,您应该将代码更改为: 其余代码将正常运行。 问题是这样的:TYPE命令是少数几个返回“简单字符串”或“状态” redis答复的命令之一(有关响应类型,请参见redis协议规范)。在red
问题内容: 以下是我的lua脚本: 如果第一次调用没有退出键,我将不执行第二次调用。 所以…我不知道None的返回值是什么。在python中,返回值将为None。 所以…我该怎么办lua? 使用零时 问题答案: 如果在if语句中使用定义局部变量,则它仅在if语句中存在。在手册中查看局部变量范围。 尝试
我是一个新的编码员,我的任务是:用谷歌应用程序脚本发送格式化的电子邮件,但不同的内容取决于谁将收到电子邮件(如姓名、截止日期、日期、一些小事情…)所以我尝试编写这个任务,使用java脚本和html,但现在我被困在这里。 如果我使用此方法:“MailApp.sendEmail(电子邮件地址、收件人、主题、邮件)”= 所以我改为另一种方法:“MailApp.sendmail(emailAddress,
问题内容: 我想在单个调用中使用键列表从Redis获取所有集合。根据文档,Redis为此提供了SSCAN命令,但是由于我使用StackExchange.Redis作为Redis适配器,因此我猜想此命令在此适配器中没有任何此类方法。所以我要寻找两件事: 我期待使用LUA脚本执行SSCAN,但无法在Internet上找到任何此类示例。任何人都可以共享使用多个SET键从LUA调用SSCAN的方法。 同样