图片 4

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

  

前些日子在做用户画像的时候,遇到了这么的二个难题,记录某二个货品的用户购买群,刚好这种需求就能够用到Redis中的Set,key作为productID,value便是具体的customerid会集,后续的话,笔者就可以通过productid来查阅该customerid是不是买了此商品,要是购买了,就能够有连带的关系推荐,当然那只是系统中的1个小事情规范,那时候小编就能够用到SADD操作方法,代码如下:

     
 上3个月在做用户画像的时候,碰着了如此的一个标题,记录某贰个商品的用户购买群,刚好这种供给就能够用到Redis中的Set,key作为productID,value

    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);
      }
    }

哪怕具体的customerid集结,后续的话,作者就能够透过productid来查阅该customerid是或不是买了此商品,借使购买了,就能够有相关的涉及推荐,当然那只是系统中

一:问题

的贰个小事情规则,那时候小编就足以用到SADD操作方法,代码如下:

   
不过地方的这段代码很显然存在2个大难题,Redis自身就是依据tcp的几个Request/Response
protocol情势,不信的话,能够用wireshark监视一下:

        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);
            }
        }

 图片 1

 

从图中能够看来,有很频仍的1玖二.168.二叁.一 => 1玖二.168.二三.151之间的多寡往返,从传输内容中山高校约也得以见见有3个堪称productid_xxx的前缀,

一:问题

那要是有百万次局域网那样的round
trip,那这些延迟性由此可见,断定达不到大家预料的高质量。

   
然而下面的这段代码很扎眼存在三个大主题素材,Redis自身正是依据tcp的一个Request/Response
protocol方式,不信的话,能够用wireshark监视一下:

 贰:消除方案【Batch】

图片 2

    
刚好基于咱们现成的事体,小编得以定期的将批量的productid和customerid进行分组整合,然后用batch的款式插入到某一个切实的product的set中去,接下去本身得以把地点的代码改成类似下边那样:

从图中能够见见,有很频仍的192.16八.贰三.一 => 19二.16八.二三.15一之间的数目往返,从传输内容中山大学约也得以看出有二个名称为productid_xxx的前缀,

     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());
     }

那若是有百万次局域网那样的round
trip,这这么些延迟性由此可见,确定达不到大家预料的高品质。

 

 

 图片 3

2:搞定方案【Batch】

从截图中传输的request,response能够观察,本次大家2遍性交给过去,相当大的较少了在网络传输方面带来的窘迫性。。

   
 刚好基于大家现存的职业,作者能够定期的将批量的productid和customerid举行分组整合,然后用batch的款式插入到某二个切实的product的set中去,

 三:再度提议难题

接下去本人得以把上边的代码改成类似上边那样:

product维度的传真大家能够缓和了,不过大家还有1个customerid的维度,也正是说小编索要有限支持贰个customerid为key的set集结,当中value的值为该customerid的各样平均值,比方说“总交易次数”,“总交易金额”。。。等等那样的聚合音信,然后推送过来的是批量的customerid,也正是说你须求定期维护一小嘬set会集,在这种情况下某三个set的批量操作就搞不定了。。。原始代码如下:

 1         static void Main(string[] args)
 2         {
 3             ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("192.168.23.151:6379");
 4 
 5             var db = redis.GetDatabase();
 6 
 7             var productID = string.Format("productID_{0}", 1);
 8 
 9             var list = new List<int>();
10 
11 
12             for (int i = 0; i < 10; i++)
13             {
14                 list.Add(i);
15             }
16 
17             db.SetAdd(productID, list.Select(i => (RedisValue)i).ToArray());
18         }
     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);
       }
     }

图片 4

肆:消除方案【PipeLine】

 

=上边这种代码在生产上本来是对事情没有什么帮助的,可是针对这种主题素材,redis早已经提议了相关的解决方案,那正是pipeline机制,原理照旧同样,将下令集整合起来经过一条request请求一同送过去,由redis内部fake出三个client做批量进行操作,代码如下:

从截图中传输的request,response能够观察,此番大家壹回性交给过去,相当的大的较少了在互连网传输方面带来的难堪性。。

     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那样的小命令,那就注解有数不尽下令是①道过去的,大大的提高了质量。