利用Redis实现排行系统

利用redis的list和zset数据类型都可以实现排行榜系统。

区别:

  • list本身没有排序功能,需要外部程序排序之后存储到list中,通过list的LRANGE key start stop命令实现分页数据或者前50的排名或者最新前5条数据。
  • zset本身有排序机制,不需要外部程序做排序。
  • list适合做定时排序,如每天的销量排行。
  • zset适合做实时计算排行,如玩家分数排行。
  • zset比list占用更大的内存空间。

list类型

list类型是简单的字符串列表,按照插入顺序排序。每个列表最多可以存储 232 - 1 个元素(40多亿) ,list类型主要有以下应用场景。。

  1. 消息队列

  list类型的lpop和rpush(或者反过来,lpush和rpop)能实现队列的功能,故而可以用Redis的list类型实现简单的点对点的消息队列。不过不推荐在实战中这么使用,因为现在已经有Kafka、NSQ、RabbitMQ等成熟的消息队列了,它们的功能已经很完善了,除非是为了更深入地理解消息队列,不然没必要去重复造轮子。

  2. 排行榜(非实时计算)

  list类型的lrange命令可以分页查看队列中的数据。可将每隔一段时间计算一次的排行榜存储在list类型中,如京东每日的手机销量排行、学校每次月考学生的成绩排名、斗鱼年终盛典主播排名等。

  但是,并不是所有的排行榜都能用list类型实现,只有定时计算的排行榜才适合使用list类型存储,与定时计算的排行榜相对应的是实时计算的排行榜,list类型不能支持实时计算的排行榜,之后在介绍有序集合sorted set的应用场景时会详细介绍实时计算的排行榜的实现。

  3. 最新列表

  list类型的lpush命令和lrange命令能实现最新列表的功能,每次通过lpush命令往列表里插入新的元素,然后通过lrange命令读取最新的元素列表,如朋友圈的点赞列表、评论列表。

  但是,并不是所有的最新列表都能用list类型实现,因为对于频繁更新的列表,list类型的分页可能导致列表元素重复或漏掉,举个例子,当前列表里由表头到表尾依次有(E,D,C,B,A)五个元素,每页获取3个元素,用户第一次获取到(E,D,C)三个元素,然后表头新增了一个元素F,列表变成了(F,E,D,C,B,A),此时用户取第二页拿到(C,B,A),元素C重复了。只有不需要分页(比如每次都只取列表的前5个元素)或者更新频率低(比如每天凌晨更新一次)的列表才适合用list类型实现。对于需要分页并且会频繁更新的列表,需用使用有序集合sorted set类型实现。另外,需要通过时间范围查找的最新列表,list类型也实现不了,也需要通过有序集合sorted set类型实现,如以成交时间范围作为条件来查询的订单列表。之后在介绍有序集合sorted set类型的应用场景时会详细介绍sorted set类型如何实现最新列表。

  那么问题来了,对于排行榜和最新列表两种应用场景,list类型能做到的sorted set类型都能做到,list类型做不到的sorted set类型也能做到,那为什么还要使用list类型去实现排行榜或最新列表呢,直接用sorted set类型不是更好吗?原因是sorted set类型占用的内存容量是list类型的数倍之多,对于列表数量不多的情况,可以用sorted set类型来实现,比如上文中举例的手机销量排行榜,每天全国只有一份,两种数据类型的内存容量差距可以忽略不计,但是如果要实现手机在某地区排行榜,数十万手机,300多个地区,会产生数量庞大的榜单,或者数量更加庞大的朋友圈点赞列表,就需要慎重地考虑容量的问题了。

zset类型

Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。

  1. 排行榜(实时计算)

  其实就是reids命令的:ZINCRBY key increment member,描述:有序集合中对指定成员的分数加上增量 increment,比如微博热搜排序,key就可以是小时榜/天榜/月榜,member是某一条热搜词条,incrementScore就是这个词条热度增量/权重增量),这个命令是自增类型的,所以你也不用担心刚开始的时候是否存在这个key(并发问题),如果调用ZINCRBY的时候这个key已经存在,那就score自增,如果不存在那就新增这个key,然后把自增量设置为初始值,天然的线程安全,redis牛逼!!! 又比如你的业务是直播间但消费额排行,那你的ZINCRBY自增量就是本次消费的金额数,这点应该很好理解。
       剩下的就是取数据了,取数据的话也是从zset取排行的有序集合数据:

命令就是:ZREVRANGEBYSCORE key max min [WITHSCORES],描述:返回有序集中指定分数区间内的成员,分数从高到低排序。
举个例子哈,如果你要取排行榜前十名,那么调用上面方法的参数就是:ZREVRANGEBYSCORE key 0 9

 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值