Redis Lua脚本

Redis Lua脚本

EVAL script numkeys key [key …] arg [arg …]
  • script: 一段Lua 5.1 脚本程序,这段脚本不必定义为一个Lua函数
  • numkeys:键名参数的个数
  • 要求使用正确的形式来传递键(key)是有原因的,因为不仅仅是 EVAL 这个命令,所有的 Redis 命令,在执行之前都会被分析,籍此来确定命令会对哪些键进行操作。

示例:

eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
1) "key1"
2) "key2"
3) "first"
4) "second"

脚本的原子性

Redis 使用单个 Lua 解释器去运行所有脚本,并且, Redis 也保证脚本会以原子性(atomic)的方式执行:当某个脚本正在运行的时候,不会有其他脚本或 Redis 命令被执行。相当于事务,事务还有可能被lua脚本替代。

特别注意:如果这个lua脚本执行很慢,会严重影响其他脚本运行

Lua脚本中执行Redis命令

主要是这两个函数:

  • redis.call() 直接抛出Redis异常,执行脚本出错
  • redis.pcall() 会捕获异常,并返回错误信息
    示例:
redis> eval "return redis.call('get', KEYS[1])" 1 foo

EVALSHA

redis> EVALSHA sha1 numkeys key [key …] arg [arg …]
  • sha1 是lua脚本的SHA1校验码,相当于脚本的身份id
  • Redis会缓存每次执行的脚本,并永久备份(除非手动清除),下次执行相同脚本,可以用sha1代替,而不是每次都传脚本内容(可能会很长),来节省宽带

EVALSHA 命令的表现如下:

  • 如果服务器还记得给定的 SHA1 校验和所指定的脚本,那么执行这个脚本
  • 如果服务器不记得给定的 SHA1 校验和所指定的脚本,那么它返回一个特殊的错误,提醒用户使用 EVAL 代替 EVALSHA

使用Lua脚本的好处

  • 减少网络开销:使用脚本,一次性执行多个命令,减少网络请求,减少了网络往返时延。
  • 原子操作:Redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。
  • 复用:客户端发送的脚本会永久存储在Redis中,意味着其他客户端可以复用这一脚本而不需要使用代码完成同样的逻辑。

使用Lua脚本注意事项

Lua脚本应该具备以下属性:

对于同样的数据集输入,给定相同的参数,脚本执行的 Redis 写命令总是相同的。脚本执行的操作不能依赖于任何隐藏(非显式)数据,不能依赖于脚本在执行过程中、或脚本在不同执行时期之间可能变更的状态,并且它也不能依赖于任何来自 I/O 设备的外部输入

为了防止不必要的数据泄漏进 Lua 环境, Redis 脚本不允许创建全局变量

为了保证符合上面要求,Redis做了一下工作:

  • Lua没哟访问系统时间或其他内部状态的命令
  • 每当返回无序元素时,会进行字典序排序,以保证数据返回结果一致
  • 对Lua的伪随机函数进行修改,使得每次运行总有相同的seed值,这样产生的随机数序列都是相同的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值