全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-12 8 分钟 ✍️ juanwangdev

Redis 排行榜与社交功能

Redis的有序集合(ZSet)天然适合排行榜场景,集合(Set)的交并差运算完美支持社交关系计算。

排行榜实现

游戏排行榜

Bash
# 玩家分数写入
ZADD leaderboard 1000 "player1"
ZADD leaderboard 950 "player2"
ZADD leaderboard 900 "player3"
ZADD leaderboard 850 "player4"

# 获取前10名(降序)
ZREVRANGE leaderboard 0 9 WITHSCORES
# 返回:
# 1) "player1"
# 2) "1000"
# 3) "player2"
# 4) "950"

# 获取玩家排名(从0开始)
ZREVRANK leaderboard "player1"
# 返回: 0(第一名)

# 获取玩家分数
ZSCORE leaderboard "player1"
# 返回: "1000"

# 增加分数
ZINCRBY leaderboard 50 "player1"
# player1分数变为1050

多维度排行榜

Bash
# 每日排行榜
ZADD leaderboard:daily:2024:01:01 100 "user:1000"

# 每周排行榜
ZADD leaderboard:weekly:2024:01 500 "user:1000"

# 全局排行榜
ZADD leaderboard:global 10000 "user:1000"

实时更新排行榜

Bash
# 用户完成任务增加积分
ZINCRBY leaderboard:game 100 "user:1000"

# 定时清理过期数据
ZREMRANGEBYSCORE leaderboard:daily:2024:01:01 0 -inf

# 获取分页数据
ZREVRANGE leaderboard 0 20 WITHSCORES  # 前21名
ZREVRANGE leaderboard 21 40 WITHSCORES # 第22-41名

分数范围查询

分数区间查询

Bash
# 查询分数在100-500之间的玩家
ZRANGEBYSCORE leaderboard 100 500 WITHSCORES

# 分页查询
ZRANGEBYSCORE leaderboard 100 500 LIMIT 0 10

# 开区间查询(不含边界)
ZRANGEBYSCORE leaderboard (100 (500

百分比排名

Bash
# 获取总分人数
total = ZCARD leaderboard

# 获取玩家排名
rank = ZREVRANK leaderboard "user:1000"

# 百分比 = rank / total * 100
# 前10%表示排名在0-total*0.1范围内

社交功能实现

用户关注关系

Bash
# 用户关注列表
SADD user:1000:following "user:1001" "user:1002" "user:1003"

# 用户粉丝列表
SADD user:1001:followers "user:1000" "user:1004"

# 检查关注关系
SISMEMBER user:1000:following "user:1001"
# 返回: 1(已关注)

# 关注数量
SCARD user:1000:following

# 取消关注
SREM user:1000:following "user:1001"

共同关注/共同好友

Bash
# 用户A关注的人
SADD user:A:following "user:1" "user:2" "user:3"

# 用户B关注的人
SADD user:B:following "user:2" "user:3" "user:4"

# 共同关注(交集)
SINTER user:A:following user:B:following
# 返回: "user:2", "user:3"

# 存储结果
SINTERSTORE common:user:A:B user:A:following user:B:following

可能认识的人

Bash
# 用户A关注的人
SADD user:A:following "user:1" "user:2" "user:3"

# user:1关注的人
SADD user:1:following "user:A" "user:4" "user:5"

# 推荐:user:1关注的人中A未关注的
SDIFF user:1:following user:A:following
# 返回: "user:4", "user:5"

# 排除自己
SREM result "user:A"

二度关系

Bash
# 用户A的朋友
SADD user:A:friends "user:B" "user:C"

# 用户B的朋友
SADD user:B:friends "user:D" "user:E"

# 用户C的朋友
SADD user:C:friends "user:F"

# 二度朋友:A朋友的共同朋友(排除A)
# 需要多次集合运算实现

社交动态时间线

推模式(写扩散)

Bash
# 用户发布动态
LPUSH timeline:user:1000 "post:500"

# 推送到所有粉丝的时间线
# 粉丝列表
SADD user:1000:followers "user:1001" "user:1002"

# 推送
LPUSH timeline:user:1001 "post:500"
LPUSH timeline:user:1002 "post:500"

# 限制时间线长度
LTRIM timeline:user:1001 0 1000

拉模式(读扩散)

Bash
# 用户关注的人
SMEMBERS user:1000:following
# 返回: "user:1001", "user:1002"

# 从每个关注者拉取动态
LRANGE timeline:user:1001 0 20
LRANGE timeline:user:1002 0 20

# 合并排序(应用层实现)

推拉结合

Bash
- 活跃用户:推模式,直接写入粉丝时间线
- 普通用户:拉模式,关注者主动拉取
- 粉丝少的用户:推模式成本低
- 粉丝多的用户:拉模式避免大量写入

点赞与收藏

点赞功能

Bash
# 文章点赞用户集合
SADD article:500:likes "user:1000"

# 检查点赞状态
SISMEMBER article:500:likes "user:1000"
# 返回: 1(已点赞)

# 点赞数
SCARD article:500:likes

# 取消点赞
SREM article:500:likes "user:1000"

点赞排行榜

Bash
# 按点赞数排序的文章
ZADD articles:hot 100 "article:500" 80 "article:501"

# 增加热度
ZINCRBY articles:hot 10 "article:500"

# 热门文章
ZREVRANGE articles:hot 0 10

实现要点

排行榜设计

text
- 分数选择:整数精度高,浮点有精度问题
- 分数重复:同分数按字典序排列
- 数据清理:定期清理过期排行榜
- 分页优化:使用ZREVRANGE而非全量获取

社交关系设计

text
- 双向存储:同时存following和followers
- 关注上限:限制关注数量避免集合过大
- 集合运算:小集合优先提高效率
- 缓存结果:频繁查询结果可缓存

性能优化

text
# 集合运算优化
SINTER small:set large:set  # 小集合优先

# 分页获取
ZREVRANGE leaderboard 0 20  # 限制返回数量

# 遍历大集合
SSCAN user:1000:following 0 COUNT 100

要点总结

  • ZSet天然适合排行榜,分数排序+排名查询
  • ZREVRANGE降序获取前N名,ZREVRANK获取排名
  • ZINCRBY原子增加分数,实时更新排行榜
  • Set交集(SINTER)实现共同关注,差集(SDIFF)推荐好友
  • 时间线推模式写入扩散,拉模式读取聚合
  • 点赞用Set存储用户ID,SCARD统计数量
  • 关注关系双向存储:following + followers
  • 集合运算小集合优先,大集合用SSCAN遍历

📝 发现内容有误?点击此处直接编辑

← 上一篇 Redis 延迟队列
下一篇 → Redis 消息队列
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库