Redis lua基本使用最佳实践

最佳实践有点大了,其实就是几个使用建议。

背景知识

redis 的单条命令可保证原子性,但多条命令无法保证。
甚至分布式场景下, mget 这种会被分拆的命令也无法保证原子性。
而如何保证多条命令的原子性呢?此时可以使用 lua。

典型使用场景有rate limit等。

使用建议

先说结论,后续详细解释:

  • 正确的使用方法
    1. lua 脚本维护在代码中
    2. 找个测试服务器,SCRIPT LOAD此lua脚本,拿到sha值
    3. 执行脚本时,先EVALSHA,如果报找不到脚本错误,再执行EVAL+lua脚本内容(可以提前预热)
    4. 随着所有节点都执行过EVAL,之后只需要执行EVALSHA就可以
  • lua 脚本尽量简单,负责可能会影响其它请求
  • 参数一定要通过KEYSARGV传入,而且一定要区分二者区别
  • 不要在代码里面动态修改lua脚本,那样每次请求都是一个新的lua脚本,消耗大量内存

基本命令

redis 下 lua 脚本相关的命令有:

  • EVAL:执行lua脚本,需要原始lua脚本作为输入
  • EVALSHA:使用sha值执行lua脚本,sha值需要通过SCRIPT LOAD获得
  • SCRIPT DEBUG:调试
  • SCRIPT EXISTS:通过sha值检查脚本是否存在
  • SCRIPT FLUSH:情况lua脚本,可同步、异步执行
  • SCRIPT KILL:杀死lua脚本
  • SCRIPT LOAD:加载lua脚本,这是目前获取sha值得唯一手段

需要注意的几点:
redis命令相关
无法直接拿到sha值
sha值生成算法相同

redis 的单线程机制

lua脚本的正确使用方式

提前拿到sha值

为什么不提前load

KEYS 和 ARGV

lua 脚本不要过大

不要动态生成lua脚本

其它

分布式场景

codis:使用第一个key路由,因此可用hash tag。旧版本迁移bug。而且会导致不均衡。
redis-cluster:会进行校验,必须在一个hash slot内。否则会报错。

exec/multi

只适用于单机

参考文档