基于storm实时热点统计的分布式并行缓存预热解决方案

编程入门 行业动态 更新时间:2024-10-24 14:26:50

基于storm实时<a href=https://www.elefans.com/category/jswz/34/1768365.html style=热点统计的分布式并行缓存预热解决方案"/>

基于storm实时热点统计的分布式并行缓存预热解决方案

缓存冷启动,redis启动后,一点数据都没有,直接就对外提供服务了,mysql就裸奔

(1)提前给redis中灌入部分数据,再提供服务

(2)肯定不可能将所有数据都写入redis,因为数据量太大了,第一耗费的时间太长了,第二根本redis容纳不下所有的数据

(3)需要根据当天的具体访问情况,实时统计出访问频率较高的热数据

(4)然后将访问频率较高的热数据写入redis中,肯定是热数据也比较多,得多个服务并行读取数据去写,并行的分布式的缓存预热

(5)然后将灌入了热数据的redis对外提供服务,这样就不至于冷启动,直接让数据库裸奔了


1、nginx+lua将访问流量上报到kafka中

 

要统计出来当前最新的实时的热数据是哪些,我们就得将商品详情页访问的请求对应的流量,日志,实时上报到kafka中

 

2、storm从kafka中消费数据,实时统计出每个商品的访问次数,访问次数基于LRU内存数据结构的存储方案

 

优先用内存中的一个LRUMap去存放,性能高,而且没有外部依赖

 

否则的话,依赖redis,我们就是要防止redis挂掉数据丢失的情况,就不合适了; 用mysql,扛不住高并发读写; 用hbase,hadoop生态系统,维护麻烦,太重了

 

其实我们只要统计出最近一段时间访问最频繁的商品,然后对它们进行访问计数,同时维护出一个前N个访问最多的商品list即可

 

热数据,最近一段时间,可以拿到最近一段,比如最近1个小时,最近5分钟,1万个商品请求,统计出最近这段时间内每个商品的访问次数,排序,做出一个排名前N的list

 

计算好每个task大致要存放的商品访问次数的数量,计算出大小

 

然后构建一个LRUMap,apachecommons collections有开源的实现,设定好map的最大大小,就会自动根据LRU算法去剔除多余的数据,保证内存使用限制

 

即使有部分数据被干掉了,然后下次来重新开始计数,也没关系,因为如果它被LRU算法干掉,那么它就不是热数据,说明最近一段时间都很少访问了

 

3、每个storm task启动的时候,基于zk分布式锁,将自己的id写入zk同一个节点中

 

4、每个storm task负责完成自己这里的热数据的统计,每隔一段时间,就遍历一下这个map,然后维护一个前3个商品的list,更新这个list

 

5、写一个后台线程,每隔一段时间,比如1分钟,都将排名前3的热数据list,同步到zk中去,存储到这个storm task对应的一个znode中去

 

6、我们需要一个服务,比如说,代码可以跟缓存数据生产服务放一起,但是也可以放单独的服务

 

服务可能部署了很多个实例

 

每次服务启动的时候,就会去拿到一个storm task的列表,然后根据taskid,一个一个的去尝试获取taskid对应的znode的zk分布式锁

 

如果能获取到分布式锁的话,那么就将那个storm task对应的热数据的list取出来

 

然后将数据从mysql中查询出来,写入缓存中,进行缓存的预热,多个服务实例,分布式的并行的去做,基于zk分布式锁做了协调了,分布式并行缓存的预热

热点缓存问题:促销抢购时的超级热门商品可能导致系统全盘崩

溃的场景


当一个商品一时间被多次访问,瞬间变成热门商品,但是之前的hash分发策略会把该商品的所有请求打在同一个nginx,导致宕机。

解决方案:基于nginx+lua+storm的热点缓存的流量分发策略自动降级解决方案

1、在storm中,实时的计算出瞬间出现的热点

某个storm task,上面算出了1万个商品的访问次数,LRUMap

 

频率高一些,每隔5秒,去遍历一次LRUMap,将其中的访问次数进行排序,统计出往后排的95%的商品访问次数的平均值

 

1000

999

888

777

666

50

60

80

100

120

 

比如说,95%的商品,访问次数的平均值是100

 

然后,从最前面开始,往后遍历,去找有没有瞬间出现的热点数据

 

1000,95%的平均值(100)的10倍,这个时候要设定一个阈值,比如说超出95%平均值得n倍,5倍

 

我们就认为是瞬间出现的热点数据,判断其可能在短时间内继续扩大的访问量,甚至达到平均值几十倍,或者几百倍

 

当遍历,发现说第一个商品的访问次数,小于平均值的5倍,就安全了,就break掉这个循环

 

热点数据,热数据,不是一个概念

 

有100个商品,前10个商品比较热,都访问量在500左右,其他的普通商品,访问量都在200左右,就说前10个商品是热数据

 

统计出来

 

预热的时候,将这些热数据放在缓存中去预热就可以了

 

热点,前面某个商品的访问量,瞬间超出了普通商品的10倍,或者100倍,1000倍,热点

 

2、storm这里,会直接发送http请求到nginx上,nginx上用lua脚本去处理这个请求

 

storm会将热点本身对应的productId,发送到流量分发的nginx上面去,放在本地缓存中

 

storm会将热点对应的完整的缓存数据,发送到所有的应用nginx服务器上去,直接放在本地缓存中

 

3、流量分发nginx的分发策略降级

 

流量分发nginx,加一个逻辑,就是每次访问一个商品详情页的时候,如果发现它是个热点,那么立即做流量分发策略的降级

 

hash策略,同一个productId的访问都同一台应用nginx服务器上

 

降级成对这个热点商品,流量分发采取随机负载均衡发送到所有的后端应用nginx服务器上去

 

瞬间将热点缓存数据的访问,从hash分发,全部到一台nginx,变成了,负载均衡发送到多台nginx上去

 

避免说大量的流量全部集中到一台机器,50万的访问量到一台nginx,5台应用nginx,每台就可以承载10万的访问量

 

4、storm还需要保存下来上次识别出来的热点list

 

下次去识别的时候,这次的热点list跟上次的热点list做一下diff,看看可能有的商品已经不是热点了

 

热点的取消的逻辑,发送http请求到流量分发的nginx上去,取消掉对应的热点数据,从nginx本地缓存中,删除





更多推荐

基于storm实时热点统计的分布式并行缓存预热解决方案

本文发布于:2024-03-08 14:47:48,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1721174.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:热点   分布式   缓存   实时   解决方案

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!