详解python调用redis lua内嵌脚本的高级用法

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

我对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是参数,必须是这两个名字.

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

Leave a Reply

Your email address will not be published. Required fields are marked *