详解redis大幅性能提升之使用管道(PipeLine)和批量(Batch)操作

发布时间 - 2026-01-10 22:02:28    点击率:

前段时间在做用户画像的时候,遇到了这样的一个问题,记录某一个商品的用户购买群,刚好这种需求就可以用到Redis中的Set,key作为productID,value就是具体的customerid集合,后续的话,我就可以通过productid来查看该customerid是否买了此商品,如果购买了,就可以有相关的关联推荐,当然这只是系统中的一个小业务条件,这时候我就可以用到SADD操作方法,代码如下:

    static void Main(string[] args)
    {
      ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("192.168.23.151:6379");

      var db = redis.GetDatabase();

      var productID = string.Format("productID_{0}", 1);

      for (int i = 0; i < 10; i++)
      {
        var customerID = i;

        db.SetAdd(productID, customerID);
      }
    }

一:问题

    但是上面的这段代码很明显存在一个大问题,Redis本身就是基于tcp的一个Request/Response protocol模式,不信的话,可以用wireshark监视一下:

 

从图中可以看到,有很多次的192.168.23.1 => 192.168.23.151 之间的数据往返,从传输内容中大概也可以看到有一个叫做productid_xxx的前缀,

那如果有百万次局域网这样的round trip,那这个延迟性可想而知,肯定达不到我们预想的高性能。

 二:解决方案【Batch】

     刚好基于我们现有的业务,我可以定时的将批量的productid和customerid进行分组整合,然后用batch的形式插入到某一个具体的product的set中去,接下来我可以把上面的代码改成类似下面这样:

     static void Main(string[] args)
     {
       ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("...:");
 
       var db = redis.GetDatabase();
 
       var productID = string.Format("productID_{}", );
 
       var list = new List<int>();
 
 
       for (int i = ; i < ; i++)
       {
         list.Add(i);
       }
 
       db.SetAdd(productID, list.Select(i => (RedisValue)i).ToArray());
     }
 

 

从截图中传输的request,response可以看到,这次我们一次性提交过去,极大的较少了在网络传输方面带来的尴尬性。。

 三:再次提出问题

product维度的画像我们可以解决了,但是我们还有一个customerid的维度,也就是说我需要维护一个customerid为key的set集合,其中value的值为该customerid的各种平均值,比如说“总交易次数”,“总交易金额”。。。等等这样的聚合信息,然后推送过来的是批量的customerid,也就是说你需要定时维护一小嘬set集合,在这种情况下某一个set的批量操作就搞不定了。。。原始代码如下:

     static void Main(string[] args)
     {
       ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("...:");
 
       var db = redis.GetDatabase();
 
 
       //批量过来的数据: customeridlist, ordertotalprice,具体业务逻辑省略
       var orderTotalPrice = ;
 
       var customerIDList = new List<int>();
 
       for (int i = ; i < ; i++)
       {
         customerIDList.Add(i);
       }
 
       //foreach更新每个redis 的set集合
       foreach (var item in customerIDList)
       {
         var customerID = string.Format("customerid_{}", item);
 
         db.SetAdd(customerID, orderTotalPrice);
       }
     }

四:解决方案【PipeLine】

=上面这种代码在生产上当然是行不通的,不过针对这种问题,redis早已经提出了相关的解决方案,那就是pipeline机制,原理还是一样,将命令集整合起来通过一条request请求一起送过去,由redis内部fake出一个client做批量执行操作,代码如下:

     static void Main(string[] args)
     {
       ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("...:");
 
       var db = redis.GetDatabase();
 
 
       //批量过来的数据: customeridlist, ordertotalprice,具体业务逻辑省略
       var orderTotalPrice = ;
 
       var customerIDList = new List<int>();
 
       for (int i = ; i < ; i++)
       {
         customerIDList.Add(i);
       }
 
       var batch = db.CreateBatch();
 
       foreach (var item in customerIDList)
       {
         var customerID = string.Format("customerid_{}", item);
 
         batch.SetAddAsync(customerID, orderTotalPrice);
       }
 
       batch.Execute();
     }

然后,我们再看下面的wireshark截图,可以看到有很多的SADD这样的小命令,这就说明有很多命令是一起过去的,大大的提升了性能。

 

 最后可以再看一下redis,数据也是有的,是不是很爽~~~

192.168.23.151:6379> keys *
 1) "customerid_0"
 2) "customerid_9"
 3) "customerid_1"
 4) "customerid_3"
 5) "customerid_8"
 6) "customerid_2"
 7) "customerid_7"
 8) "customerid_5"
 9) "customerid_6"
10) "customerid_4"

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# redis  # 批量写入  # 管道批量获取  # 管道  # redis批量操作pipeline管道操作方法  # Redis中管道操作的项目实践  # Springboot下使用Redis管道(pipeline)进行批量操作  # Python redis操作实例分析【连接、管道、发布和订阅等】  # Redis中管道操作pipeline的实现  # 可以看到  # 我就  # 有很多  # 再看  # 就可以  # 的是  # 可以用  # 买了  # 提出了  # 这段  # 我们可以  # 这就  # 说我  # 可以通过  # 少了  # 不信  # 还有一个  # 这只  # 说你  # 大大的 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel怎么创建控制器Controller_Laravel路由绑定与控制器逻辑编写【指南】  千库网官网入口推荐 千库网设计创意平台入口  最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?  EditPlus 正则表达式 实战(3)  手机软键盘弹出时影响布局的解决方法  如何在不使用负向后查找的情况下匹配特定条件前的换行符  如何快速搭建高效服务器建站系统?  BootStrap整体框架之基础布局组件  如何在浏览器中启用Flash_2025年继续使用Flash Player的方法【过时】  Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧  七夕网站制作视频,七夕大促活动怎么报名?  百度浏览器网页无法复制文字怎么办 百度浏览器复制修复  Android GridView 滑动条设置一直显示状态(推荐)  Thinkphp 中 distinct 的用法解析  网站制作壁纸教程视频,电脑壁纸网站?  在线教育网站制作平台,山西立德教育官网?  零服务器AI建站解决方案:快速部署与云端平台低成本实践  成都网站制作公司哪家好,四川省职工服务网是做什么用?  如何在阿里云完成域名注册与建站?  Laravel项目如何进行性能优化_Laravel应用性能分析与优化技巧大全  微信小程序制作网站有哪些,微信小程序需要做网站吗?  Laravel如何实现全文搜索功能?(Scout和Algolia示例)  品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?  如何正确下载安装西数主机建站助手?  Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】  如何用y主机助手快速搭建网站?  在centOS 7安装mysql 5.7的详细教程  如何在景安服务器上快速搭建个人网站?  Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件  js实现获取鼠标当前的位置  nginx修改上传文件大小限制的方法  免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?  Win11怎样安装网易有道词典_Win11安装词典教程【步骤】  如何在企业微信快速生成手机电脑官网?  Laravel如何配置和使用缓存?(Redis代码示例)  Python结构化数据采集_字段抽取解析【教程】  如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南  ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法  如何用ChatGPT准备面试 模拟面试问答与职场话术练习教程  百度浏览器如何管理插件 百度浏览器插件管理方法  JavaScript Ajax实现异步通信  浅谈Javascript中的Label语句  微信小程序 require机制详解及实例代码  php结合redis实现高并发下的抢购、秒杀功能的实例  韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南  python中快速进行多个字符替换的方法小结  如何在阿里云购买域名并搭建网站?  敲碗10年!Mac系列传将迎来「触控与联网」双革新  Laravel如何处理文件下载请求?(Response示例)  如何利用DOS批处理实现定时关机操作详解