第三方接口超大數據獲取方案(下載-解析-入庫模式)

需求:

每間隔2個小時,定時從亞馬遜接口獲取商家廣告數據

細則說明:

  • 商家指的是亞馬遜商家授權給平臺的用戶。(類似淘寶店)
  • 亞馬遜接口指的是亞馬遜對外提供數據的公開接口。
  • 廣告數據指的是商家在亞馬遜平臺添加的廣告,產生的點擊率,轉化率等廣告相關數據。

現有問題:

  1. 授權商家達到一定量級,每2個小時需要獲取大量廣告數據,存在2個小時數據獲取不完的問題。
  2. 短時間內獲取大量數據,導致服務內存飆升,導致內存OOM。

方案構思:

針對上述需求,我們主要需要攻克兩個問題:

  1. 如何快速高效的獲取到亞馬遜接口數據
  2. 如何降低服務內存消耗

我們目前的架構如下所示:

image

備註:

目前架構主要通過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),然後定時進行統一入庫操作。
  • 爲了提高下載帶寬的利用率,我們可以先將文件下載到本地,然後再做其它的處理。

image

優化之後的架構可以將下載帶寬和服務資源發揮到最大,因爲亞馬遜返回的數據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緩存有可能會同時進行,那如何保證統一入庫的數據不會缺失???
  • 解析超大文件是,如何保證速度和內存???
  • 下載、解析、入庫三個步驟如何進行關聯,才能保證服務性能和可靠性達到最大???

未完待續。。。(後記的坑自己填,哈哈哈)

參考文獻:https://www.cnblogs.com/zhaopanpan/articles/9339784.html

想要更多幹貨、技術猛料的孩子,快點拿起手機掃碼關注我,我在這裏等你哦~

林老師帶你學編程https://wolzq.com

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章