Redis 脚本使用 Lua 解释器来执行脚本。 Redis 2.6 版本通过内嵌支持 Lua 环境。执行脚本的常用命令为 EVAL。
Lua 是一个小巧的脚本语言。它是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个由 Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo 三人所组成的研究小组于 1993 年开发的。其设计目的是为了通过灵活嵌入应用程序中从而为应用程序提供灵活的扩展和定制功能。
Lua 由标准 C 编写而成,几乎在所有操作系统和平台上都可以编译、运行。Lua 并没有提供强大的库,这是由它的定位决定的。所以 Lua 不适合作为开发独立应用程序的语言。Lua 有一个同时进行的 JIT 项目,提供在特定平台上的即时编译功能。
下面将通过 EVAL 命令演示 Redis 脚本工作过程,EVAL 命令语法如下:
EVAL script numkeys key [key ...] arg [arg ...]
参数说明:
script: 表示一段 Lua 5.1 脚本程序,脚本不必(也不应该)定义为一个 Lua 函数
numkeys: 用于指定键名参数的个数
key [key ...]: 从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,下标从 1 开始访问 KEYS[1]、KEYS[2] 以此类推
arg [arg ...]: 附加参数,在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似 ARGV[1] 、ARGV[2] 以此类推
例1:演示 EVAL 命令中脚本怎样获取 KEY 和参数,如下:
# 访问 EVAL 指定的键和参数 127.0.0.1:6379> EVAL "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second 1) "key1" 2) "key2" 3) "first" 4) "second"
例2:使用 EVAL 执行 LUA 脚本,通过 Lua 返回指定键的值,如下:
# 设置一个键 127.0.0.1:6379> set mykey hello OK 127.0.0.1:6379> get mykey "hello" # 通过 Lua 脚本从 Redis 中获取 mykey 键的值 127.0.0.1:6379> eval "return redis.call('get',KEYS[1])" 1 mykey "hello"
例3:使用 EVAL 执行一个 Lua 脚本,用来比较给定的键的值是否为给定的值,如下:
# 设置 a 的值为 100 127.0.0.1:6379> set a 100 OK # 通过 Lua 脚本判断 a 的值是否为 100 127.0.0.1:6379> eval "return redis.call('get', KEYS[1]) == ARGV[1]" 1 a 100 (integer) 1 # 通过 Lua 脚本判断 a 的值是否为 200 127.0.0.1:6379> eval "return redis.call('get', KEYS[1]) == ARGV[1]" 1 a 200 (nil)
下表列出了 Redis 脚本的常用命令。
执行 Lua 脚本。语法如下:
EVAL script numkeys key [key ...] arg [arg ...]
实例:
# 设置一个键 127.0.0.1:6379> set mykey hello OK # 通过 Lua 脚本从 Redis 中获取 mykey 键的值 127.0.0.1:6379> eval "return redis.call('get',KEYS[1])" 1 mykey "hello"
执行 Lua 脚本。语法如下:
EVALSHA sha1 numkeys key [key ...] arg [arg ...]
实例:
127.0.0.1:6379> SCRIPT LOAD "return 'hello hxstrive.com'" "49b7402c9c6e770d9734aeec03b71c2495cb0307" 127.0.0.1:6379> EVALSHA "49b7402c9c6e770d9734aeec03b71c2495cb0307" 0 "hello hxstrive.com"
如果我们将一段 Lua 脚本通过 SCRIPT LOAD 命令加载到缓存中,然后来执行。如下:
127.0.0.1:6379> script load "return redis.call('get', KEYS[1])" "4e6d8fc8bb01276962cce5371fa795a7763657ae" 127.0.0.1:6379> set mykey "hxstrive.com" OK 127.0.0.1:6379> evalsha "4e6d8fc8bb01276962cce5371fa795a7763657ae" 1 mykey "hxstrive.com" 127.0.0.1:6379> set mykey2 12345 OK 127.0.0.1:6379> evalsha "4e6d8fc8bb01276962cce5371fa795a7763657ae" 1 mykey2 "12345"
查看指定的脚本是否已经被保存在缓存当中。语法如下:
SCRIPT EXISTS script [script ...]
实例:
# 加载 Lua 脚本到缓存 127.0.0.1:6379> script load "return redis.call('get', KEYS[1])" "4e6d8fc8bb01276962cce5371fa795a7763657ae" # 判断指定 SHA 对应的 Lua 脚本是否在缓存中 127.0.0.1:6379> script exists "4e6d8fc8bb01276962cce5371fa795a7763657ae" 1) (integer) 1 # 手动修改 SHA 值,返回不在缓存中 0 127.0.0.1:6379> script exists "4e6d8fc8bb01276962cce5371fa795a7763657aeEE" 1) (integer) 0
从脚本缓存中移除所有脚本。语法如下:
SCRIPT FLUSH
实例:
# 加载 Lua 脚本到缓存 127.0.0.1:6379> script load "return redis.call('get', KEYS[1])" "4e6d8fc8bb01276962cce5371fa795a7763657ae" # 判断指定 SHA 对应的 Lua 脚本是否在缓存中 127.0.0.1:6379> script exists "4e6d8fc8bb01276962cce5371fa795a7763657ae" 1) (integer) 1 127.0.0.1:6379> script flush OK 127.0.0.1:6379> script exists "4e6d8fc8bb01276962cce5371fa795a7763657ae" 1) (integer) 0
杀死当前正在运行的 Lua 脚本。语法如下:
SCRIPT KILL
实例:
127.0.0.1:6379> script kill (error) NOTBUSY No scripts in execution right now
将脚本 script 添加到脚本缓存中,但并不立即执行这个脚本。语法如下:
SCRIPT LOAD script
实例:
# 加载 Lua 脚本到缓存 127.0.0.1:6379> script load "return redis.call('get', KEYS[1])" "4e6d8fc8bb01276962cce5371fa795a7763657ae"
更多命令请访问 https://redis.io/commands/ 进行参考。