• 优化统计服务


    终于把统计服务实现了,测试并发布上线。观察了几天 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 的资源使用情况,发现内存消耗增加了很多,但是对数据库的压力的减轻更明显了,如此实现了我们的目标。

  • 相关阅读:
    JavaWeb-RESTful(一)_RESTful初认识
    【算法】简单题_球弹跳高度的计算
    【算法】简单题_鸡兔同笼问题
    【算法】贪心算法_节目时间安排问题
    SVN_SVN的基本认识
    JavaWeb_(视频网址)_二、用户模块1 注册登陆
    【知识库】-数据库_MySQL性能分析之Query Optimizer
    【知识库】-数据库_MySQL之高级数据查询:去重复、组合查询、连接查询、虚拟表
    【知识库】-数据库_MySQL之基本数据查询:子查询、分组查询、模糊查询
    【知识库】-数据库_MySQL常用SQL语句语法大全示例
  • 原文地址:https://www.cnblogs.com/kexxxfeng/p/10842333.html
Copyright © 2020-2023  润新知