mysql视频 分布式机器 PaddleHub volatile svn loam算法测试 yii2 upload tinymce UIkit vue状态管理 vue传值 vue组件开发 vue前端框架 less用法 matlab根号怎么打出来 js字符串排序 网络游戏server编程 mysql自连接 less比较级 tomcat调优和jvm调优 android网络请求 mysql建表主键自增长 docker保存镜像 python课程 java操作mysql java手册 java的泛型 java重命名 java异常 sql实例 嵌入式开发教程 黑客攻防实战入门 网络是怎样连接的 超级力量2修改 git命令 ip地址转换器 wegame更新失败 游戏linux正则表达式 抠图软件免费版
当前位置: 首页 > 学习教程  > 编程语言

redis中multi与pipeline介绍分析

2020/9/19 15:15:02 文章标签:

背景

由于对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标记事务开始,之后每次执行,服务端返回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服务端一次性返回所有命令执行返回结果。

 

 

 

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抓包,如下图所示

  • pipeline 客户端请求包示例图

 

 

 

  • pipeline 服务端返回包示例图

 

 

 

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

两者的区别

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

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


作者:Walker5883
链接:https://juejin.im/post/6844903635252412430
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


本文链接: http://www.dtmao.cc/news_show_200241.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?