美文网首页
Redis实现排行榜

Redis实现排行榜

作者: 钟离惜 | 来源:发表于2020-11-06 00:44 被阅读0次

ZSet有序集合

redis的有序集合与集合一样也是String类型元素的集合,不允许有重复的元素。
每一个元素都会关联一个double类型的分数,redis正是通过分数来为集合中的成员进行从小到大的排序。
有序集合中的成员是唯一的,但是分数可以重复。
集合是通过哈希表实现的,集合中的最大元素是2的32次方减1。Zset是有序且不重复的。

注意:默认排序从小到大。

ZSet命令

1、赋值
127.0.0.1:6379> zadd rank 90 c++ 80 java 70 php 60 lua
(integer) 4

创建了一个key(名字)为rank的排行版。

2、修改分数
127.0.0.1:6379> zincrby rank 10 c++
"10"
3、通过索引区间返回指定区间内的成员
127.0.0.1:6379> zrange rank 0 -1
1) "lua"
2) "php"
3) "java"
4) "c++"
127.0.0.1:6379> zrange rank 0 1
1) "lua"
2) "php"
4、通过索引区间返回指定区间内的成员及分数
127.0.0.1:6379> zrange rank 0 -1 withscores
1) "lua"
2) "60"
3) "php"
4) "70"
5) "java"
6) "80"
7) "c++"
8) "90"
5、从大到小查询
127.0.0.1:6379> zrevrange rank 0 1 withscores
1) "c++"
2) "90"
3) "java"
4) "80"
6、获取成员数量
127.0.0.1:6379> zcard rank
(integer) 4
7、计算指定区间分数的成员数
127.0.0.1:6379> zcount rank 80 90
(integer) 2

注意这个最小分数和最大分数都是闭区间。

8、返回指定成员的索引(排名)
127.0.0.1:6379> zrank rank c++
(integer) 3
127.0.0.1:6379> zrevrank rank c++
(integer) 0

zrank是从小到大的排名,zrevrank 是从大到小的。

9、返回指定分数区间的成员
127.0.0.1:6379> zrangebyscore rank 80 90
1) "java"
2) "c++"
127.0.0.1:6379> zrevrangebyscore rank 90 80 withscores
1) "c++"
2) "90"
3) "java"
4) "80"

zrangebyscore的参数是最低分最高分,zrevrangebyscore 的参数是最高分最低分,同样是闭区间。

10、移除指定域成员
127.0.0.1:6379> zrem rank lua
(integer) 1
127.0.0.1:6379> zrange rank 0 -1
1) "php"
2) "java"
3) "c++"
11、移除给定的排名区间的所有成员
127.0.0.1:6379> zremrangebyrank rank 0 1
(integer) 2
127.0.0.1:6379> zrange rank 0 -1
1) "c++"
12、移除给定分数区间的所有成员
127.0.0.1:6379> zremrangebyscore rank 80 85
(integer) 0
13、移除整个集合排行榜
127.0.0.1:6379> del rank
(integer) 1
127.0.0.1:6379> exists rank
(integer) 0

如何处理分数相同

一般的思路都是采用实际分数和时间戳相组合结合成的最终分数作为存入ZSet的分数。
年月日时分秒xx(2x年)xx(月)xx(日)xx(时)xx(分)xx(秒),这里需要10个十进制位,如果还精确到毫秒,那么需要13个十进制位。
一个int类型最大值是2^31-1(包含±),2,147,483,647,大约是10个十进制位。
一个double类型最大值是2^63-1(包含±),9,223,372,036,854,775,807,大约是19个十进制位。
而ZSet的分数是 64位的有符号长整型,也就是约19个十进制位。

所以去掉毫秒级别13个十进制位的时间戳,还剩6个十进制位,能存储10^6个数据。

有个小问题就是分数是越大排名越靠前,但是时间戳得越小排名越靠前,这里可以采用“实际分数 + 13个9 - 13位时间戳”作为分数。

参考文章
redis:zset(赋值、取值、删除、修改分数)
Redis 排行榜 相同分数根据时间优先排行

相关文章

  • redis实现热搜排行榜及历史搜索记录

    一. 前言 热搜排行榜实现要点: 性能/简单/时效 .redis性能高是公认的, redis的数据结构zset有个...

  • redis3.0.4编译安装

    Redis的应用场景:缓存系统、计数器、排行榜、消息队列、实时系统,基本上社交媒体的功能都可以通过Redis实现。...

  • redis实现排行榜

    1 前言 实现一个排版榜,我们通常想到的就是mysql的order by 简单粗暴就撸出来了。但是这样真的优雅吗?...

  • Redis实现排行榜

    ZSet有序集合 redis的有序集合与集合一样也是String类型元素的集合,不允许有重复的元素。每一个元素都会...

  • 跳跃表python实践

    redis的zset常用场景:统计日活;打赏排行榜;天梯榜等zset底层基于跳跃表实现 跳跃表代码实现,练习版

  • 使用redis实现排行榜

    写在前面 排行榜在很多地方都能使用到,redis的zset可以很方便地用来实现排行榜功能。本文是一个示例。 聊聊 ...

  • 严格排行榜Redis实现

    1 常见排行榜 排行榜主要分为两种,一种是并列排行榜(存在相同排名的情况),一种是严格排行榜(分先后顺序,不存在并...

  • 缓存穿透、雪崩、击穿解决方案

    Redis相关数据结构 Redis List适用场景为:排名、排行榜、近期访问数据列表等业务。Redis Set适...

  • Redis实现实时排行榜

    游戏中存在各种各样的排行榜,比如玩家的等级排名、分数排名等。玩家在排行榜中的名次是其实力的象征,位于榜单前列的玩家...

  • redis实战之使用redis实现排行榜(转)

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

网友评论

      本文标题:Redis实现排行榜

      本文链接:https://www.haomeiwen.com/subject/omnqvktx.html