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脚本字符串前面的三个参数顺次是:

  1. redis Lua脚本所须要的KEYS的数量 ,只有一个KEYS[1],所以紧跟脚本之后的参数值是1
  2. Lua 脚本须要的参数KEYS[1]的参数值,在咱们的例子中值为key:name
  3. 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命令的作用,能够参考hmsetzadd

执行上面的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命令执行该脚本