内容简介:都说我们都知道Redis 是单线程的,那么在常规使用情况下,我们使用 Redis ,如下代码执行是什么流程呢?Redis 的执行方式是逐条命令: 发送命令->执行->返回执行结果。
都说 Pipeline
有很大好处,但是能量是守恒的,好坏也是相对的。 所以我们主要来测试看看 Pipeline
的利弊。 带着几个问题我们来进行基本的测试。 1. Pipeline
对命令数量是否有限制? 2. Pipeline
打包执行多少命令合适? 3. Pipeline
批量执行的时候,是否对 Redis 进行了锁定,导致其他应用无法再进行读写?
Redis 常规使用方式
我们都知道Redis 是单线程的,那么在常规使用情况下,我们使用 Redis ,如下代码执行是什么流程呢?
$key1 = "abc1"; $key2 = "abc2"; $key3 = "abc3"; $redisObj->set($key1, 1); $redisObj->set($key2, 2); $redisObj->set($key3, 3);
Redis 的执行方式是逐条命令: 发送命令->执行->返回执行结果。
如图:
什么是 pipeline
呢?
知道了常规的使用方式,那么我们再来看看 pipeline
模式, pipeline
模式则是将执行的命令写入到缓冲中,最后由exec命令一次性发送给redis执行返回。
我们以灌一个list来进行测试,以20000条list数据为例,来对比一下常规模式的的写入和 pipeline
模式的写入。
Redis pipeline
的执行方式: 打包开始->缓存->打包结束->发送->执行->返回执行结果。
如图:

逐条写模式(常规模式)
<?php $redisObj = new \Redis(); $redisObj->connect('127.0.0.1', 6379); $time_start = microtime(true); $mcKey = "lpush:normal"; for ($i = 0; $i < 20000; $i++) { $redisObj->lPush($mcKey, $i); } $time_end = microtime(true); $time = $time_end - $time_start; echo "逐条写模式耗时: {$time}\n";
Pipeline(管道) 模式
<?php $redisObj = new \Redis(); $redisObj->connect('127.0.0.1', 6379); $time_start = microtime(true); $redisObj->multi(Redis::PIPELINE); unset($time, $time_end, $mcKey); $mcKey = "lpush:pipeline"; for ($i = 0; $i < 20000; $i++) { $redisObj->lPush($mcKey, $i); } $redisObj->exec(); $time_end = microtime(true); $time = $time_end - $time_start; echo "pipeline 模式运行耗时:{$time}\n";
我们看看,两者的执行结果:
#php t.php 逐条写模式耗时: 1.0443658828735 pipeline 模式运行耗时:0.045078039169312
根据结果可以看出, pipeline
模式的耗时比 逐条写模式
提升了2倍多。
Pipeline(管道) 的优点:
-
pipeline
通过打包命令,一次性执行,可以节省连接->发送命令->返回结果
所产生的往返时间, - 减少的I/O的调用次数。
Pipeline(管道) 的缺点:
-
pipeline
每批打包的命令不能过多,因为pipeline
方式打包命令再发送,那么redis
必须在处理完所有命令前先缓存起所有命令的处理结果。这样就有一个内存的消耗。 -
pipeline
是责任链模式,这个模式的缺点是,每次它对于一个输入都必须从链头开始遍历(参考Http Server处理请求就能明白),这确实存在一定的性能损耗。 -
pipeline
不保证原子性,如果要求原子性的,不推荐使用pipeline
问题解答
Q、 Pipeline
对命令数量是否有限制? A、没有限制,但是打包的命令不能过多,对内存的消耗就越大。
Q、 Pipeline
打包执行多少命令合适? A、查询 Redis 官方文档,根据官方的解释,推荐是以 10k
每批 (*注意:这个是一个参考值,请根据自身实际业务情况调整)。
IMPORTANT NOTE: While the client sends commands using pipelining, the server will be forced to queue the replies, using memory. So if you need to send a lot of commands with pipelining, it is better to send them as batches having a reasonable number, for instance 10k commands, read the replies, and then send another 10k commands again, and so forth. The speed will be nearly the same, but the additional memory used will be at max the amount needed to queue the replies for this 10k commands. https://redis.io/topics/pipelining
Q、 Pipeline
批量执行的时候,是否对Redis进行了锁定,导致其他应用无法再进行读写? A、Redis 采用多路I/O复用模型,非阻塞IO,所以 Pipeline
批量写入的时候,一定范围内不影响其他的读操作。
以上为个人总结,如有不对,欢迎指正。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 速度不够,管道来凑——Redis管道技术
- Golang pipline泛型管道和类型管道的性能差距
- Linux 管道那些事儿
- mongodb 聚合管道
- Redis管道
- Clojure 集合管道函数练习
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
未来世界的幸存者
阮一峰 / 人民邮电出版社 / 2018-6-1 / 39.00 元
本书为阮一峰博客文集,主要收录的是作者对技术变革的影响的一些思考,希望能够藉此书让读者意识到世界正在剧烈变化,洪水就在不远处,从而早早准备出路。本书适合所有乐于思考的读者。一起来看看 《未来世界的幸存者》 这本书的介绍吧!