目录
- 前言
- Redis的Lua常用命令
- EVAL命令
- 在脚本中调用redis命令
- SCRIPT LOAD命令
- EVALSHA命令
- SCRIPT EXISTS 命令
- SCRIPT KILL 命令
- SCRIPT FLUSH 命令
前言
在操作redis的代码中,我们经常可以看到lua脚本的代码,那么在redis中使用lua脚本有什么好处呢?主要有以下三点
Redis使用lua 脚本的优点
1、减少网络开销。可以将多个请求通过脚本的形式一次发送,减少网络时延。2、原子操作。Redis会将整个脚本作为一个整体执行,中间不会被其他请求插入。因此在脚本运行过程中无需担心会出现竞态条件,无需使用事务。3、复用。客户端发送的脚本会永久存在redis中,这样其他客户端可以复用这一脚本,而不需要使用代码完成相同的逻辑。清空脚本缓存只有唯一一个方式,就是执行script flush命令。
看完是不是觉得有必要了解下redis的lua脚本,关于lua的基础语法,可以看我另一篇文章:lua基础。下面主要介绍redis中的lua命令
Redis的Lua常用命令
Redis的Lua命令不多,就下面这几个:
- EVAL
- EVALSHA
- SCRIPT LOAD - SCRIPT EXISTS
- SCRIPT FLUSH
- SCRIPT KILL
EVAL命令
命令格式:
EVAL script numkeys key [key …] arg [arg …]
- script参数是一段 Lua脚本程序
- numkeys指定后续参数有几个key,即:key [key …]中key的个数。如没有key,则为0
- key [key …] 从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key)。在Lua脚本中通过KEYS[1], KEYS[2]获取。
- arg [arg …] 附加参数。在Lua脚本中通过ARGV[1],ARGV[2]获取。
实例:
127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 val1 val2
1) "key1"
2) "key2"
3) "val1"
4) "val2"
在脚本中调用redis命令
在脚本中可以使用redis.call函数调用Redis命令
redis.call函数的返回值就是Redis命令的执行结果
call()函数第一个参数表示redis中的命令,就是发给Redis的命令,比如SET、GET、INCR等,除了第一个参数,剩下的就是命令的输入的入参
例:
redis还提供了redis.pcall函数,功能与redis.call相同,唯一的区别是当命令执行出错时,redis.pcall会记录错误并继续执行,而redis.call会直接返回错误,不会继续执行。在脚本中可以使用return语句将值返回给客户端,如果没有执行return语句则默认返回nil
redis返回值类型和Lua数据类型转换规则
SCRIPT LOAD命令
语法:
SCRIPT LOAD script
SCRIPT LOAD命令作用是将将脚本 script 添加到Redis服务器的脚本缓存中,并不立即执行这个脚本,而是对输入的脚本进行求值。并返回给定脚本的 SHA1 摘要。如果给定的脚本已经在缓存里面了,那么不执行任何操作。
在脚本被加入到缓存之后,在客户端就可以通过EVALSHA命令,使用脚本的 SHA1 摘要来调用这个脚本。脚本可以在缓存中保留无限长的时间,直到执行SCRIPT FLUSH为止。
例:
EVALSHA命令
语法:
EVALSHA sha1 numkeys key [key ...] arg [arg ...]
在脚本比较长的情况下,如果每次调用脚本都需要将整个脚本传给Redis会占用较多的带宽。为了解决这个问题,Redis提供了EVALSHA命令,允许开发者通过脚本内容的SHA1摘要来执行脚本,该命令的用法和EVAL一样,只不过是将脚本内容替换成脚本内容的SHA1摘要。
Redis在执行EVAL命令时会计算脚本的SHA1摘要并记录在脚本缓存中,执行EVALSHA命令时Redis会根据提供的摘要从脚本缓存中查找对应的脚本内容,如果找到了则执行脚本,否则会返回错误:“NOSCRIPT No matching script. Please use EVAL.”
例:
SCRIPT EXISTS 命令
语法:
SCRIPT EXISTS sha1 [sha1 …]
作用:给定一个或多个脚本的 SHA1 校验和,返回一个包含 0 和 1 的列表(0表示不存在,1表示存在),表示校验和所指定的脚本是否已经被保存在缓存当中
例:
SCRIPT KILL 命令
语法:
SCRIPT KILL
作用: 强制终止当前脚本的执行(是正在运行的脚本)。 但是,如果当前执行的脚步对redis的数据进行了写操作,则SCRIPT KILL命令不会终止脚本的运行,以防止脚本只执行了一部分。
SCRIPT FLUSH 命令
语法:SCRIPT FLUSH
作用:清空Redis服务端的Lua脚本缓存
例: