Lua 脚本功能是 Reids 2.6 版本开始提供的高级功能, 我们可以通过redis内嵌的 Lua 环境的进行搞复杂的需求。
使用内置的lua脚本环境可以解决Redis长久以来不能高效地处理 CAS (check-and-set)命令的缺点, 并且可以通过组合使用多个命令, 轻松实现以前很难实现或者不能高效实现的模式。


该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新。 

http://xiaorui.cc/?p=3052

我对redis lua的两个粗浅的看法:

1.  Lua作为脚本自己本身的性能是很高效的,有尝试过nginx lua组合的朋友应该能感受到。redis lua适合在单机单实例中使用,因为现在市面上的redis proxy都没有实现对于lua的调度支持。 大多数redis proxy代理只是实现了command和key的一致性hash而已。 

问题是我们为了高性能往往都是一个实例,一个cpu核心.  所以在redis集群的场景下这redis不适合. 

2.  redis lua 虽然内置了很多的模块组件,已经足够我们去写复杂的逻辑了。  但redis lua为了安全着想,屏蔽了很多的基本命令。 比如 os.time(), Date, hash 。

我为什么会需要os.Time() ,因为我需要做时序队列,为什么需要hash,因为有去重的需求,我把文档做成hash md5,扔到set集合里。但redis lua没有内置hash的函数或方法。

值得高兴的是redis lua含有解析构建json的cjson,还有能处理二进制MessagePack的cMessagePack。 

Redis 对 Lua 环境做了一些列相应的安全措施:

1. 不提供访问系统状态状态的库,时间也不可以。 虽然通过redis.call(“TIME”) 可以拿到时间戳,但这时间戳不能写入任务一个键值里,只能提供比对的功能。 
2. 禁止使用 loadfile 函数, 也就是 require “os”
3. 如果脚本执行了带有随机性质的读命令(比如 SMEMBERS ),那么在脚本的输出返回给 Redis 之前,会先被执行一个自动的字典序排序,从而确保输出结果是有序的。

经过这一系列的调整之后, Redis 可以保证被执行的脚本:
1. 没有有害的随机性。
2. 对于同样的输入参数和数据集,总是产生相同的写入命令。

最重要的一点是redis lua脚本会首先尽量的执行脚本里的逻辑,redis会阻塞其他的指令操作,因为内置的lua进行数据库操作是不经过网络io这一层,所以他的执行效率是最快的。但如果你初次之外还有一堆的小请求,那么对于整体的性能来说肯定会有所影响的。

所以说,一定不要让你的lua脚本执行时间太长,要分而治之,不要把所有逻辑放到一个lua脚本里面。  

redis是可以针对lua进行超时控制的。默认是不允许lua脚本超过5秒的。  - redis: command=config name=lua-time-limit value=100 ,时间单位是ms毫秒.   


下面是redis lua的基本用法,lua本身语法也干练,所以大家看起来也不觉得难。redis.call(command命令.)  argv, keys是参数,必须是这两个名字.


下面是个比较完整的例子:


我在使用python调用lua中遇到的问题,  提示说是没有os模块,如果我require “os”,也会提示require错误的。

下面的问题是引用了时间引起的, 上面说过redis不可以把获取的时间,insert到任何结构类型里。 

下面是我dtrace的追踪调用的日志, 没有看到他跟redis有多余的网络请求. 

这里是本文最有料的地方, redis lua的各方面优缺点我都有描述。  我这边最看重他的是节省网络io的优点。  下面的代码是伪业务逻辑,其实我线上的业务逻辑更加繁琐,对于redis的请求次数更多。 
下面代码本身不是很复杂,但是需要来回的从redis pull push操作。另外键值中的value基本是在200KB大小,所以他是来回的经过redis网络消耗可想而知。 

首先我会判断他的service_level级别,如果是ddos,那么我会根据队列的大小进行lpop队列,zadd时序队列,我这边针对每条记录进行cjson解析json,如果他的字段符合depth <10 ,我还会进行incr操作。。。。

上面的伪业务逻辑不需要理解,你需要着想的是,如果这里不采用redis lua脚本,这一次次的网络io花费的时间… …  下面是我写的一个复杂的python redis lua场景脚本,代码很easy。

这段redis lua运行后的结果是这样的,

下面是redis server输出的日志。

在stackoverflow看到了一个帖子,是有关什么时候才用到redis lua组合的讨论.  很多论点跟我想的一样…  

http://stackoverflow.com/questions/30869919/redis-lua-when-to-really-use-it

END



对Python及运维开发感兴趣的朋友可以加QQ群 : 478476595 !!!
{ 2000人qq大群内有各厂大牛,常组织线上分享及沙龙,对高性能及分布式场景感兴趣同学欢迎加入该QQ群 }

另外如果大家觉得文章对你有些作用!   帮忙点击广告. 一来能刺激我写博客的欲望,二来好维护云主机的费用.
如果想赏钱,可以用微信扫描下面的二维码. 另外再次标注博客原地址  xiaorui.cc  ……   感谢!
暂无相关产品