当前位置: 首页 > article >正文

redis 用来实现排行榜的功能

  1. 简单的用 Redis的 zset 数据结构来 实现。
  @Test
    @DisplayName("实现一个简单的排行榜")
    public void zSetRankingTest() {
        ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();

        // 添加假数据到排行榜
        zSetOperations.add("ranking", "张三", 1500);
        zSetOperations.add("ranking", "李四", 2000);
        zSetOperations.add("ranking", "王五", 1800);
        zSetOperations.add("ranking", "赵六", 1700);
        zSetOperations.add("ranking", "钱吧", 2200);

        // 获取排行榜前3名
        Set<ZSetOperations.TypedTuple<String>> top3 = zSetOperations.reverseRangeWithScores("ranking", 0, 2);
        //打印前三名的数据
        System.out.println("Top 3 Players:");
        for (ZSetOperations.TypedTuple<String> tuple : top3) {
            System.out.println(tuple.getValue() + ": " + tuple.getScore());
        }

        // 获取排行榜最后3名
        Set<ZSetOperations.TypedTuple<String>> bottom3 = zSetOperations.rangeWithScores("ranking", 0, 2);
        //打印后三名的数据
        System.out.println("Bottom 3 Players:");
        for (ZSetOperations.TypedTuple<String> tuple : bottom3) {
            System.out.println(tuple.getValue() + ": " + tuple.getScore());
        }

        // 获取某个玩家的排名
        Long playerRank = zSetOperations.reverseRank("ranking", "李四");
        System.out.println("Player3 Rank: " + (playerRank != null ? playerRank + 1 : "Not found"));

        // 获取排行榜的总人数
        Long totalPlayers = zSetOperations.size("ranking");
        System.out.println("Total Players: " + totalPlayers);
    }
1. 数据采集层
2. 热度计算层
3. 存储层
4. 排行榜服务层
5. API接口层

实时统计关键词的频率,可能需要用哈希表来记录每个关键词的计数。然后排行榜需要实时更新,所以每次有新的搜索或点击事件时,都要更新计数,并且重新排序。不过,如果每次事件都排序整个列表,效率可能不高,特别是数据量大的时候。所以可能需要一个高效的数据结构,比如优先队列(堆),或者定时分批处理。

然后是热度计算。单纯计数可能不够,微博的热搜可能结合了点击量、转发量、评论量,还有时间因素。比如使用衰减函数,让旧的数据权重逐渐降低。或者采用窗口机制,比如统计最近一小时的量。这时候可能需要滑动窗口算法,或者使用时间分片来记录每个时间段的数据,汇总时再合并。

存储方面,如果数据量很大,内存数据库比如Redis可能更合适,因为它支持高效的数据结构和持久化。比如Redis的有序集合(Sorted Set)可以自动排序,非常适合排行榜功能。不过用户要求用Java实现,可能需要考虑是否引入外部存储,或者先用内存处理,后面再考虑扩展。

接着是架构设计。可能需要一个消息队列来处理高并发的事件,比如用户的搜索、点击等行为先发送到消息队列,然后由消费者处理,更新关键词的热度。这样可以解耦,提高系统的吞吐量。Java中可以用Kafka或者RabbitMQ,或者Java自带的BlockingQueue作为简单的队列。

热度计算模块需要接收事件,更新对应的关键词计数。这里要注意线程安全,因为可能有多个事件同时触发更新。可以用ConcurrentHashMap来存储关键词和对应的计数器,或者使用原子类比如AtomicInteger来保证原子性。

排行榜生成模块需要定期(比如每分钟)从存储中取出数据,按热度排序,生成TopN的列表。如果使用堆结构,维护一个大小为N的小根堆,可以高效地维护前N个元素。但要注意,当数据量大时,频繁排序可能影响性能,可以考虑每隔一定时间异步生成排行榜,或者使用缓存。


http://www.kler.cn/a/580828.html

相关文章:

  • Qt 中实现自定义控件子类化
  • scala传递匿名函数简化的原则
  • Android 低功率蓝牙之BluetoothGattCharacteristic详解
  • linux下文件读写操作
  • 探索CAMEL:揭开多智能体系统的神秘面纱
  • upload-labs(1-20)详解(专业版)
  • JVM参数调整
  • Linux——基础IO【3万字大章】
  • 第四次CCF-CSP认证(含C++源码)
  • 构建服务器--在线单词查询
  • Ubuntu 22.04 升级到 Ubuntu 24.04 全流程指南
  • tcc编译器教程6 进一步学习编译gmake源代码
  • Unity2017打包出来后的场景一片红
  • P8630 [蓝桥杯 2015 国 B] 密文搜索--map、substr
  • 大型语言模型为何看不懂电路图:局限性分析
  • OpenHarmony 5.0.0 Release
  • 【算法 C/C++】二维前缀和
  • 蓝桥杯备赛-差分-重新排序
  • 逻辑回归实战——银行贷款案例初步实现
  • MoonSharp 文档四