• 优化统计服务


    终于把统计服务实现了,测试并发布上线。观察了几天 Redis 的内存开销,访问量大约每天 800 万,基本维持在 150 MB 以下,数据库的压力也有明显下降。

    仔细复盘这个架构,存在一个缺点:由于 Watcher 从 SETPop 一个 Key,Pop 是随机的,所以有可能把新加入SETkeyPop 出来了,而我们的目标是缓存 5 分钟再持久化。

    比如说有篇热门博文,5 分钟之内有上千人阅读了,那么就有可能出现最坏的情况, Watcher 刚好 Pop 了上千次这个 Key,也就需要访问上千次数据库。

    因此我们要改进这个架构,让每篇博文的阅读数统计尽可能的缓存 5 分钟,进一步减少数据库的压力。

    难点是如何缓存 5 分钟。分解一下这个问题,由于SETPop是随机的,所以无法实现准确的缓存5分钟。我们要换一个结构ZSET

    ZSET和 SET 有些相似,不同的地方是:ZSET 的每个成员都有一个常用来排序的得分 Score,我们可以把每个缓存的开始时间的秒钟数当成 Score 进行排序。

    改进之后的架构如下图所示:

    Counter 服务接受到请求之后,根据博文的主键生成一个用于去重的 Key,例如 counter-blog-post-100,去重标志作为 value,尝试插入 SET 集合,如果插入成功,说明是一个有效统计,生成一个用于计数的 Key,例如statistic-blog-post-100,尝试 incr 到 String 中,incr 成功之后,生成一个用于计时的 Key,例如 zcounter-blog-post-100 以及对应的 score, 即此刻的时间的 ticks,插入到 zset 中。

    后台服务定时任务,按序出栈,计算出 Score 对应的时间,判断这个 Key 是不是已经大于 5 分钟,如果大于则按照 Key 取出对应的统计数,再持久化,如果不大于,则停止出栈,等待下一次任务。

    后台任务可以灵活的配置,当高峰时期,就多跑几个任务去出栈持久化。

    这样就是实现了缓存 5 分钟的效果。

    上线之后,观察 Redis 的资源使用情况,发现内存消耗增加了很多,但是对数据库的压力的减轻更明显了,如此实现了我们的目标。

  • 相关阅读:
    人类历史上最智慧的169条警世箴言(句句珠玑,发人深省)
    最负责任的回答
    成大事必须依靠的五种人
    一生的伤痕
    有谁愿意陪我一程
    惜缘
    那朵美丽的格桑花,你是否依然绽放?
    今生今世只等你
    成就一生的15条黄金法则
    遇到困难挫折也不要悲观:每个人生来就是冠军(转)
  • 原文地址:https://www.cnblogs.com/kexxxfeng/p/10842333.html
Copyright © 2020-2023  润新知