Redis 脚本
Redis 脚本使用 Lua 解释器来执行脚本。 Redis 2.6 版本通过内嵌支持 Lua 环境。执行脚本的常用命令为 EVAL。
语法
Eval 命令的基本语法如下:
redis 127.0.0.1:6379> EVAL script numkeys key [key …] arg [arg …]
示例
以下示例演示了 redis 脚本工作过程:
127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 zk kafka redis mysql
1) "zk"
2) "kafka"
3) "redis"
4) "mysql"
解释说明:
- eval:执行lua脚本的命令
- “return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}”:lua脚本内容,KEYS[x]是键盘参数,ARGV[x]是附加参数
- 2:指定KEYS键的数量
- zk kafak:参数值
- first second:附加参数值
注意:指定KEY键数量之后的都是附加参数值,ARGV[1]指第一个附加参数值,ARGV[2]指第二个附加参数值。
下面再举一个例子,注意和上面的例子对比区别:
127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 3 zk kafka redis mysql
1) "zk"
2) "kafka"
3) "mysql"
解释说明:上面指定KEYS占位符3个,则zk kafka redis
分别对应着KEYS[1] KEYS[2] KEYS[3]
msyql 就是第一个附加参数ARGV[1]的值,而ARGV[2] 就应该为空。所以只能打印出zk kafka mysql。
Redis 脚本命令
下表列出了 redis 脚本常用命令:
命令 | 说明 |
---|---|
EVAL script numkeys key [key …] arg [arg …] | 执行 Lua 脚本。 |
EVALSHA sha1 numkeys key [key …] arg [arg …] | 执行 Lua 脚本。 |
SCRIPT EXISTS script [script …] | 查看指定的脚本是否已经被保存在缓存当中。 |
SCRIPT FLUSH | 从脚本缓存中移除所有脚本。 |
SCRIPT KILL | 杀死当前正在运行的 Lua 脚本。 |
SCRIPT LOAD script | 将脚本 script 添加到脚本缓存中,但并不立即执行这个脚本。 |
redis pipeline
了解redis中的流水线(pipeline)我们先来看以上示例:
首先来看 redis 执行一次操作所需要的时间:
1 次时间 = 1 次网络时间 + 1次命令时间
执行 n 次就需要:
n 次时间 = n 次网络时间 + n 次命令时间
所以可以看到,如果执行 n 次的话(比如 n 次 set 操作),时间开销是非常大的。
而由于命令时间非常短,影响时间开销的主要是网络时间,所以我们可以把一组命令打包,然后一次发送过去。这样的话,时间开销就变为:
1 次 pipeline(n条命令) = 1 次网络时间 + n 次命令时间
从上面看出,其实redis中的pipeline就是多个命令打包后一次性发送。
pipeline 的好处
- 省略由于单线程导致的命令排队时间,一次命令的消耗时间=一次网络时间 + 命令执行时间
比起命令执行时间,网络时间很可能成为系统的瓶颈 - pipeline的作用是将一批命令进行打包,然后发送给服务器,服务器执行完按顺序打包返回。
- 通过pipeline,一次pipeline(n条命令)=一次网络时间 + n次命令时间
命令 | N个命令操作 | 一次pipeline操作 |
---|---|---|
时间 | n次网络+n次命令 | 1次网络+n次命令 |
数据量 | n条命令 | 1条命令 |
pipeline VS M 操作(mget、mset)
之前我们讲过 M 操作,也是类似 pipeline,将多个命令一次执行,一次发送出去,节省网络时间。但是它们之间有如下区别:
- M操作在Redis队列中是一个原子操作,pipeline不是原子操作
- pipeline与M操作都会将数据顺序的传送顺序地返回(redis 单线程)
- M 操作一个命令是对应多个键值对,而Pipeline是多条命令
pipeline注意事项
- 每次pipeline携带命令数量不推荐过大,否则会影响网络性能
- pipeline每次只能作用在一个Redis节点上
更多关于redis的知识分享,请前往博客主页。编写过程中,难免出现差错,敬请指出