美文网首页
缓存冷启动问题与缓存预热解决方案

缓存冷启动问题与缓存预热解决方案

作者: sknfie | 来源:发表于2020-09-30 14:29 被阅读0次

    概述

    缓存冷启动就是缓存中没有数据,由于缓存冷启动一点数据都没有,如果直接就对外提供服务了,那么并发量上来mysql就裸奔挂掉了。
    因此需要通过缓存预热的方案,提前给 redis 灌入部分数据后再提供服务。

    缓存冷启动场景

    系统第一次上线启动,或者系统在 redis 故障的情况下重新启动,这时在高并发的场景下就会出现所有的流量 都会打到 mysql(原始数据库) 上去,导致 mysql 崩溃。


    缓存冷启动
    • 新系统第一次上线,此时在缓存里是没有数据的。
    • 系统在线上稳定运行着,但是突然redis 缓存崩了,而且不幸的是,数据全都无法找回来。

    缓存预热解决方案

    1.缓存预热问题

    • 数据量太大的话,无法将所有数据放入 redis 中:耗费时间过长或 redis 根本无法容纳下所有的数据;
    • 需要根据当天的具体访问情况,实时统计出访问频率较高的热数据;
    • 将访问频率较高的热数据写入 redis 中,肯定数据也比较多, 我们也得多个服务并行读取数据去写,并行的分布式缓存预热。

    2.缓存预热大致思路

    • nginx +lua 将访问流量上报到 kafka 中,统计出当前最新的实时的热数据,将商品详情页访问的请求对应的流量日志实时上报到 kafka 中;
    • storm 从 kafka 中消费数据,实时统计访问次数;
    • 访问次数基于 LRU 内存数据结构的存储方案。

    由于storm 中读写数据频繁,并且数据量大,需要采用LRU 内存架构:
    这种场景不适合采用 redis 或者 mysql:

    • redis 可能会出现故障,会影响 storm 的稳定性;
    • mysql扛不住高并发读写;
    • hbase:hadoop 生态组合还是不错的,但是维护太重了;
      实际场景就是:统计出最近一段时间访问最频繁的商品,进行访问计数, 同时维护出一个前 N 个访问最多的商品 list 即可。
    • 也就是热数据:最近一段时间(如最近 1 小时、5 分钟),1 万个商品请求, - 统计这段时间内每个商品的访问次数,排序后做出一个 top n 列表。
    • 计算好每个 task 大致要存放的商品访问次数的数量,计算出大小, 然后构建一个 LRU MAP,它能够给你一个剩下访问次数最多的商品列表,访问高的才能存活。
      LRU MAP 有开源的实现,apach commons collections 中有提供,设置好 map 的最大大小, 就会自动根据 LRU 算法去剔除多余的数据,保证内存使用限制, 即时有部分数据被干掉了,下次会从 0 开始统计,也没有关系,因为被 LRU 算法干掉了, 就表示它不是热数据,说明最近一段时间都很少访问了,热度下降了。

    3.分布式并行缓存预热解决方案

    • 每个 Storm task 启动时,基于 zk 分布式锁,将自己的 ID 写入 zk 同一个节点中:
      这个 id 写到一个固定节点中,形成一个 task id 列表, 后续可以通过这个 id 列表去拿到对于 task 存储在 zk node 上的 topn 列表。
    • 每个 Storm task 负责完成自己这里的热数据统计。
      比如每隔一段时间,就遍历下这个 map,维护并更新一个前 n 个商品的 list。
    • 定时同步到 zk 中去。
      写一个后台线程,每隔一段时间,比如 1 分钟,将这个 task 所有的商品排名算一次 将排名前 n 的热数据 list 同步到 zk 中去。
    • 需要一个服务,根据 top n 列表在 mysql 中获取数据往 redis 中存
      这个服务有会部署多个实例,在启动时会拉取 storm task id 列表, 然后通过 zk 分布式锁,基于 id 去加锁,获取到这个 task id 节点中存储的 topn 列表, 然后读取 mysql 中的数据,存储在 redis 中。
      这个服务可以是单独的服务,也可以放在缓存服务中。

    总结

    冷启动是说缓存中没有数据但是缓存短时间又恢复正常后的流量被大量打到 mysql。
    那么通过缓存预热来解决缓存冷启动问题:

    • 使用 stom 实时计算出最近一段时间内的 n 个 topn 列表,并存储在 zk task id 节点上。
    • 多服务通过 task id 进行分布式锁,获取 topn 列表,去 mysql 拉取数据放入 redis 中。
      利用storm 创建大量并行的 task 和数据分组策略, 让大量的访问日志分发到 n 个 task 中,让 storm 这种抗住大量并发访问量的计算能力, 这里是计算出 n 个 topn 列表,也就是大量的热数据。而不是唯一的一份 topn 列表, 而且是最近一段时间内的(通过这种分而治之方式 + 分段时间来重复计算自己负责的部分结果数据实现的)。

    相关文章

      网友评论

          本文标题:缓存冷启动问题与缓存预热解决方案

          本文链接:https://www.haomeiwen.com/subject/qfgeuktx.html