加入收藏 | 设为首页 | 会员中心 | 我要投稿 网站开发网_安阳站长网 (https://www.0518zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长百科 > 正文

Redis存储总用String?你大概错过了更优的使用方法

发布时间:2019-01-31 04:43:37 所属栏目:站长百科 来源:王清培(沪江)
导读:副标题#e# Redis为我们提供了5种数据类型,基本上我们使用频率最高的就是String,而对其他四种数据类型使用的频次稍弱于String。原因在于: String使用起来比较简单,可以方便存储复杂的对象,使用场景比较多; 由于Redis expire time只能设置在key上,像Lis

在一些比较特殊的场合可能需要组合排序,可能有多个Zset分别用来对同一个实体在不同维度的排序,按时间排序、按人数排序等。这个时候就可以组合使用Zset带来的便捷性,利用pipeline再结合多个Zset最终得出组合排序集合。

二、案例:沪江团购系统大促hot-top接口cache设计

以沪江团购系统大促hot-top接口cache设计为例,我们总结了Redis提供的5种数据类型的各自特点和一般的使用场景。但是我们不仅仅可以分开使用这些数据类型,我们完全可以综合使用这些数据类型来完成复杂的cache场景。

下面我们分享一个使用多个Zset、String来优化团购系统前台接口的例子。由于篇幅和时间限制,这里只介绍跟本次案例相关的信息。

注:hot-top接口是指热点、排名接口的意思,表示它的浏览量、并发量比较高,一般大促的时候都会有几个这种性能要求比较高的接口。

我们先来分析一个查询接口所包含的常规信息。

首先一个查询接口肯定是有query condition查询条件,然后是sort排序信息、最后是page分页信息。这是一般接口所承担的基本职责,当然,特殊场景下还需要支持master/slave replication时关于数据session一致性的要求,需要提供跟踪标记来回master查询数据,这里就不展开了。

我们可以抽象出这几个维度的信息:

  • querycondition:查询条件,companyid =100,sellerid=1010101诸如此类。
  • sort:排序信息,一般是默认一个列排序,但是在复杂的场景下会有可能让接口使用者定制排序字段,比如一些租户信息列。
  • page:分页信息,简单理解就是数据记录排完序之后的第几行到第几行。

由于这里我们纯粹用Redis来提高cache能力,不涉及到有关于任何搜索的能力,所以这里忽略其他复杂查询的情况。其实我们在复杂的地方使用了Elastcsearch来提高搜索能力。

上述我们分析总结出了一个查询接口的基本信息,这里还有一个有关于高并发接口的设计原则,就是将hot-top接口和一般search接口分离开,因为只有分而治之才能分别根据特点选用不同的技术。

如果我们不分职责将所有的查询场景封装在一个接口里,那么在后面优化接口性能的时候基本就很麻烦了,有些场景是无法或者很难用cache来解决的,因为接口里耦合了各种场景逻辑,就算勉强能实现性能也不会高。

前面做这些铺垫是为了能在介绍案例的时候达成一个基本的共识。现在我们来看下这个团购系统的hot-top接口的具体逻辑。

注:在大促的时候需要展现团购列表,这个接口的访问量是非常大的,团购活动需要根据参团人数倒序排序,并且分页返回指定数量的团列表。我们假设这个接口名为getTopGroups(getTopGroupsRequestrequest)。

1)query condition查询条件问题

我们来仔细分析下,首先不同的查询条件从DB里查询出来的数据是不一样的,也就是说查询出来的团列表是不一样的,可能有company公司、channel渠道等过滤条件。

由于一个团购活动下不会有太多团,顶多上百个是极限了,所以一个查询条件出来的团列表也顶多几十个,而且根据场景分析热点查询条件不会超过十个,所以我们选择将查询条件Hash出一个code来缓存本次查询条件的全量团列表集合,但是这些结果集是没有任何排序的。

2)sort排序问题

再看根据参团人数排序问题,我们立刻就可以想到使用Zset来处理团排序问题,因为只有一个排序维度,所以一个Zset就够了。我们使用一个Zset来缓存所有团的参团人数集合,它是一个全量的团排序集合。

那么我们如何将用户的查询条件出来的团列表根据参团人数排序呢?刚好可以使用Zset的交集运算,直接计算出当前这个集合的Zset子集。

3)page分页问题

通过对已经排序之后的团列表Zset使用Zrange来获取出分页集合。我们来看下完整的流程,如何处理查询、排序、分页的。

下图从query condition计算Hash Code,然后通过DB查询出当前条件全量团列表:

Redis存储总用String?你大概错过了更优的使用方法

zset:marketing:groupon:hottop:available:groupkey表示全量团的参团人数,用一个Zset来缓存。接着将这两个Zset计算交集,就可以得出当前查询所需要的带有参团人数的Zset,最后在使用Zrevrange获取分页区间。

  1. ZADD zset:marketing:groupon:hottop:condition:2986080 0 G4ZD5732YZQ 0 G5VW3YF42UC 0 GF773FEJ7CC 0 GFW8DUEND8S 0 GKPKKW8XEY9 0 GL324DGWMZM  
  2. (integer) 6  
  3. ZADD zset:marketing:groupon:hottop:available:group 5 GN7KQH36ZWK 10 GS7VB22AWD4 15 GF773FEJ7CC 17 G5VW3YF42UC 18 G4ZD5732YZQ 32 GTYJKCEJBRR 40 GKPKKW8XEY9 45 GL324DGWMZM 50 GFW8DUEND8S 60 GYTKY4ACWLT  
  4. (integer) 10  
  5. ZINTERSTORE zset:marketing:groupon:hottop:condition:interstore 2 zset:marketing:groupon:hottop:condition:2986080 zset:marketing:groupon:hottop:available:group  
  6. (integer) 6  
  7. ZRANGE zset:marketing:groupon:hottop:condition:interstore 0 -1 withscores  
  8. 1) "GF773FEJ7CC"  
  9. 2) "15"  
  10. 3) "G5VW3YF42UC"  
  11. 4) "17"  
  12. 5) "G4ZD5732YZQ"  
  13. 6) "18"  
  14. 7) "GKPKKW8XEY9"  
  15. 8) "40"  
  16. 9) "GL324DGWMZM"  
  17. 10) "45"  
  18. 11) "GFW8DUEND8S"  
  19. 12) "50"  
  20. ZREVRANGE zset:marketing:groupon:hottop:condition:interstore 2 4 withscores  
  21. 1) "GKPKKW8XEY9"  
  22. 2) "40"  
  23. 3) "G4ZD5732YZQ"  
  24. 4) "18"  
  25. 5) "G5VW3YF42UC"  
  26. 6) "17" 

有了返回的团code集合之后就可以通过mget来批量获取String类型的团详情信息,这里就不贴出代码了。

(编辑:网站开发网_安阳站长网)

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