• redis中multi与pipeline介绍分析


    背景

    由于对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不保证原子性

    作者:Walker
    链接:https://juejin.im/post/5b42e025f265da0fa332d4dc
    来源:掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    2017 五一 清北学堂 Day1模拟考试结题报告
    2973 枪毙
    2840 WIKIOI——评测
    解决magento保存产品时耗时很长的问题
    easyui-layout中的收缩层无法显示标题问题解决
    JAVA排序(一) Comparable接口
    C语言数据结构----栈与递归
    [置顶] SpecDD(混合的敏捷方法模型)主要过程概述
    Vim 实用技术,第 1 部分: 实用技巧(转)
    如何解决dns解析故障
  • 原文地址:https://www.cnblogs.com/cjjjj/p/12818735.html
Copyright © 2020-2023  润新知