首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >redis的MULTI与PIPELINE

redis的MULTI与PIPELINE

作者头像
跑马溜溜的球
发布于 2020-12-07 07:30:50
发布于 2020-12-07 07:30:50
1.3K00
代码可运行
举报
文章被收录于专栏:日积月累1024日积月累1024
运行总次数:0
代码可运行

1. 问题

redis的multi相信很多同学用过,先看下面的代码。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?php
$redis = new Redis();
$host = "10.136.30.144";
$port = "7777";

$redis->connect($host, $port);
$multi = $redis->multi();
for ($i=0; $i<5; $i++){
    $multi->incr("x");
}

$res = $redis->exec();
var_dump($res);

代码对x执行了5次incr操作,输出结果也很容易理解

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
array(5) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
  [3]=>
  int(4)
  [4]=>
  int(5)
}

问题来了 1. 这5次incr命令是一起发给redis的么? 2. 服务端是一次返回所有结果还是分5次返回? 3. 整个过程客户端除了发送incr命令外是否还发送了其它命令?

如果你对上面几个问题的答案不是很确定,那么不妨继续往下读。

2. 回答

要解答上面的问题,最方便的办法是~抓个包。 在客户端机器上执行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
tcpdump port 7777 -n -s 1024 -i eth0 -w multi.dump

结果如下:

整个过程一共有22个tcp包,耗时0.013s其中: - 4包向服务端发MULTI指令 - 6包服务端回复OK - 8包向服务端发送INCR - 9包服务端返回QUEUED - 10-17包内容与8-9一样,是循环执行的过程 - 18包向服务端发送EXEC - 19包返回执行结果

现在我们可以回答上面的问题了 1. 5次incr命令是单独发给服务端的,每发送服务端都要回复QUEUED 2. 服务端将执行结果打包一次返回给了客户端 3. 除了INCR,客户端还额外发送了MULTI和EXEC指令。

3. 对比

如果使用普通方式,串行执行5个INCR会怎么样呢? 我们将代码调整为

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?php
$redis = new Redis();
$host = "10.136.30.144";
$port = "7777";

$redis->connect($host, $port);

for ($i=0; $i<5; $i++){
    $res = $redis->incr("x");
    var_dump($res);
}

重新抓包,结果如下:

18个数据包,0.0076s完成,比MULTI方式略少。

4. 如何更高效

有没有方法将所有想执行的命令一次打包发给redis服务端,使得整个执行过程更高效呢(节省网络交互时间)?答案是肯定的。 multi有个可选参数,默认值是使用Redis::MULTI。将参数值设为Redis::PIPELINE即可解决问题。 将上1中的代码改动一行。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$multi = $redis->multi(Redis::PIPELINE);

重新抓包,结果如下:

整个过程一共有10个tcp包,其中: - 4包向服务端打包发送所有INCR指令 - 6包返回执行结果

再对比下执行时间,由于PIPELINE方式网络交互少,从抓包图上看,整个过程只要0.0036s,只有2中的MULTI方式(0.013s)的28%!,2中普通串行方式(0.076s)的47%。

5. 更进一步

  • PIPE方式,对打包的命令条数有限制么?

我们将上面的循环次数改为500次,也就是将500条INCR一下发给redis,也可以正常运行。唯一不同的是,受限于TCP包大小,500条INCR被拆成了2个数据包发给redis服务端,服务端返回的数据也同样由于包大小的限制,被拆成了3个数据包。所以,可以认为PIPE对打包命令的条数没有限制。

