详解redis 中Pipeline流水线机制

详解redis 中Pipeline流水线机制

大家好,又见面了,我是全栈君。

一、pipeline出现的背景:

redis客户端执行一条命令分4个过程:

发送命令-〉命令排队-〉命令执行-〉返回结果

这个过程称为Round trip time(简称RTT, 往返时间),mget mset有效节约了RTT,但大部分命令(如hgetall,并没有mhgetall)不支持批量操作,需要消耗N次RTT ,这个时候需要pipeline来解决这个问题。

二、pepeline的性能

1、未使用pipeline执行N条命令

详解redis 中Pipeline流水线机制

2、使用了pipeline执行N条命令

详解redis 中Pipeline流水线机制

3、两者性能对比

详解redis 中Pipeline流水线机制

小结:这是一组统计数据出来的数据,使用Pipeline执行速度比逐条执行要快,特别是客户端与服务端的网络延迟越大,性能体能越明显.

三、原生批命令(mset, mget)与Pipeline对比

1、原生批命令是原子性,pipeline是非原子性

(原子性概念:一个事务是一个不可分割的最小工作单位,要么都成功要么都失败。原子操作是指你的一个业务逻辑必须是不可拆分的. 处理一件事情要么都成功,要么都失败,原子不可拆分)

2、原生批命令一命令多个key, 但pipeline支持多命令(存在事务),非原子性

3、原生批命令是服务端实现,而pipeline需要服务端与客户端共同完成

四、Pipeline正确使用方式

在下面代码里,我用了一个用户名数组,数组元素的key值是用户对应的id,一旦用户修改了其用户名,我将修改两个redis值:

  • 当前用户其用户名修改次数需要+1

  • 更新当前用户对应的用户名数据

$redis = new Redis();

//开启管道模式,代表将操作命令暂时放在管道里
$pipe = $redis->multi(Redis::PIPELINE);

//循环遍历数据,执行操作
foreach ($users as $user_id => $username)
{
    //用户名修改次数+1
    $pipe->incr('changes:' . $user_id);

    // 更新用户名
    $pipe->set('user:' . $user_id . ':username', $username);
}

//开始执行管道里所有命令
$pipe->exec();

管道里放什么操作,并没有什么限制,即使你放获取数据的操作也是ok的。
现在就假设我们要给某个redis key值+1,但是获取另一个redis key值的value数据。
如下代码就是一个操作是更新某个用户被访问的次数,另一个操作则是获取用户信息数据。

$redis = new Redis();

//开启管道模式
$pipe = $redis->multi(Redis::PIPELINE);

//循环遍历数据,执行操作
foreach ($users as $user_id => $username)
{
    // 用户被访问的次数+1
    $pipe->incr('accessed:' . $user_id);

    // 获取用户数据记录
    $pipe->get('user:' . $user_id);
}
// 开始执行管道里所有命令
$users = $pipe->exec();

// 打印数据
print_r($users);

注意,由于管道里每一条命令都会返回数据,所以最终打印的数组,会含有incr操作带来的记录,还有从获取用户操作那里拉下来的redis key值作为了打印数组的索引值。

不过有个好处,管道里每个操作命令返回的数据是按照管道里顺序存储的,key值是0,1,2这种。我们想要啥数据,自己稍微处理一下就好啦。

如果我们像取消管道操作,用下面代码即可:

$pipe->discard();

总结:pipeline 虽然好用,但是每次pipeline 每次组装的命令个数不能没有节制,否则一次组装pipeline数据量过大,一方面会增加客户端的等待时间,另一方面会造成一定的网络阻塞,可以将一次包含大量命令的pipeline拆分成多次较小的pipeline来完成。

详解redis 中Pipeline流水线机制

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/111449.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • github上开源的优秀android项目

    github上开源的优秀android项目源码大招:不服来战!撸这些完整项目,你不牛逼都难!经常有人问我有没有什么项目代码,我回复说去Github找,但是还是好多人不知道如何找到那些比较好的项目。今天花了点时间找了些安卓的项目,觉得还是不错的,几乎就是自己生活常用的一些app,如果你是一个Android开发者,我觉得撸完这些项目,你想不牛逼都难。菜鸟新闻菜鸟新闻客户端是一个仿照36Kr官方,实时抓取36Kr…

    2022年6月16日
    36
  • django中实现逻辑删除[通俗易懂]

    django中实现逻辑删除[通俗易懂]django中实现逻辑删除,主要分三步:1.增加字段:is_delete=models.BooleanField(default=False,verbose_name=’逻辑删除’,help_text=’逻辑删除’)2.重写models中delete方法:defdelete(self,using=None,keep_parents=False):    ""…

    2022年5月15日
    43
  • pip安装的包pycharm识别不了_手机上的python安装第三方库

    pip安装的包pycharm识别不了_手机上的python安装第三方库问题描述:在cmd控制台pipinstallpytest后并显示安装成功后,并且尝试用pycharm的python中importpytest,显示异常,提示我未安装过pytest解决方法方法一:在PyCharm下载第三方库(即把之前下的库作废,这里重新再下一次……)方法二:坚持用pip的方法安装第三方库方法1:无需命令,通过pycharm操作即可,找到“pytest”点击“install”安装即可(由于我已经安装)方法2:我们…

    2022年8月27日
    5
  • TCP: time wait bucket table overflow的解决方法「建议收藏」

    TCP: time wait bucket table overflow的解决方法「建议收藏」1、问题描述:今天发现服务器日志中/var/log/message中有很多下面的这样的日志,并且es的进程占用cpu资源很高。然后百度查看了一下TIME_WAIT的值,[root@hadoop13~]#netstat-n|awk’/^tcp/{++S[$NF]}END{for(ainS)printa,S[a]}’发现等待数达到了10000多了。其实也可以用下面查

    2022年5月27日
    33
  • qstring如何初始化_qstringlist 初始化

    qstring如何初始化_qstringlist 初始化();//将路径赋值给strFilePath}ui->label->setText(strFilePath);QStringListfileList;dir.cd(strFilePath);//打开路径,调用dir对象的成员……(intindex,QStringkeyorvalue);//读取键名private:voidinit_com();…

    2022年6月9日
    168
  • 2021年计算机保研-假211真双非三无的失败保研经历(武大/复旦/计算所/华科/同济/上交)

    2021年计算机保研-假211真双非三无的失败保研经历(武大/复旦/计算所/华科/同济/上交)从知乎@孤芳倚花红转过来啦~一、个人情况学校:华中地区211,计算机科学与技术(感觉华中211CS水平都差不多)。英语:CET4-534,预推免CET6-447。夏令营的时候没有六级真的太伤了,第一次裸考没过,第二次忘了报名,幸亏第三次考过了预推免可以用上。成绩:专业排名3/140,预推免2/147。211只有rk1和非rk1,非rk1≈没学上。科研:国家级、省级大创各一项,均是负责人,前者OD,后者SOD。没有论文,但是有一定CV和DL的基础,不惧面试。竞赛:省一及以上数学建模、数学竞赛奖项

    2022年7月25日
    67

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号