深入理解redis中multi与pipeline


Posted in Redis onJune 02, 2021

背景

由于对redis缓存中数据有批量操作,例如预热缓存数据,或者在列表页批量去获取缓存数据,在使用了multi批量提交事务后,发现redis压力高居不下,而使用了pipeline之后压力回落了平常,也因为这个案例,特在此写个分析与笔记。

multi

简介

标记一个事务块的开始。
事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性(atomic)地执行。

实现原理

我用php扩展调起redis服务,执行,代码如下:

$redis = new redis();
$redis->connect('127.0.0.1',6379);
$handle = $redis->multi();
$handle->incr('a');
$handle->incr('b');
$handle->exec();

为了查看这期间具体的连接过程,用wireshark监听回环地址端口6379,抓包请求如下图所示:

深入理解redis中multi与pipeline

redis客户端与服务端建立连接后,multi标记事务开始,之后每次执行,服务端返回queued队列标志。查看redis源码src/multi.c文件:

void queueMultiCommand(client *c) {
    multiCmd *mc;
    int j;

    c->mstate.commands = zrealloc(c->mstate.commands,
            sizeof(multiCmd)*(c->mstate.count+1));
    mc = c->mstate.commands+c->mstate.count;
    mc->cmd = c->cmd;
    mc->argc = c->argc;
    mc->argv = zmalloc(sizeof(robj*)*c->argc);
    memcpy(mc->argv,c->argv,sizeof(robj*)*c->argc);
    for (j = 0; j < c->argc; j++)
        incrRefCount(mc->argv[j]);
    c->mstate.count++;
}

在上述源码中可以看到redis服务端每次会把事务块中的命令保存到内存中,上述简介已经解释过最后通过exec命令执行,再看下面示例图的返回结果可以了解到redis服务端一次性返回所有命令执行返回结果。

深入理解redis中multi与pipeline

pipeline

简介

客户端将执行的命令写入到缓冲中,最后由exec命令一次性发送给redis执行返回。

实现原理

同样,用相关代码调用redis抓包;

$redis = new redis();
$redis->connect('127.0.0.1',6379);
$handle = $redis->pipeline();
$handle->incr('a');
$handle->incr('b');
$handle->exec();

继续用wireshark抓包,如下图所示

深入理解redis中multi与pipeline

pipeline 客户端请求包示例图

深入理解redis中multi与pipeline

这上面的图片简要分析一下,pipeline管道操作是需要客户端与服务端的支持,客户端将命令写入缓冲,最后再通过exec命令发送给服务端,服务端通过命令拆分,逐个执行返回结果。

两者的区别

由上面的请求也可以看出了两者最明显的区别是客户端发送请求的方式不一样,具体相关区别如下:

  • pipeline选择客户端缓冲,multi选择服务端缓冲;
  • 请求次数的不一致,multi需要每个命令都发送一次给服务端,pipeline最后一次性发送给服务端,请求次数相对于multi减少
  • multi/exec可以保证原子性,而pipeline不保证原子性

到此这篇关于深入理解redis中multi与pipeline 的文章就介绍到这了,更多相关redis multi与pipeline 内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Redis 相关文章推荐
Redis 配置文件重要属性的具体使用
May 20 Redis
解析高可用Redis服务架构分析与搭建方案
Jun 20 Redis
比较几种Redis集群方案
Jun 21 Redis
Redis集群的关闭与重启操作
Jul 07 Redis
Redis Cluster 集群搭建你会吗
Aug 04 Redis
为什么RedisCluster设计成16384个槽
Sep 25 Redis
Jedis操作Redis实现模拟验证码发送功能
Sep 25 Redis
Redis 持久化 RDB 与 AOF的执行过程
Nov 07 Redis
Redis Stream类型的使用详解
Nov 11 Redis
Redis特殊数据类型bitmap位图
Jun 01 Redis
Redis keys命令的具体使用
Jun 05 Redis
Redis实现分布式锁的五种方法详解
Jun 14 Redis
SpringBoot 集成Redis 过程
Jun 02 #Redis
详解Redis基本命令与使用场景
Django使用redis配置缓存的方法
Jun 01 #Redis
详解Redis集群搭建的三种方式
May 31 #Redis
浅谈Redis主从复制以及主从复制原理
5分钟教你docker安装启动redis全教程(全新方式)
May 29 #Redis
详解缓存穿透击穿雪崩解决方案
You might like
无数据库的详细域名查询程序PHP版(2)
2006/10/09 PHP
PHP中对各种加密算法、Hash算法的速度测试对比代码
2014/07/08 PHP
PHP实现163邮箱自动发送邮件
2016/03/29 PHP
PHP实现RSA签名生成订单功能【支付宝示例】
2017/06/06 PHP
利用PHP获取汉字首字母并且分组排序详解
2017/10/22 PHP
jquery和ajax的关系详细介绍
2013/11/29 Javascript
Javascript核心读书有感之语句
2015/02/11 Javascript
JavaScript、jQuery与Ajax的关系
2016/01/24 Javascript
js实现瀑布流效果(自动生成新的内容)
2017/03/16 Javascript
bootstrap弹出层的多种触发方式
2017/05/10 Javascript
NodeJS实现微信公众号关注后自动回复功能
2017/05/31 NodeJs
详细AngularJs4的图片剪裁组件的实例
2017/07/12 Javascript
详解基于vue-cli优化的webpack配置
2017/11/06 Javascript
详解JavaScript中的数组合并方法和对象合并方法
2018/05/11 Javascript
判断iOS、Android以及PC端的示例代码
2018/11/15 Javascript
vue中轮训器的使用
2019/01/27 Javascript
记录vue做微信自定义分享的一些问题
2019/09/12 Javascript
vue + axios get下载文件功能
2019/09/25 Javascript
使用Vue-cli3.0创建的项目 如何发布npm包
2019/10/10 Javascript
python 示例分享---逻辑推理编程解决八皇后
2014/07/20 Python
python字符串,数值计算
2016/10/05 Python
Java分治归并排序算法实例详解
2017/12/12 Python
python模块导入的细节详解
2018/12/10 Python
linux下安装python3和对应的pip环境教程详解
2019/07/01 Python
Python astype(np.float)函数使用方法解析
2020/06/08 Python
python开发前景如何
2020/06/11 Python
Matlab使用Plot函数实现数据动态显示方法总结
2021/02/25 Python
css 省略号 css3让多余的字符串消失并附加省略号的实现代码
2013/02/07 HTML / CSS
美国顶级奢侈茶:Mighty Leaf Tea(美泰茶)
2016/11/26 全球购物
保安拾金不昧表扬信
2014/01/15 职场文书
文秘大学生求职信
2014/02/25 职场文书
2014年廉洁自律承诺书
2014/05/26 职场文书
电视新闻稿
2015/07/17 职场文书
导游词之江苏溱潼古镇
2019/11/27 职场文书
win10下go mod配置方式
2021/04/25 Golang
win10壁纸在哪个文件夹 win10桌面背景图片文件位置分享
2022/08/05 数码科技