有序集合(sorted set)
Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)却可以重复。 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
项目需求
- 几十万游戏玩家,按游戏积分实时排序,取前1000名
解决思路
- 用户积分变动时,向 Redis 中 ZSET 中添加|修改数据
- 使用 Redis 的 ZREVRANGE 方法获取排行榜
具体实现
# 添加用户积分
127.0.0.1:6379> ZADD game_rank_list 100 account_1
127.0.0.1:6379> ZADD game_rank_list 50 account_2
127.0.0.1:6379> ZADD game_rank_list 150 account_3
# 查看用户排序
127.0.0.1:6379> ZREVRANGE game_rank_list 0 999 WITHSCORES
1) "account_3"
2) "150"
3) "account_1"
4) "100"
5) "account_2"
6) "50"
# 修改用户积分
127.0.0.1:6379> ZADD game_rank_list 120 account_2
# 查看用户排序
127.0.0.1:6379> ZREVRANGE game_rank_list 0 999 WITHSCORES
1) "account_3"
2) "150"
3) "account_2"
4) "120"
5) "account_1"
6) "100"
问题
- 如果用户分数相同的话,那排名就会根据用户账号排序,这样就不能按实现谁先达到谁排在前面问题
解决思路
- 时间戳的积分 = 实际积分*10000000000 + (9999999999 – timestamp)
- 但如果同一秒达到相同积分,但也会无法区分排名,这种情况可以不考虑