1. 程式人生 > >初識布隆去重 BloomFilter

初識布隆去重 BloomFilter

關於BloomFilter: Bloom filter 是由 Howard Bloom 在 1970 年提出的二進位制向量資料結構,它具有很好的空間和時間效率,被用來檢測一個元素是不是集合中的一個成員。如果檢測結果為是,該元素不一定在集合中;但如果檢測結果為否,該元素一定不在集合中。因此Bloom filter具有100%的召回率。這樣每個檢測請求返回有“在集合內(可能錯誤)”和“不在集合內(絕對不在集合內)”兩種情況,可見 Bloom filter 是犧牲了正確率以節省空間。

1.應用場景:針對分散式包scrapy_redis使用,一般scarpy框架直接使用內建的去重機制,不建議修改scrapy原始碼配置布隆去重。 作用:針對大量的url,可以提升url的去重量。並且佔用很少的記憶體空間。

2.爬蟲去重方案: ①利用資料庫去重;(資料量少的爬蟲程式),每爬取一個Url地址,都將這個url地址在資料庫中儲存一份,然後在獲取新的url地址時,先查詢一下資料庫中是否已經存在這個url,如果已經存在直接跳過這個url,繼續解析下一個url。這種去重方案每次都要讀寫資料庫(每次都要和本地磁碟進行互動,這種效率相對來說(記憶體)是較低的。) 比如:使用這種方式去重,1億的url要佔用9GB記憶體 100000000(億) * 2bytes*50個字元/1024(KB)/1024(MB)/1024(GB) = 9(GB)

使用記憶體去重;可以大大降低記憶體和磁碟的互動次數,提高去重的效率。如果資料量太大,會佔用過多的記憶體空間。如果使用記憶體進行去重的話,肯定是需要對資料進行加密,加密之後資料的長度會更少,進而佔用更少的記憶體空間。一般加密方法不管原始資料是多長,加密之後的長度都是固定的。

scrapy使用的就是記憶體去重,而且對原始資料進行hash加密。hash加密比md5/base64加密後的資料長度更少,一般hash加密是按照 ‘’位‘’來計算記憶體的。如果使用md5加密可能會佔用3GB的記憶體空間,但是hash加密大概在2GB的記憶體。

使用布隆去重,也是記憶體去重,程式直接從記憶體中讀取資料,比從磁碟中讀取資料要快的多。Bloomfilter是將去重物件對映到幾個記憶體“位”,通過幾個位的 0/1值來判斷一個物件是否已經存在。 在這裡插入圖片描述 比如:使用這種方式去重,1億的url要佔用12MB記憶體 100000000(億) * 1bit/8bytes/1024(KB)/1024(MB)/1024(GB) = 0.0116(GB) = 12MB

然而Bloomfilter執行在一臺機器的記憶體上,不方便持久化(機器down掉就什麼都沒啦),也不方便分散式爬蟲的統一去重。如果可以在Redis上申請記憶體進行Bloomfilter,就能解決這一問題了。

3.布隆去重的配置: ① 去Github上下載布隆去重的包; https://github.com/liyaopinner/BloomFilter_imooc 在這裡插入圖片描述 ?/要進行操作的專案是分散式爬蟲jobbolespider ② 將解壓後的BloomFilter_imooc-master\BloomFilter_imooc-master的py_bloomfilter.py放在scrapy_redis這個分散式的包中。

③python 基於redis實現的bloomfilter依賴mmh3 需要安裝依賴包: pip install mmh3 在這裡插入圖片描述 但是安裝的時候出錯 error: Microsoft Visual C++ 14.0 is required

考慮使用之前的解決辦法,但是去 https://www.lfd.uci.edu/~gohlke/pythonlibs/ 網站上並沒有該包存在,後來在python的官網:https://pypi.python.org/pypi/mmh3/2.0 中發現確實有該包(可能是內容比較新吧)下載後發現時C++的檔案,這個檔案需要你用VC++14.0編譯,然後通過在C++的環境中編譯生成lib檔案,然後對該lib檔案進行安裝即可。 (我這個是32位的) 在這裡插入圖片描述 在這裡插入圖片描述 這樣就好了。 ④使用布隆去重的程式碼,替換scrapy_redis中的程式碼; 主要改動的地方 dupefilter.pydupefilter.py在這裡插入圖片描述 在這裡插入圖片描述 在這裡插入圖片描述 py_bloomfilter.py中 匯入mmh3 import mmh3 在這裡插入圖片描述 4.啟動專案 先開啟redis服務 在這裡插入圖片描述 右擊專案‘debug.py’中‘run’ 在這裡插入圖片描述 這樣專案就跑起來了。