加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-16 04:45:59 所属栏目:安全 来源:网络整理
导读:? ? ? ?前段时间在做用户画像的时候,遇到了这样的一个问题,记录某一个商品的用户购买群,刚好这种需求就可以用到Redis中的Set,key作为productID,value 就是具体的customerid集合,后续的话,我就可以通过productid来查看该customerid是否买了此商品,如

  

? ? ? ?前段时间在做用户画像的时候,遇到了这样的一个问题,记录某一个商品的用户购买群,刚好这种需求就可以用到Redis中的Set,key作为productID,value

就是具体的customerid集合,后续的话,我就可以通过productid来查看该customerid是否买了此商品,如果购买了,就可以有相关的关联推荐,当然这只是系统中

的一个小业务条件,这时候我就可以用到SADD操作方法,代码如下:

Main(= ConnectionMultiplexer.Connect( </span><span style="color: #0000ff;"&gt;var</span> db =<span style="color: #000000;"&gt; redis.GetDatabase(); </span><span style="color: #0000ff;"&gt;var</span> productID = <span style="color: #0000ff;"&gt;string</span>.Format(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;productID_{0}</span><span style="color: #800000;"&gt;"</span>,<span style="color: #800080;"&gt;1</span><span style="color: #000000;"&gt;); </span><span style="color: #0000ff;"&gt;for</span> (<span style="color: #0000ff;"&gt;int</span> i = <span style="color: #800080;"&gt;0</span>; i < <span style="color: #800080;"&gt;10</span>; i++<span style="color: #000000;"&gt;) { </span><span style="color: #0000ff;"&gt;var</span> customerID =<span style="color: #000000;"&gt; i; db.SetAdd(productID,customerID); } }</span></pre>

? ? 但是上面的这段代码很明显存在一个大问题,Redis本身就是基于tcp的一个Request/Response protocol模式,

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

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

? ? ?刚好基于我们现有的业务,我可以定时的将批量的productid和customerid进行分组整合,然后用batch的形式插入到某一个具体的product的set中去,

接下来我可以把上面的代码改成类似下面这样:

Main( ConnectionMultiplexer redis = ConnectionMultiplexer.Connect( db = productID = .Format(, list = List<> ( i = ; i < ; i++ (RedisValue)i).ToArray()); }

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

  product维度的画像我们可以解决了,但是我们还有一个customerid的维度,也就是说我需要维护一个customerid为key的set集合,其中value的值为

该customerid的各种平均值,比如说“总交易次数”,“总交易金额”。。。等等这样的聚合信息,然后推送过来的是批量的customerid,也就是说你需要定时

维护一小嘬set集合,在这种情况下某一个set的批量操作就搞不定了。。。原始代码如下:

Main( ConnectionMultiplexer redis = ConnectionMultiplexer.Connect( db = orderTotalPrice = customerIDList = List<> ( i = ; i < ; i++ ( item customerID = .Format( }

? ? 上面这种代码在生产上当然是行不通的,不过针对这种问题,redis早已经提出了相关的解决方案,那就是pipeline机制,原理还是一样,将命令集整合起来通过

一条request请求一起送过去,由redis内部fake出一个client做批量执行操作,代码如下:

Main( ConnectionMultiplexer redis = ConnectionMultiplexer.Connect( db = orderTotalPrice = customerIDList = List<> ( i = ; i < ; i++ batch = ( item customerID = .Format( }

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

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

.:> keys * ) ) ) ) ) ) ) ) ) )

好了,先就说到这里了,希望本篇对你有帮助。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读