专栏名称: 码小辫
给程序员和编程爱好者分享计算机编程电子书以及相关的学习资源
目录
相关文章推荐
知乎日报  ·  长篇创作冲刺中!来为你心中的宝藏作者打 Call ·  10 小时前  
知乎日报  ·  参加 2025 年高考是种什么样的体验? ·  10 小时前  
九章算法  ·  Meta招聘软件工程师,年薪$21.3w-$ ... ·  昨天  
九章算法  ·  Meta猛发offer!杀疯了! ·  2 天前  
51好读  ›  专栏  ›  码小辫

排行榜的 5 种方案!

码小辫  · 公众号  ·  · 2025-05-11 10:00

正文

请到「今天看啥」查看全文


@Scheduled(fixedRate = 60000// 每分钟执行一次
public void updateRankingCache() {
    List rankings = userScoreDao.getTop1000Scores();
    redisTemplate.opsForValue().set("ranking_list", rankings);
}

public List getRankingList() {
    return (List) redisTemplate.opsForValue().get("ranking_list");
}

优点

  • 减轻数据库压力
  • 查询速度快(O(1))
  • 实现相对简单

缺点

  • 数据有延迟(取决于定时任务频率)
  • 内存占用较高
  • 排行榜更新不及时

架构图如下

方案三:Redis有序集合

适用场景 :数据量大(百万级),需要实时更新

Redis的有序集合(Sorted Set)是实现排行榜的利器。

示例代码如下:

public void addUserScore(String userId, double score) {
    redisTemplate.opsForZSet().add("ranking", userId, score);
}

public List getTopUsers(int topN) {
    return redisTemplate.opsForZSet().reverseRange("ranking"0, topN - 1);
}

public Long getUserRank(String userId) {
    return redisTemplate.opsForZSet().reverseRank("ranking", userId) + 1;
}

优点

  • 高性能(O(log(N))时间复杂度)
  • 支持实时更新
  • 天然支持分页
  • 可以获取用户排名

缺点

  • 单机Redis内存有限
  • 需要考虑Redis持久化
  • 分布式环境下需要额外处理

架构图如下

方案四:分片+Redis集群

适用场景 :超大规模数据(千万级以上),高并发场景

当单机Redis无法满足需求时,可以采用分片方案。

示例代码如下:

// 
public void addUserScore(String userId, double score) {
    RScoredSortedSet set = redisson.getScoredSortedSet("ranking:" + getShard(userId));
    set.add(score, userId);
}

private String getShard(String userId) {
    // 简单哈希分片
    int shard = Math.abs(userId.hashCode()) % 16;
    return "shard_" + shard;
}

在这里我们以Redisson客户端为例。

优点







请到「今天看啥」查看全文