話說同誌們在爬取數據的時候如何保存已經訪問過的url和隊列?對於爬取過的url,我使用redis的set來保存,訪問隊列是用list來保存,數據量是直線上升,內存不大,也隻有4g,扛不住。不知道以前的方法是什麼?
ringa_lee2017-04-21 10:59:04
佇列和判斷是否存取我都是用的MySQL,考慮到Redis的持久化特性不是很好,而且當時也沒想過用Redis或其他的,暫時現在用MySQL也沒問題。
具體的做法就是對url的md5值做唯一索引,每次查詢都很快,表結構也簡單。
隊列的話使用的是查表的形式,SQL如下(具體status是表示一些自己定義的狀態):
select * from t_down_task where status = 0 order by id limit 1;
定期刪除已經執行的任務
怪我咯2017-04-21 10:59:04
http://en.wikipedia.org/wiki/Bloom_fi...
4G記憶體可以開很大的BloomFilter了,每個URL只需要幾個比特,URL長度無關。 BloomFilter有一定錯誤率(例如千分之一、百分之一,取決於設定),會導致漏爬一些網頁,但不會重複爬。
如果4G內存開BloomFilter還不夠的話,樓主更需要考慮的問題是怎麼存爬出來的網頁。
ringa_lee2017-04-21 10:59:04
md5的hash儲存在資料量不是很大的時候,存在KV儲存中還是比較可靠的,索引量很大的話,估計不太夠用,就得使用帶空間壓縮的一些特別演算法,比如上面有人提到的bloom filter
也有人把這個演算法儲存用Memcache協定實作了,http://code.google.com/p/mc-bloom-fil...
ringa_lee2017-04-21 10:59:04
這種還是不要用redis來做了,直接用檔案系統
已經採集過的url透過MD5成16進位字串,然後每4個字元作為一層目錄,最後4個字元作為檔案名,檔案內容為空即可
判斷url有沒有採集過,直接把目前url MD5以後,依照上述規則產生檔案路徑,直接判斷檔案路徑是否存在即可。
巴扎黑2017-04-21 10:59:04
頂bloomfilter。可以這樣使用:使用leveldb來儲存url,然後查詢的時候先用bloomfilter擋掉大部分不在庫裡面的的url,這樣應該就差不多了。
lz要爬多少url?如果url非常多,例如上億,有hadoop的話也可以用hadoop做新url和老url的去重,MapReduce很快的