6.如何选择

  • Redis::MULTI方式会将命令逐条发给redis服务端。只有在需要使用事物时才选择Redis::MULTI方式,它可以保证发给redis的一系列命令以原子方式执行。但效率相应也是最低的。
  • Redis::PIPELINE方式,可以将一系列命令打包发给redis服务端。如果只是为了一下执行多条redis命令,无需事物和原子性,那么应该选用Redis::PIPELINE方式。代码的性能会有大幅度提升!
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/01/16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
详解redis 中Pipeline流水线机制
这个过程称为Round trip time(简称RTT, 往返时间),mget mset有效节约了RTT,但大部分命令(如hgetall,并没有mhgetall)不支持批量操作,需要消耗N次RTT ,这个时候需要pipeline来解决这个问题。
码农编程进阶笔记
2021/09/09
2.1K0
详解redis 中Pipeline流水线机制
Redis基础知识(二)
redis中的事务是一组命令的集合,事务中的命令要么全部执行,要么都不执行,Redis 通过 MULTI 、DISCARD 、EXEC 和 WATCH 四个命令来实现事务功能,multi表示事物的开启,exec表示事物的执行,exec执行后返回事务执行的结果,discard表示放弃事务执行,清空事务队列中已有的所有命令并退出队列,watch用于监视给定的键,如果键被其他客户端修改,将不会执行事务。
没有故事的陈师傅
2020/03/30
5790
干货--Redis 30分钟快速入门
一、 redis环境搭建 1.简介        redis是一个开源的key-value数据库。它又经常被认为是一个数据结构服务器。因为它的value不仅包括基本的string类型还有list,set ,sorted set和hash类型。当然这些类型的元素也都是string类型。也就是说list,set这些集合类型也只能包含 string 类型。你可以在这些类型上做很多原子性的操作。比如对一个字符value追加字符串(APPEND命令)。加加或者减减一个数字字符串(INCR命令,当 然是按整数
汤高
2018/01/11
1.1K0
详解redis 中Pipeline流水线机制
这个过程称为Round trip time(简称RTT, 往返时间),mget mset有效节约了RTT,但大部分命令(如hgetall,并没有mhgetall)不支持批量操作,需要消耗N次RTT ,这个时候需要pipeline来解决这个问题。
全栈程序员站长
2022/07/19
8740
详解redis 中Pipeline流水线机制
Redis性能优化:理解与使用Redis Pipeline
当我们谈论Redis数据处理和存储的优化方法时,「Redis Pipeline」无疑是一个不能忽视的重要技术。
BookSea
2023/10/12
2.4K0
Redis构建分布式锁
  为什么要构建锁呢?因为构建合适的锁可以在高并发下能够保持数据的一致性,即客户端在执行连贯的命令时上锁的数据不会被别的客户端的更改而发生错误。同时还能够保证命令执行的成功率。
那一叶随风
2018/08/22
5810
Redis构建分布式锁
Redis 键管理与小功能
一、单个键管理 针对单个键的命令,有type、del、object, exists, expire等,下面介绍几个重要的 键的重命名
小手冰凉
2020/07/27
4130
Redis系列:Redis持久化机制与Redis事务
Redis 是个基于内存的数据库。那服务一旦宕机,内存中数据必将全部丢失。所以丢失数据的恢复对于 Redis 是十分重要的,我们首先想到是可以从数据库中恢复,但是在由 Redis 宕机时(说明相关工作正在运行)且数据量很大情况下,从数据库恢复的话,会为数据库带来巨大的压力,进而导致程序相应缓慢。因此实现数据的持久化,避免从后端数据库中恢复数据,对于Redis 是十分必要的。
栗筝i
2022/12/01
3730
Redis系列:Redis持久化机制与Redis事务
一篇和Redis有关的锁和事务的文章
通过SETNX命令,set if not exist的缩写。那么多个服务在调用的时候可以通过同一个key申请一个lock(也就是调用命令成功返回1),然后根据相应条件做释放(比如时间到期,or手动释放),也就是delete key。
_淡定_
2019/05/15
1.1K0
Redis
2.修改slave1的配置文件: [root@redis-slave1 ~]# cd /data/application/redis/ [root@redis-slave1 redis]# vim redis.conf —修改如下:
Cyylog
2020/08/19
4650
Redis Shell
Redis提供了redis-cli、redis-server、redis-benchmark等Shell工具。它们虽然比较简单,但是麻雀虽小五脏俱全,有时可以很巧妙地解决一些问题。
三产
2021/01/12
6980
Redis事务涉及的watch、multi等命令
作用: 用于监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。 用法:
Clive
2018/12/05
1.2K0
你真的懂Redis事务吗?
MULTI 、 EXEC 、 DISCARD 和 WATCH 是 Redis 事务的基础。
Bug开发工程师
2018/08/17
8.4K1
Redis pipeline(12)原
Pipeline模式:是一次性发送多个命令,最后一次取回所有的返回结果,这种模式通过减少网络的往返时间和io读写次数,大幅度提高通信性能。
兜兜毛毛
2020/04/23
9990
Redis的高级特性与应用场景(二)
Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。 这意味着通常情况下一个请求会遵循以下步骤:
憧憬博客
2020/07/21
5210
PHP操作Redis详解案例
$redis = new Redis(); connect, open 链接redis服务 参数 host: string,服务地址 port: int,端口号 timeout: float,链接时长 (可选, 默认为 0 ,不限链接时间) 注: 在redis.conf中也有时间,默认为300 pconnect, popen 不会主动关闭的链接 参考上面 setOption 设置redis模式 getOption 查看redis设置的模式 ping 查看连接状态 get 得到某个key的值(string值)
思梦php
2018/03/09
1.4K0
Go语言中高效使用Redis的Pipeline
在构建高性能应用时,Redis 经常成为开发者的首选工具。作为一个内存数据库,Redis 可以处理大量的数据操作,但如果每个命令都单独发送,网络延迟会成为瓶颈,影响性能。
南山竹
2024/08/19
5300
Go语言中高效使用Redis的Pipeline
Redis的Multi的内幕真相
由于本人太忙不想去阅读Redis Server的源代码(其实是懒),就通过TCPDump来分析吧。
sunsky
2020/08/20
6560
云测评 | Redis-pipeline对于性能的提升究竟有多大?
点击上方蓝字每天学习数据库 首先来介绍一下今天的主角——Redis Pipelining。该功能是为了解决因为客户端和服务器的网络延迟造成的请求延迟。 Redis Pipelining在很早就出现了,如果你在用较早版本的Redis,那么也能使用这个功能。此功能可以将一系列请求连续发送到Server端,不必等待Server端的返回,而Server端会将请求放进一个有序的管道中,在执行完成后,会一次性将返回值再发送回来。 对于这么神奇的功能,我们怎么能不测一下pipeline对于性能的提升有多大呢? 一、
腾讯云数据库 TencentDB
2019/05/16
4.4K0
云测评 | Redis-pipeline对于性能的提升究竟有多大?
Redis | Redis 的事务二
上篇关于整理 Redis 事务的文章中遗留了一个问题,当一个客户端对一个 key 进行修改操作时,另外一个客户端也修改了同一个 key 导致数据产生了问题。上篇文章的地址是:Redis | Redis 的事务一
码农UP2U
2020/12/15
3200
相关推荐
详解redis 中Pipeline流水线机制
更多 >
交个朋友
加入[数据] 腾讯云技术交流站
获取数据实战干货 共享技术经验心得
加入数据技术工作实战群
获取实战干货 交流技术经验
加入[数据库] 腾讯云官方技术交流站
数据库问题秒解答 分享实践经验
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验