共计 2118 个字符,预计需要花费 6 分钟才能阅读完成。
Redis 是一种十分风行的内存数据库,罕用于数据缓存与高频数据存储。大多数开发人员可能据说过 redis 能够运行 Lua 脚本,然而可能不晓得 redis 在什么状况下须要应用到 Lua 脚本。
一、浏览本文前置条件
- 能够遵循这个链接中的办法在操作系统上装置 Redis
- 如果你对 redis 命令不相熟,查看《Redis 命令援用》
二、为什么须要 Lua 脚本
简而言之:Lua 脚本带来性能的晋升。
- 很多利用的服务工作蕴含多步 redis 操作以及应用多个 redis 命令,这时你能够应用 Redis 联合 Lua 脚本,会为你的利用带来更好的性能。
- 另外蕴含在一个 Lua 脚本外面的 redis 命令具备原子性,当你面对高并发场景下的 redis 数据库操作时,能够无效防止多线程操作产生脏数据。
三、学点 Lua 语法
说了那么多,Lua 不会怎么办?不要慌!Lua 其实很简略,如果你已经学习过任何一门编程语言,学习 Lua 都非常简单。上面给大家举几个例子学习一下:
3.1. 一个简略的例子
Lua 脚本通过各种语言的 redis 客户端都能够调用,咱们就简略一点应用 redis-cli
看上面的 redis 命令行:
eval "redis.call('set', KEYS[1], ARGV[1])" 1 key:name value
EVAL命令行前面跟着的是 Lua 脚本:"redis.call('set', KEYS[1], ARGV[1])"
, 放到编程语言外面就是一段字符串,跟在 Lua 脚本字符串前面的三个参数顺次是:
- redis Lua 脚本所须要的 KEYS 的数量,只有一个 KEYS[1],所以紧跟脚本之后的参数值是 1
- Lua 脚本须要的参数 KEYS[1]的参数值,在咱们的例子中值为 key:name
- Lua 脚本须要的参数 ARGV[1]的参数值,在咱们的例子中值为 value
Lua 脚本中包含两组参数:KEYS[]和ARGV[],两个数组下标从 1 开始。一个值得去恪守的最佳实际是:把 redis 操作所需的 key 通过 KEYS 进行参数传递,其余的 Lua 脚本所需的参数通过 ARGV 进行传递。
下面的脚本执行实现之后,咱们应用上面的 Lua 脚本来进行验证,如果该脚本的返回值是”value”,与咱们之前设置的 key:name 的值雷同,则示意咱们的 Lua 脚本被正确执行了。
eval "return redis.call('get', KEYS[1])" 1 key:name
3.2. 认真看下 Lua 脚本里的内容
咱们的第一个 Lua 脚本只蕴含一条语句,调用redis.call
redis.call('set', KEYS[1], ARGV[1])
所以在 Lua 脚本外面能够通过 redis.call
执行 redis 命令,call 办法的第一个参数就是 redis 命令的名称,因为咱们调用的是 redis 的 set 命令,所以须要传递 key 和 value 两个参数。
咱们第二个脚本不只是执行了一个脚本,因为执行 get 命令还返回了执行后果。留神脚本中有一个 return 关键字。
eval "return redis.call('get', KEYS[1])" 1 key:name
当然如果只是下面的这么简略的 Lua 脚本,还不如间接应用命令行更不便。咱们理论应用到的 Lua 脚本会比下面的简单,下面的 Lua 脚本只是一个 Hello World。
3.3. 简单点的例子
我曾应用 Lua 脚本从一个 hash map 外面依照肯定的程序获取若干 key 对应的值。对应的程序在一个 zset 排序汇合中进行保留,数据设置及排序能够通过上面的实现。
# 设置 hkeys 为键 Hash 值
hmset hkeys key:1 value:1 key:2 value:2 key:3 value:3 key:4 value:4 key:5 value:5 key:6 value:6
# 建一个 order 为键的汇合,并给出程序
zadd order 1 key:3 2 key:1 3 key:2
如果不晓得 hmset 和 zadd 命令的作用,能够参考hmset 和 zadd
执行上面的 Lua 脚本
eval "local order = redis.call('zrange', KEYS[1], 0, -1); return redis.call('hmget',KEYS[2],unpack(order));" 2 order hkeys
你将看到如下的输入后果
“value:3”“value:1”“value:2”
- 通过 zrange 取出 order 汇合外面的数据,即:[key:3 , key:1 , key:2]
- 而后通过 unpack 函数将[key:3 , key:1 ,key:2] 转成 key:3 key:1 key:2
- 最初执行 hmget hkeys key:3 key:1 key:2,所以失去下面的输入后果
四、Lua 脚本预加载
Redis 能够对 Lua 脚本进行预加载,能够通过 script load 命令把 Lua 脚本预加载到 redis 外面。
script load "return redis.call('get', KEYS[1])"
预加载实现之后,你会看到上面的一段输入
“4e6d8fc8bb01276962cce5371fa795a7763657ae”
这是一个具备唯一性的 hash 字符串,这个 hash 就代表着咱们刚刚预加载的 Lua 脚本,咱们能够通过 EVALSHA 命令执行该脚本