Post

一文设计亿级redis实时排行榜

一文设计亿级redis实时排行榜

设计高并发实时排行榜所需redis基础

redis四大统计

基数统计

基数 / Cardinality 是指集合中不同的元素的数量,简单来说,就是去重后的个数。

二值统计

二值统计是指将数据分为两个类别或状态,成功失败这样的,并对这些数据进行计数和分析。

排序统计

排序统计涉及将数据按照一定的顺序(升序或降序)进行排序,以便分析比较。

聚合统计

将多个数据记录组合成一个集合,并对该集合进行数值特征的计算统计。

Redis的有序集合 Sorted Set

语法:

  1. ZADD / 向有序集合添加一个或多个成员,或者更新已经存在成员的分数
1
ZADD key score member [score member ...]
  1. ZSCORE / 获取有序集合中指定成员的分数
1
ZSCORE key member
  1. ZINCRBY / 为有序集合中已存在的成员分数加上一个增量值
1
ZINCRBY key increment member
  1. ZRANK / ZREVRANK 获取有序集合中指定成员的排名。ZRANK是升序排名,ZREVRANK是降序排名。
1
2
ZRANK key member
ZREVRANK key member
  1. ZRANGE / ZREVRANGE 获取有序集合中指定区间的成员,ZRANGE是按分数从小到大排序,ZREVRANGE是按分数从大到小排序
1
2
ZRANGE key start stop [WITHSCORES]
ZREVRANGE key start stop [WITHSCORES]
  • WITHSCORES / 返回携带值
  1. ZCOUNT / 获取有序集合中指定分数区间的成员数量
1
ZCOUNT key min max
  1. ZREM / 移除有序集合中的一个或多个成员
1
ZREM key member [member...]
  1. ZCARD / 获取有序集合的成员数
1
ZCARD key
  1. ZREMRANGEBYSCORE / 移除有序集合中给定分数区间的所有成员
1
ZREMRANGEBYSCORE key min max

游戏玩家排行榜–积分制排行榜

在一个多人在线游戏中,我们希望能够实时追踪和显示玩家的排行榜,在高并发场景下,我们该佮设计能够承载频繁修改的排行榜呢?如果我们希望排行榜是实时更新的,在高并发下,后台的压力的非常巨大的。

现在的需求是这样的,需要周期更新的日榜、周期更新的周榜、实时更新的总榜。对于这三种不同类型的排行榜,采用不同的三种最合适的设计来满足不同的需求。

日榜

日榜的更新频率比较频繁,需要redis提高并发性,但是数据量比较少,不需要入库。所以设计方案是redis提供读写。

那如何实现周期更新呢?系统配置有更新排行榜的时间,比如00:00。日榜的key值这样设计:platform+type+time。这样新的一天的数据更新就不会影响到昨天的数据。当redis内缓存了太多的数据,可以删除一些老的日榜数据。

周榜

周榜是写少读多,对实时性要求不高,不需要redis来承载高并发量的访问,故周榜使用mysql实现即可。周榜库表的设计和日榜redis比较类似,表名:platform+type+time。字段持有用户id,用户在time范围内获得的积分。

前端想要获得周榜,就拿对应的时间来查表即可。比如想要那上一周的周榜,后端会计算上一周对应的time,然后去查表得到前100名的用户数据,然后返回前端

总榜

总榜的特点是实时性,和周期性更新不同,对实时的要求很高。同时总榜不比日榜,对数据量的要求也大。不能只拿redis来负责,需要使用redis+mysql来实现。

mysql的库表非常简单,不需要对time进行多表处理。redis负责缓存前100名的排行榜,mysql负责储存所有用户的排行榜。redis如何知道自己的前一百名排行榜数据脏了呢?每局游戏胜利后,在向数据库写入前,会查看当前用户的积分是不是比第一百名的大,如果是,说明前一百名发生变动,需要把redis的数据设置为脏。

到此三种榜单便全部设计完成

后续更新滚动榜等的实现

This post is licensed under CC BY 4.0 by the author.