上一篇 如何将代码打包部署到storm 集群运行, 主要讲解了如何将代码打包部署到storm 集群运行,本篇主要讲解缓存冷启动带来的问题及解决方案思路。
缓存冷启动
应用部署分析根据上图,我们能知道些什么呢,能看出什么呢???
- 应用系统新版本上线,这时候 redis cluster 集群内存中可能没有数据的,这时候大量请求进去,会导致大量的高并发请求和流量直接打到mysql 中,完蛋,mysql 挂了,redis cluster 集群中也没有数据,这时候整个系统就处于不可用状态
- 应用系统运行过程中,突然 redis cluster 集群挂了,内存中数据也没有了,就算开启了持久化也无法恢复数据,然后集群在故障中重新启动,这时候全部请求同样进入mysql,mysql 也搞挂了,系统同样出于不可用状态
从上面两点看,不管如何,只要redis cluster 集群内存中没有数据,那么大量请求进来,都有可能导致mysql崩溃,从而系统不可以用。
redis cluster 集群启动,没有任何的缓存数据,可以称之为redis缓存冷启动。
缓存冷启动,redis cluster启动后,没有任何数据,就直接对外提供服务了,这是mysql 就相当于裸奔状态。
前几篇笔者提到过,解决冷启动的方案是数据预热
缓存预热
解决方案思路
- redis 启动后,提前给redis 灌入部分数据,然后再给应用提供服务
- 部分数据指的是根据当天具体的访问情况,进行时时统计出访问频率较高的数据(热数据),因为我们不可能将所有数据写入redis,数据量大,灌入数据时间消耗长,而且也没必要
- 热数据会比较多,这时候我们需要多个服务并行进行读写(并行的分布式缓存预热)
- 完成以上数据预热,然后提供对外服务,这样就不会存在redis 冷启动了,从而减少了大部分数据的 mysql 读压力
技术处理思路(结合笔者前面的内容)
- 通过 nginx+lua 将访问流量上报到kafka
统计当前最新的实时的热数据是哪些,我们只需要将商品详情页访问的请求流量日志,实时上报到kafka即可
- 利用storm实时计算能力,从 kafka 中消费上报的流量日志数据,统计出商品对应访问次数
访问次数通过 商品id ,次数 方式存储,可以使用LRUMap的内存数据结构的存储方案,LRUMap 性能高,并且没有外部依赖问题
优先用内存中的一个LRUMap去存放,性能高,而且没有外部依赖(指的是第三方存储,比如redis、hbase、mysql等等)
科普: LRUMap的初始化时需要指定最大集合元素个数,新增的元素个数大于允许的最大集合个数时,则会执行 LRU淘汰算法。所有的元素在LRUMap中会根据最近使用情况进行排序。最近使用的会放在元素的最前面(LRUMap是通过链表来存储元素内容). 所以LRUMap进行淘汰时只需要删除链表最后一个即可(即header.after所指的元素对象)
LRUMap 可以考虑维护一个最多前N个商品的限制,不需要全部的数据(本身LRUMap 就是基于 LRU(least recently used) 算法实现,apache commons collections有开源的实现)
-
每个storm task启动的时候,基于zk分布式锁,将自己的id写入zk同一个节点中
-
每个storm task负责完成自己这里的热数据的统计,每隔一段时间,就遍历一下这个map,然后维护一个前N个商品的list,并更新list
-
启动一个后台线程,每隔一段时间,比如1分钟,都将排名前N的热数据list,同步到zk中去,存储到这个storm task对应的一个znode中
-
启动一个服务(可能有多个实例,分布式并行获取 zk 锁)
去根据storm task列表,拿到taskid,然后拿到zk 中对应的热数据list,最后从mysql 中查询出来,写到缓存中,进行预热
以上就是本章内容,如有不对的地方,请多多指教,谢谢!
为了方便有需要的人,本系列全部软件都在 https://pan.baidu.com/s/1qYsJZfY
下章预告:主要 讲解 nginx+lua 实现请求流量上报kafka
作者:逐暗者 (转载请注明出处)
网友评论