1. 程式人生 > >解決Scrapy效能問題——案例四(響應太多導致溢位)

解決Scrapy效能問題——案例四(響應太多導致溢位)

症狀:下載器幾乎是在滿負荷工作,然後過一會就關閉了。然後一直重複這樣,而scaper佔用的記憶體很多。

示例:這裡我們和之前的設定是一樣的(也使用了treq),但是響應的大小被設定成了120kb的HTML。正如你所看到的,它一共花費了31s而不是20s:

$ time scrapy crawl speed -s SPEED_TOTAL_ITEMS=1000 -s
SPEED_T_RESPONSE=0.25 -s SPEED_API_T_RESPONSE=1 -s
SPEED_PIPELINE_API_VIA_TREQ=1 -s SPEED_DETAIL_EXTRA_SIZE=120000
s/edule d/load scrape p/line done mem
952
16 32 32 0 3842818 917 16 35 35 32 4203080 876 16 41 41 67 4923608 840 4 48 43 108 5764224 805 3 46 27 149 5524048 ... real 0m30.611s

討論:我們可能簡單地把這些延遲為花費了更多的時間來建立、轉移或者處理網頁。但是實際上並不是這樣,對於所有Response物件的總的大小在寫本書的時候有一個硬性的限制max_active_size = 5000000。每個Response物件被假定它們的大小與它裡面的HTML程式碼大小相等,並且最小是1kb。

這裡寫圖片描述

這裡一個非常重要的細節是,這個限制或者是Scrapy用以保證爬蟲和pipeline執行速度的最微妙最必要的機制。如果你的任何一個pipeline的吞吐量小於下載器的吞吐量,那麼這種現象就最終會發生。當pipeline處理時間比較長的時候,即使是小的Response

物件也會導致突破限制值。

解決方案:基於現有的框架基礎,我們能做的事情不多。所有能做的就是減少pipeline的處理時間以減少scraper中的Response物件的數目。對此可以使用傳統的優化方法:檢查你與之互動的web api或者資料庫能否支撐你的scraper的吞吐量,把scraper的功能簡單化,以及把一些複雜的功能從pipeline中移到批處理/後處理系統中,或者使用效能更好的伺服器或分散式地抓取。