一、缓存预热node
缓存冷启动,redis启动后,一点数据都没有,直接就对外提供服务了,mysql就裸奔mysql
(1)提早给redis中灌入部分数据,再提供服务
(2)确定不可能将全部数据都写入redis,由于数据量太大了,第一耗费的时间太长了,第二根本redis容纳不下全部的数据
(3)须要根据当天的具体访问状况,实时统计出访问频率较高的热数据
(4)而后将访问频率较高的热数据写入redis中,确定是热数据也比较多,咱们也得多个服务并行读取数据去写,并行的分布式的缓存预热
(5)而后将灌入了热数据的redis对外提供服务,这样就不至于冷启动,直接让数据库裸奔了nginx
二、nginx+lua将访问流量上报到kafka中redis
要统计出来当前最新的实时的热数据是哪些,咱们就得将商品详情页访问的请求对应的流量,日志,实时上报到kafka中算法
三、storm从kafka中消费数据,实时统计出每一个商品的访问次数,访问次数基于LRU内存数据结构的存储方案sql
优先用内存中的一个LRUMap去存放,性能高,并且没有外部依赖数据库
我以前作过的一些项目,不光是这个项目,还有不少其余的,一些广告计费类的系统,stormapache
不然的话,依赖redis,咱们就是要防止redis挂掉数据丢失的状况,就不合适了; 用mysql,扛不住高并发读写; 用hbase,hadoop生态系统,维护麻烦,过重了缓存
其实咱们只要统计出最近一段时间访问最频繁的商品,而后对它们进行访问计数,同时维护出一个前N个访问最多的商品list便可数据结构
热数据,最近一段时间,能够拿到最近一段,好比最近1个小时,最近5分钟,1万个商品请求,统计出最近这段时间内每一个商品的访问次数,排序,作出一个排名前N的list
计算好每一个task大体要存放的商品访问次数的数量,计算出大小
而后构建一个LRUMap,apache commons collections有开源的实现,设定好map的最大大小,就会自动根据LRU算法去剔除多余的数据,保证内存使用限制
即便有部分数据被干掉了,而后下次来从新开始计数,也不要紧,由于若是它被LRU算法干掉,那么它就不是热数据,说明最近一段时间都不多访问了
四、每一个storm task启动的时候,基于zk分布式锁,将本身的id写入zk同一个节点中
五、每一个storm task负责完成本身这里的热数据的统计,每隔一段时间,就遍历一下这个map,而后维护一个前3个商品的list,更新这个list
六、写一个后台线程,每隔一段时间,好比1分钟,都将排名前3的热数据list,同步到zk中去,存储到这个storm task对应的一个znode中去
七、咱们须要一个服务,好比说,代码能够跟缓存数据生产服务放一块儿,可是也能够放单独的服务
服务可能部署了不少个实例
每次服务启动的时候,就会去拿到一个storm task的列表,而后根据taskid,一个一个的去尝试获取taskid对应的znode的zk分布式锁
若是能获取到分布式锁的话,那么就将那个storm task对应的热数据的list取出来
而后将数据从mysql中查询出来,写入缓存中,进行缓存的预热,多个服务实例,分布式的并行的去作,基于zk分布式锁作了协调了,分布式并行缓存的预热