在 redis 里执行 lua 脚本的跳坑指南

个人博客版传送门

最近基于 Kong 做一些东西,其中一个插件的算法设计需要去 redis 做多次读取判断,于是准备把这部分实现逻辑放到 redis 侧,省去多次访问 redis 的网络开销。

redis 的一般用法是对其基础数据结构的读写,因为数据都放在内存,读写非常迅速,进一步还支持执行 lua 脚本,redis 提供了一个 lua 的执行环境(注意是 5.1),并提供了一些在 lua 脚本中调用 redis 命令的方法(redis.call、redis.pcall、redis.log、…),可以通过 script load 或 eval 命令来载入 lua 脚本,载入后得到一个 sha1 值,客户端就可以通过 evalsha <sha1> 来调用这个脚本

evalsha <sha1> <key_num> [<key1> <key2> ...] <arg1> <arg2> ...

从网友的共识来看,最权威的介绍 lua 的书籍是 《Programming in Lua 3rd》,写的过程中对照着看就行。

在脚本放到 redis 后发现有 3 个坑。

第一个坑就是 redis 所支持的 lua 版本过低的问题,还记得一开始我提到,redis 内置的 lua 执行环境版本是5.1,而 5.1 和 5.2+ 的其中一个区别是后者增加了对 goto 的语法支持(虽然 goto 是万恶之源,当年写汇编作业的时候也是 goto 到上头)。而我写的时候先用 java 实现了一遍(顺手用了 continue),再翻译为 lua 代码,不幸的是调试的时候用的 lua5.3,因为猛然发现没有 continue,所以按照网上方案用了 goto 来替代(repeat 的方案多套了一层循环,感觉不够直观),这下就有点尴尬。

翻了 so、github,在 2011 年的时候就有网友提了 PR,请社区将 redis 的 lua 版本升级到 5.2,但维护者认为 5.1 就够用了(一个个的,要什么自行车),于是在最新的 redis 6.2.1 里还是 lua5.1。最后调整了分支逻辑,上岸。

第二个坑是 lua 的变量作用范围,放到 redis 以后发现 redis 的 lua 环境禁止操作全局变量,只能改之,传个 table 引用得了。看起来在 lua 里,全局变量是个危险的灰色地带。

第三个坑是 lua 里的数组(换了个马甲其实还是 table)起始下标为 1,改了几个循环体,忍不住停下来想——我是谁?我在哪?

作为一个弱类型的脚本语言,写的时候还是很爽的,特别是对比 java 里返回多值的那种扭捏羞涩。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值