使用redis实现排行榜功能

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011510825/article/details/85394592

排行榜功能是一个很普遍的需求。

设想在一个游戏中,有上百万的玩家数据,如果现在需要你根据玩家的经验值整理一个前20名的排行榜,你会怎么做呢?

你不可能 order by + limit 去实现

select * from game_socre order by score desc limit 0,20  

使用 Redis 中有序集合的特性来实现排行榜是又好又快的选择。

首先介绍下,会用到的几个命令及其它们的作用:

详情看官网(redis中文)

zrange  查看排行榜 (升序)

zrevrange 查看排行榜 (降序)

zadd 添加一个数据

zrem 删除一个数据

zrank 获取排名(升序)

zrevrank 获取排名 (降序)

了解命令之后,我们就可以试着玩一下了

127.0.0.1:6379> zrange rank_name 0 -1 withscores
(empty list or set)

查一下rank_name的排名表是空的,因为我们还没对rank_name这个有序集合进行添加,0,-1表示查找所有,withscores 表示带数值。

我们使用zadd添加一些数据

127.0.0.1:6379> zadd rank_name 10 zhangsan
(integer) 1
127.0.0.1:6379> zadd rank_name 5 lisi
(integer) 1
127.0.0.1:6379> zadd rank_name 100 wangwu
(integer) 1

再次查看

127.0.0.1:6379> zrange rank_name 0 -1 withscores
1) "lisi"
2) "5"
3) "zhangsan"
4) "10"
5) "wangwu"
6) "100"
127.0.0.1:6379> zrevrange rank_name 0 -1 withscores
1) "wangwu"
2) "100"
3) "zhangsan"
4) "10"
5) "lisi"
6) "5"

现在我想单独查看,zhangsan和lisi的排名

127.0.0.1:6379> zrank rank_name zhangsan
(integer) 1
127.0.0.1:6379> zrank rank_name lisi
(integer) 0

这里要注意,redis的排名是从0开始的,所以一般会加1,比较没有人说第0名。

更新的操作也是比较简单的,可以使用zadd直接进行覆盖。高并发情况下不推荐使用。例如投票这样的排名表,一般使用原子自增操作,确保数据准确性

127.0.0.1:6379> zincrby rank_name 1 wangwu
"101"
127.0.0.1:6379> zrevrange rank_name 0 -1 withscores
1) "wangwu"
2) "101"
3) "zhangsan"
4) "10"
5) "lisi"
6) "5"

日排行榜,周排行榜,月排行榜基本你可以设置key+时间,如rank_name_20181230。

总结:

redis的有序集合是一个非常高效的数据结构,可以替代数据库里一些很难实现的操作。它的一个典型应用场景就是排行榜,通过ZRANK可以快速得到用户的排名,通过ZRANGE可以快速得到TOP N的用户列表,它们的复杂度都是O(log(N)),用来替代数据库查询可以大大提升性能。

猜你喜欢

转载自blog.csdn.net/u011510825/article/details/85394592