麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 數據庫 > Redis > 正文

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

2020-10-28 21:38:05
字體:
來源:轉載
供稿:網友

前段時間在做用戶畫像的時候,遇到了這樣的一個問題,記錄某一個商品的用戶購買群,剛好這種需求就可以用到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"

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 99欧美视频| 男女亲热网站 | 成人影片在线免费观看 | 国产精品久久久久久久久粉嫩 | 欧美成年人视频在线观看 | 欧美国产永久免费看片 | 国产剧情v888av | 色污视频在线观看 | 在线a亚洲视频播放在线观看 | 欧美重口另类videos人妖 | 干色视频 | 国产精品成人亚洲一区二区 | 欧美精品电影一区二区 | 久久96国产精品久久秘臀 | 免费毛片儿 | 国产流白浆高潮在线观看 | 国产一区不卡 | 久久久久av69精品 | 日本欧美一区二区三区在线观看 | 亚洲视频在线一区二区 | 亚洲男人一区 | 激情小说激情图片激情电影 | 久久精品亚洲欧美日韩精品中文字幕 | 成人444kkkk在线观看 | 欧美成人精品一区二区 | 日本特级a一片免费观看 | 久久久久久久一区二区 | 国产成人精品区一区二区不卡 | 成年免费大片黄在线观看岛国 | 成人福利视频导航 | 青青国产在线视频 | 4480午夜| 欧美成人综合视频 | 精品国产视频一区二区三区 | 日美av在线 | 亚洲第一成人在线观看 | 欧美××××黑人××性爽 | 国产二区三区视频 | 黄色免费在线视频网站 | 久久91精品视频 | 久久福利小视频 |