Redis Pipeline&Script


文章目录

  • 前言
  • 一、Pipeline是什么?
  • 二、Pipeline具体实现
    • 特点
    • 缺点
  • 三、Script
  • Script具体实现
  • 对比Pipeline
  • 三、总结


前言

玩过远程过程调用的小伙伴都知道,一次请求多条数据要比多次请求1条数据效率高(当然,这里的多条数据通常是完全不同的,比如完全不同的ID)。其中的原因如下。

网络传输层是按照segment为单位的,单个segment可以传输大约1400个字节,如果只包含一个long型的ID,传输效率为8/1400, 1%的利用率都不到。再说服务侧,接收数据需要在内核和应用侧做上下文切换,一次切换的时间成本相对固定,如果仅接收这么点数据,是不是浪费?还有,有了数据,还得调度应用线程处理吧,线程好不容易排队等到分配CPU时间片,以Linux系统为例最长50ms, but 你这个请求5ms完事了,没办法线程还得继续进入等待状态,又是一层浪费;这还不算你应用产生的单条数据也很小,依然达不到单个segment的长度,然后response阶段的一波效率差。最终表现就是虽然整体响应时间不长,但是拆分到请求发送,请求处理,响应发送各个阶段时间效率都比较差。

此外,站在单次请求的角度网络传输耗时通常远大于处理耗时,因此减少RTT也可以减少时间消耗。如果可行RTT减少到1次最好,毕竟完全消除RTT目前还做不到。

就Redis而言,虽然每个数据结构都比较巧妙,可以比较高效处理单个指令,但是对一批指令的处理还有优化的空间,这就是pipeline。


一、Pipeline是什么?

Redis的Pipeline和常见的Linux Shell中的Pipeline是两码事。Redis的Pipeline更多是一个batch上的概念,而Linux pipe组成line则是以pipe的方式将多个命令串起来达到顺序的连续执行的目的。虽然两者在执行上都是顺序的,但是Linux Shell下的pipeline通常pipe前一个命令的输出会影响后一个命令的输入,Redis的Pipeline则仅仅保证命令的串行,并不关心命令之间的影响。

二、Pipeline具体实现

在pipeline模式下,client端所有的命令都被cache在本地buffer,直到通过sync命令将数据批量发送到server端。此外pipeline模式也是提升吞吐量的一种方式。

特点

  1. 需要client和server共同配合;
  2. 命令执行中单条命令是原子的, 但是整个pipeline不是原子的;如果需要整个pipeline是原子的, 需要基于transaction或者Script;
  3. 适用于批量处理, 但是对可靠性要求不高的场景;

缺点

  1. 由于批量返回时严格按照顺序完成, 因此需要有buffer进行排队, 如果每条命令返回数据量比较大, 会导致buffer爆掉。因此,buffer占用需要提前有预期。
  2. 对于批量操作命令不支持;

三、Script

前面的Pipeline是批量的,但是非原子。如果你希望所有的命令以原子形式执行,则需要借助于transaction或者Script。因为在Pipeline执行的最小单位是命令,只能保证命令一定是顺序执行,而Script则是把整个Script当做1条命令来执行。因此可以做到原子性。

Script具体实现

  1. Redis内嵌Lua脚本解释器,在Lua脚本中可以执行多个key的读写操作,也可以扩展一些额外功能,比如基于Lua脚本实现RateLimiter;
  2. 在整个Lua脚本执行过程中,其他命令的处理会被阻塞,从而保证原子性;

对比Pipeline

item pipeline Script
批量执行命令 Y Y
原子性 N Y
灵活性 内部命令灵活填充 只能调整参数, 且其中的key必须是明确的
cluster集群下 不支持,需要自己实现 支持, 需要确定复制模式通常为Effects replication, 7.0之后不再支持Verbatim replication

三、总结

以上就是本篇的全部内容,本文从pipeline的背景开始,介绍了pipeline的具体实现、与Shell pipeline的区别,以及与Script对比,希望能帮助你更好地理解和使用Redis。

你可能感兴趣的:(Redis,redis,数据库,缓存)