新闻点击排行榜系统

根据点击排行榜,将数据显示在引流入口处。

排行榜系统功能:
  1. 收集相关数据
  2. 确定排名规则
  3. 实时性的频率
  4. 可视化显示:在哪儿以什么形式显示,类别管理等等
  5. 更新频率:主动干预,保持新鲜度

技术方案
  1. 新增
  2. 删除:过期与删除
  3. 修改:调整分值
  4. 查询:按类目等进行展示
方案设计
        1、使用mysql + order by + 索引优化

                优点:数据少业务简单时,维护成本低;

                缺点:当数据量大、业务复杂,频繁的查询和更新在Mysql数据库性能降低,高并发情况下,性能会显著降低,多人同时操作时,导致数据不一致,需要采取适当措施保证数据的一致性和正确性。

        2、内存堆方案

        在涉及到多表存储,但是不推荐联表查询的场景下,可以使用优先级队列[java.util.priorityqueue]来动态维护排行榜信息

        日常+考试的分数->在内存中计算->小根堆

                实时性的问题:插入和删除时,会自动排序。如果实时更新,需要考虑并发访问的问题和更新的同步问题,并发的读写会导致性能下降、数据的不一致。

                内存占用:优先级队列需要在内存中维护排行榜的数据结构,对于大规模的排行榜
,特别是数据量较大时,可能会占用较多的内存。如果排行榜持续增长,内存占用可能成为一个问题。

                数据持久化问题:优先级队列是基于内存的数据结构,如果应用程序重启或崩溃,排行榜
数据将丢失。为了实现数据持久化,需要将排行榜数据定期或在特定事
件点保存到持久化存储(如数据库)中。

        3、Redis zset

                使用Redis的有序集合zset实现排行榜:

  •  将新闻的点击次数与新闻title,添加到REDIS的zset中
  • ZADD leaderboard <ViewingFrequency> <keyTitle>     
  • leaderboard 为集合的名称 ,ViewingFrequency 为点击的次数,keyTitle 为新闻的标题
         千万数据性能压测:
  • 使用python插入千万数据:
  • import redis
    
    # Redis连接信息
    redis_host = 'localhost'
    redis_port = 6379
    
    # 生成玩家名称
    def generate_keyTitle(index):
    return "p" + str(index)
    
    # 连接到Redis
    r = redis.Redis(host=redis_host, port=redis_port)
    
    # 批量插入数据
    for i in range(1, 10000001):
    keyTitle = generate_keyTitle(i)
    ViewingFrequency = i
    r.zadd('leaderboard', {keyTitle: ViewingFrequency})
    
    print("数据插入完成。")

  • 查询前100名:
import redis
import time

# Redis连接信息
redis_host = '127.0.0.1'
redis_port = 6379

# 创建Redis客户端
r = redis.Redis(host=redis_host, port=redis_port)

# 测试参数
start_rank = 0
end_rank = 99
num_iterations = 1000

# 执行ZREVRANGE命令并测量性能
total_time = 0

for _ in range(num_iterations):
start_time = time.time()
result = r.zrevrange('leaderboard', start_rank, end_rank, withViewingFrequencys=True)
end_time = time.time()
elapsed_time = end_time - start_time
total_time += elapsed_time

# 打印每次迭代的结果和性能指标
print('Result:', result)
print('Elapsed time:', elapsed_time, 'seconds')

# 打印平均执行时间
average_time = total_time / num_iterations
print('Average time:', average_time, 'seconds')
  • 这样在机器不是很差的情况下,一般的查询结果在1ms左右。可以满足大多数企业的要求。
  • 修改玩家分数 ZADD leaderboard <ViewingFrequency> <keyTitle>
  • 删除玩家分数 ZREM leaderboard <keyTitle>
  • 查找指定玩家的排名和分数 ZREVRANK leaderboard <keyTitle>
方案的优点
  •  Redis的zset集合了MySQL的ORDERBY和内存堆的优点,在大流量、高并发的场景下,推荐优先选取Redis的zset实现排行榜系统。
  • 1、增删改查快速
  • 2、zset是基于内存的数据结构,数据实时更新,可以通过redis的发布与订阅机制,将变动同步给订阅者。
  • 3、zset支持范围查询,也可以查询前多少名
  • 4、redis才用了高效的数据结构和内存管理,可以有效的利用内存。
  • 5、redis可以进行持久化,可以定期或即时的将数据保存到磁盘上进行持久化

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值