前段时间在做用户画像的时候,遇到了这样的一个问题,记录某一个商品的用户购买群,刚好这种需求就可以用到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"
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]