第三⽅接⼝超⼤数据获取⽅案(下载-解析-⼊库模式)
需求:
每间隔2个⼩时,定时从亚马逊接⼝获取商家⼴告数据
细则说明:
商家指的是亚马逊商家授权给平台的⽤户。(类似淘宝店)
mysql下载完如何使用亚马逊接⼝指的是亚马逊对外提供数据的公开接⼝。
⼴告数据指的是商家在亚马逊平台添加的⼴告,产⽣的点击率,转化率等⼴告相关数据。
现有问题:
1. 授权商家达到⼀定量级,每2个⼩时需要获取⼤量⼴告数据,存在2个⼩时数据获取不完的问题。
2. 短时间内获取⼤量数据,导致服务内存飙升,导致内存OOM。
⽅案构思:
针对上述需求,我们主要需要攻克两个问题:
1. 如何快速⾼效的获取到亚马逊接⼝数据
2. 如何降低服务内存消耗
我们⽬前的架构如下所⽰:
备注:
⽬前架构主要通过xxl-job、springboot框架实现,通过xxl-job分布式调度框架实现定时发送消息到MQ中,springboot中集成MQ,通过监听MQ,来进⾏消息消费,获取所需数据。
架构问题:
但是随着绑定的商家数量越来越⼤之后,发现⼴告消费服务(springboot)不能在2个⼩时之内,造成严重的消息堆积。
最简单的办法就是增加MQ消费线程,这样就可以加快数据获取速度,but这种⽅案看似解决了上⾯的问题,但是在运⾏⼀段时间后就发现服务cpu飙升、mysql数据库cpu飙升,直接导致服务宕机,服务停⽌。
问题分析:
所以仅仅只是提⾼MQ线程数量肯定是不⾏的,我们需要对架构进⾏优化才能彻底解决这个问题。
我们先来分析当前架构有什么问题?
消息队列中每⼀个消息执⾏动作太多,消耗很长的时间和内存。为什么这么说呢,⾸先服务在消费消息的时候,需要经过如过程:
第⼀步需要从亚马逊获取商家⼴告数据
第⼆步需要解析亚马逊数据,封装成我们⼊库需要的对象
第三步就是将这些⼊库对象插⼊数据库中。
我们从这三个步骤就可以看出来,每⼀步都需要消耗⼀定内存,⽽且步骤没有细分,我们没有办法简单的通过增加线程数来提⾼服务的消费能⼒。
因为从亚马逊获取数据,还会受到服务带宽的限制,但是因为我们⼀个消息执⾏动作过多,没办法将服务的下载带宽利⽤到最⼤。
最后还有⼀个很重要的原因,每⼀个消息的第三步都需要插⼊数据库,这将会导致数据库插⼊操作频繁,我们来设想⼀下,每个1分钟插⼊1w条数据和每隔30分钟插⼊60w数据,哪个效率会更⾼。
分析到这边,我们可以很明显的看出,当前架构问题主要出在:
1. 每⼀个消息消费的执⾏动作过多
2. ⼊库太频繁,且⼊库数据不均匀
3. 服务的职能划分不明显,没办法简单的进⾏横向扩容
4. ⽆法充分的利⽤服务下载带宽,导致下载速度上限低
架构优化:
针对上诉问题分析结果,我们需要做如下的优化:
拆分消息的执⾏⼒度,每⼀个消息只做⼀件事情,提⾼单个消息的执⾏速度。
将需要⼊库的对象先存储到第三⽅缓存中(redis),然后定时进⾏统⼀⼊库操作。
为了提⾼下载带宽的利⽤率,我们可以先将⽂件下载到本地,然后再做其它的处理。
优化之后的架构可以将下载带宽和服务资源发挥到最⼤,因为亚马逊返回的数据IO流(不会耗费内存),所以我们可以开多⼀点的线程来进⾏数据下载(加到服务下载带宽的峰值左右)。⽂件解析速
度⾮常快,但是⼜⽐较耗费内存,所以我们可以设置少⼀点的线程数,最后的统⼀⼊库可以根据mysql服务器的性能来设置线程数量。
这也是今天要给⼤家介绍的下载-解析-⼊库模型,叙述过程虽然简单,但是在模型搭建过程却遇到很多问题,为了⼤家能够少⾛弯路,我下⾯给⼤家分享⼀下搭建⾎泪历程。
搭建巨坑:
下载、解析、⼊库线程参数设置不合理,导致运⾏内存过⼤,服务OOM宕机,第1次卒。。。
没有对IO流进⾏压缩,导致下载的⽂件过⼤,直接怼爆磁盘,服务宕机,第2次卒。。。
没有对已经解析过的⽂件进⾏处理,导致磁盘快速爆满,服务宕机,第3次卒。。
因为⽹络存在不稳定因素,所以存在⼀定损坏的⽂件,解析损坏⽂件出现异常没有处理,导致损坏⽂件没没有及时删除,久⽽久之磁盘饱满,第4次卒。。。
下载速度⼀直上不去,⼀度怀疑是程序问题(问题出现在服务下载带宽上⾯),所以拼命加线程,导致内存飙升,服务宕机,第5次卒。。。
IO下载没有使⽤buffer流缓存,导致下载速度受限,MQ的下载消息堆积,第6次卒。。
使⽤了buffer流缓存,但是缓存的byte设置过⼤,导致服务内存OOM,服务宕机,第7次卒。。。
存⼊redis的数据没有进⾏压缩,导致redis内存溢出,redis服务宕机,第8次卒。。。
统⼀⼊库后,没有及时删除redis缓存数据,导致redis内存溢出,redis服务宕机,第9次卒。。。
没有合并redis删除指令,循环⼤批量删除redis数据,导致redis中cpu飙升,redis服务宕机,第10次卒。。。
redis因外挂掉,导致解析数据全部插⼊失败,没有进⾏错误重试,数据丢失(等同删库跑路),第11次卒。。。
⼊库成功需要推送到⼴告数据统计队列,因为数据没有去重,⼀下次推送上百万的数据,MQ内存溢出,MQ服务宕机,第n次卒。。。
搭建后记:
你以为这样就结束了还早着呢,请童鞋们⼀起思考如下问题
⽂件下载到本地磁盘后,后期如何进⾏分布式扩容
因为⽂件解析插⼊redis缓存、⼊库后删除redis缓存有可能会同时进⾏,那如何保证统⼀⼊库的数据不会缺失解析超⼤⽂件是,如何保证速度和内存
下载、解析、⼊库三个步骤如何进⾏关联,才能保证服务性能和可靠性达到最⼤
未完待续。。。(后记的坑⾃⼰填,哈哈哈)
想要更多⼲货、技术猛料的孩⼦,快点拿起⼿机扫码关注我,我在这⾥等你哦~
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论