[爬蟲架構] 如何設計一個分散式爬蟲架構

海的鄰居發表於2018-05-01

前言:

    在大型爬蟲專案中,使用分散式架構是提高爬取效率的唯一途徑。設計一個合理的分散式架構對專案、對個人都有很大的好處,接下來說說分散式架構應該具有的特性:

  1. 分散式。這是最基本也是最核心的特性,分散式將允許我們通過橫向擴充套件主機資源來提高爬取效率。
  2. 易擴充套件、易部署。當我們想要增加要爬取的網站時,只需要專注於爬取規則、解析規則、入庫規則部分的程式碼編寫就ok,其他的如日誌、異常處理則讓底層架構實現。
  3. 各功能高度模組化。模組化有利於架構的鬆耦合,以至於以後想要新增新的功能無需進行大的改動;同時也使得整個架構更清晰簡明。
  4. 可監控。通過架構部署啟動爬蟲之後,可以通過某種方式監控Request佇列實時大小、已入庫的Item條數,以確認爬蟲工作狀態。
  5. 高效能。即使在單機上部署此架構也能充分利用主機CPU、頻寬等資源,比較耗時的主要是下載頁面和入庫兩個環節,當Request佇列不斷增長的時候,消費Request的能力也必須跟上,否則佇列會消耗過多記憶體資源,且爬取效率低。入庫同理,這兩個環節都是IO密集型任務,所以恰好可以利用python的多執行緒來提高效率。
  6. Request佇列、去重集合的持久化,實現斷點續爬和增量爬取。

詳細說明:

     架構圖如下:



下圖為爬蟲執行的流程模型:


    架構主要分兩部分,下載器(Downloader)和提取器(Extractor)。下載器專注於資料的下載,可為下載器配置UA池或fake_useragent、cookie池、代理IP池(需要本地維護),不會做任何資料處理任務,下載成功後將資料寫入Redis中定義好的Response List,並將用於下載的Request寫入Dupefilter;提取器就會從Response List中拉取Response進行解析,不同網站使用不同key儲存List。這裡使用Redis作為Response中轉是因為當執行的下載器數量較多時,返回大量的Response不一定能被提取器及時解析入庫(資料庫儲存量達到一定級別後,磁碟IO可能大於網路IO),若放在記憶體中可能由於程式意外停止而丟失已經下載的Response(未入庫)。

    Dupefilter:使用BloomFilter可以有效節省去重集合對記憶體的消耗,取Redis中的256M字串可對9000萬條Url進行去重,漏失率為1.12e-04,漏失率和去重Url的數量關係可參考基於Redis的Bloomfilter去重,也就是說漏失率是可以控制的。

    Request Queue:此佇列可採用Redis的List或Zset資料型別實現,前者實現FIFO和LIFO佇列,後者實現PRORI佇列

    Downloader和Extractor都可以分散式部署,只需配置好Redis服務的網路地址。兩者的多執行緒部署有助於充分利用單機的頻寬資源,CPU利用率提升可能不明顯,爬蟲始終是偏IO密集型的活動。

   Request和Response:Request物件可作為一個字典來存,字典包含請求的url、cookie、headers、body、params、method以及others屬性,Response也作為一個字典,包含下載到的html、cookies、headers、url以及others屬性;這會有利於複雜頁面的抓取。


宣告:本文章為個人對技術的理解與總結,不保證100%正確,接收網友的斧正。

個人設計思想,轉載請註明出處!(https://blog.csdn.net/sc_lilei/article/details/80160346)

相關文章