Redis 客户端执行单条命令需要执行的四个步骤
- 四个步骤
- 1.发送命令
- 2.命令排队
- 3.命令执行
- 4.返回结果
- 第一步+第四步成为 Round Trip Time(RTT 往返时间)
单个命令操作多条数据
- eg:mget mset
- 特点
- 是服务端支持的
- 优势
- 可以有效节约RTT
- 是原子性的
- 劣势
- 只有个别命令支持操作多个数据,大部分命令不支持批量操作。eg :要执行n次 hgetall 就没有可替代的命令
pipeline
- 特点
- 需要服务端和客户端同时支持
- pipeline中发送的每个command都会被server立即执行,如果执行失败,将会在此后的相应中得到信息
- 简单来说就是管道中的命令是没有关系的,它们只是像管道一样流水发给server,而不是串行执行
- 在IO操作层面,对于client而言,就是一次批量的连续的“write”请求,然后是批量的连续的“read”操作。其实对于底层Socket-IO而言,对于client而言,只不过是多次write,然后一次read的操作;对于server端,input通道上read到数据之后,就会立即被实施,也会和非pipeline一样在output通道上输出执行的结果,只不过此时数据会被阻塞在网络缓冲区上,直到client端开始read或者关闭链接。
- 优势
- 有效节约RTT,大批量处理的时候节省时间
- 劣势
- 非原子性
- 注意事项
- 使用管道发送命令的时候, 管道命令数目不要过大,因为服务端会被迫开启一个队列答复,占用很多内存
事务
- 特点
- 原子操作:保证一个事务内的语句按顺序执行,执行过程中不会被其他命令插入
- 把事务中的命令先放入队列,当client 提交了exec命令之后,redis 会把队列中的所有命令按照顺序执行一遍。
- 异常情况
- 入队命令语法错误,此时还没有执行exec 则所有命令都不会执行
- 当exec执行完毕后,执行其他命令时发生错误,则redis 会继续执行后续命令。 即 :无论在错误命令之前还是之后的命令,都会顺利执行
- 如果命令之间有依赖关系,比如后续的命令需要处理先前命令的返回值,只能选择脚本。
lua脚本
- 特点
- 可以减少网络开销
- 本来5次网络请求的操作,可以用一个请求完成,原先5次请求的逻辑放在redis服务器上完成。使用脚本,减少了网络往返时延
- 可以减少网络开销
-
- 原子操作
- Redis 会将脚本作为一个整体执行,中间不会有其他命令插入
- 原子操作
-
- 复用
- 客户端发送的脚本会永久存储在Redis中,意味着其他客户端可以复用这一脚本而不需要使用代码完成同样的逻辑。
- 复用
- 注意事项
- 不要在script中执行过长开销的程序,否则会验证影响其他请求的执行
- Redis 中的脚本本身就是一种事务, 所以任何在事务里可以完成的事, 在脚本里面也能完成。 并且一般来说, 使用脚本要来得更简单,并且速度更快。