使用Redis实现实时排名

Redis用途很广泛,分布式用户Session缓存、爬虫URL队列、活动页面的动态列表信息等。使用Redis实现排行榜系统也是很常见的方案。

假如设计一个积分排名系统。如果积分数据都存放在数据库中,积分的更新是动态的,每次访问排行页面都需要对数据进行重新排序,在真实的产品应用中几乎是不可接受的。

Redis 提供了 sorted set 有序集合数据结构,高效的插入和删除性能,适用于需实时排序的场景。我们先抛开sorted set 的实现机制,先来尝试一下利用redis实现一个实时的排行榜系统。


zadd——新增玩家

zadd 排行榜名称 分数 玩家标识

zadd命令如果重复新增 排行榜名称和玩家标识相同,记录会被覆盖
所以我们使用zincrby实现新增用户的功能


zincrby——增减玩家分数

zincrby 排行榜名称 分数 用户
127.0.0.1:6379> ZINCRBY rank:20180601 5 user1  
"10"
127.0.0.1:6379> ZINCRBY rank:20180601 1 user2
"1"
127.0.0.1:6379> ZINCRBY rank:20180601 10 user3
"10"
127.0.0.1:6379> ZINCRBY rank:20180602 15 user1
"15"
127.0.0.1:6379> ZINCRBY rank:20180602 10 user3
"10"
127.0.0.1:6379> ZINCRBY rank:20180603 21 user2
"21"
127.0.0.1:6379> ZINCRBY rank:20180603 5 user2
"26"

ZINCRBY rank:20180603 5 user2(用户user2在20180603新增5分)


zscore——查看玩家分数

zscore 排行榜名称 玩家标识
127.0.0.1:6379> zscore rank:20180603 user2
"26"

查看user2这个玩家在20180603积累的分数。


zrevrange——查看排行榜

zrevrange 排行榜名称 起始位置 结束位置 [withscores]

由于排行榜一般是按照分数由高到低排序的,所以我们使用zrevrange,而命令zrange是按照分数由低到高排序。
起始位置和结束位置都是以0开始的索引,且都包含在内。如果结束位置为-1则查看范围为整个排行榜。
带上withscores则会返回玩家分数。

127.0.0.1:6379> zrevrange rank:20180601 0 -1 withscores
1) "user3"
2) "10"
3) "user1"
4) "10"
5) "user2"
6) "1"

查看20180601这一天所有玩家分数。


zrevrange——查看指定时间范围排行榜

ZUNIONSTORE destination numkeys key [key ...]
127.0.0.1:6379> ZUNIONSTORE rank:last_three_days 3 rank:20180601 rank:20180602 rank:20180603 WEIGHTS 1 1 1 
(integer) 3

这样就将最近3天的积分记录合并到有序集合 rank:last_three_days 中了。
权重因子 WEIGHTS 如果不给,默认就是 1。为了不隐藏细节,特意写出。
那么查询最近3天的积分榜 Top10 的信息就是:

127.0.0.1:6379> ZREVRANGE rank:last_three_days  0 9 withscores 
1) "user2"
2) "27"
3) "user1"
4) "25"
5) "user3"
6) "20"

zrevrank——查看玩家的排名

zrevrank 排行榜名称 玩家标识
127.0.0.1:6379> zrevrank rank:20180601 user2
(integer) 2

查询用户user2在20180601这一天的排名


zrem——移除某个玩家

zrem 排行榜名称 玩家标识

del——删除排行榜

del 排行榜名称

总结

上面展示了利用Redis实现实时的排行榜的排行系统。当然,要完成真正的排行榜系统还有很多细节的地方要处理,如相同分数的如何根据其他条件排序等。

同样,也可以实现对于论坛帖子的浏览统计和排序,热度的排名(可以使用ZUNIONSTORE 的 WEIGHTS 分配不同的权重 实现)。


其他命令

上面只是列出了一部分命令的使用,下面给出命令列表,可以自行组合尝试

ZADD key score1 member1 [score2 member2]
向有序集合添加一个或多个成员,或者更新已存在成员的分数 |
ZCARD key
获取有序集合的成员数 |
ZCOUNT key min max
计算在有序集合中指定区间分数的成员数 |
ZINCRBY key increment member
有序集合中对指定成员的分数加上增量 increment |
ZINTERSTORE destination numkeys key [key ...]
计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中 |
ZLEXCOUNT key min max
在有序集合中计算指定字典区间内成员数量
ZRANGE key start stop [WITHSCORES]
通过索引区间返回有序集合成指定区间内的成员
ZRANGEBYLEX key min max [LIMIT offset count]
通过字典区间返回有序集合的成员
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT]
通过分数返回有序集合指定区间内的成员
ZRANK key member
返回有序集合中指定成员的索引
ZREM key member [member ...]
移除有序集合中的一个或多个成员
ZREMRANGEBYLEX key min max
移除有序集合中给定的字典区间的所有成员
ZREMRANGEBYRANK key start stop
移除有序集合中给定的排名区间的所有成员
ZREMRANGEBYSCORE key min max
移除有序集合中给定的分数区间的所有成员
ZREVRANGE key start stop [WITHSCORES]
返回有序集中指定区间内的成员,通过索引,分数从高到底
ZREVRANGEBYSCORE key max min [WITHSCORES]
返回有序集中指定分数区间内的成员,分数从高到低排序
ZREVRANK key member
返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
ZSCORE key member
返回有序集中,成员的分数值
ZUNIONSTORE destination numkeys key [key ...]
计算给定的一个或多个有序集的并集,并存储在新的 key 中
ZSCAN key cursor [MATCH pattern] [COUNT count]
迭代有序集合中的元素(包括元素成员和元素分值)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342