部分內容參考這位大神的
在保證一定高效空間效率和一定的出錯率的前提下判斷元素是不是集合中的成員。而存在的錯誤只可能存在於元素位於集合中, 對於元素不存在集合中的情況是不會產生錯誤的情況的。由於存在一定的可能低錯誤,則不適用於「0錯誤」的場合。
如果存在上百萬量的資料的時候,如何判斷集合r中是否已經存在元素x呢,一種在少量資料中很常見的做法就是將所有的資料存入在r中,然後遍歷這個集合判斷元素是否在集合中,這種做法當然可以,但是在大資料的情況下,這樣的方法顯然不適合,如此大的資料顯然會占用很多的記憶體,於是想到將這些元素資料通過md5計算得到較短的字串,雖然短小,但是資料量大,記憶體還是很難受。
可行的方法總是被人想到,那將元素通過hash函式,將元素對映到位陣列上,如果該元素經過雜湊等到的陣列的某一位置1,表示該元素已經存在。
**問題:**hash函式總存在衝突的問題,為減少函式衝突的問題,借鑑universal hash的方法,構造多個hash函式,由此引出
bloom filter的基本思想:如果通過其中的乙個hash值我們得出某元素不在集合中,那麼該元素肯定不在集合中。只有在所有的hash函式告訴我們該元素在集合中時,才能確定該元素存在於集合中。
兩個主要的方法add和membershiptest
public
void
add(key key)
int h= hash.hash(key);
hash.clear();
for(int i =0; iset(h[i]);
}}
public boolean membershiptest(key key)
int h= hash.hash(key);
hash.clear();
for(int i =0; iif(!bits.get(h[i]))
}return
true;
}
原因是如果刪除了乙個元素的置位,則對於其他元素的這一置位也會受到影響。
乙個簡單的改進:使用引用計數,而不是單一的位置1,使用counting bloom filter,就可以支援刪除了。
如何根據輸入個數(n),來選定位陣列m的大小和hash函式的個數k。即hash函式會影響效率。當hash函式個數k=(ln2)*(m/n)時錯誤率最小。在錯誤率不大於e的情況 下,m至少要等於n*lg(1/e) 才能表示任意n個元素的集合。但m還應該更大些,因為還要保證bit陣列裡至少一半為0,則m應 該》=nlg(1/e)*lge ,大概就是nlg(1/e)1.44倍(lg表示以2為底的對數)。
舉個例子我們假設錯誤率為0.01,則此時m應大概是n的13倍。這樣k大概是8個。
具體可以檢視#t2 說得非常詳細呢
假設有2個表需要進行內連線,其中乙個表非常大,另乙個表非常小,這是為了加快處理速度,通常會基於小表建立連線列上的bloom filter,具體的做法就是先建立bloom filter物件,然後將小表連線列上的值都儲存到bloom filter上,然後開始通過mapreduce作業執行內連線。
在map階段,讀取小表的時候直接輸出連線列值為key,以資料為value的鍵值對,在讀取大表的時候,則在輸出前先判定連線列值是否在bloom filter中,如果存在則以同樣的方式輸出,如果不存在則不需要輸出,這樣就很大程度地提高了效率。
在reduce階段,針對每個連線列值連線2個表的元組合並輸出結果。
Bloom Filter 海量資料處理
先來看這樣乙個爬蟲相關問題 檔案a中有10億條url,每條url占用64位元組,機器的記憶體限制是4g,現有乙個url,請判斷它是否存在於檔案a中 爬過的url無需再爬 如果有很多個url需要判斷呢?分析之後我們可以發現,這就是快速query問題,通常查操作居多,寫操作較少。要快速判斷乙個url是否...
海量資料處理之Bloom Filter詳解
本部落格內曾已經整理過十道海量資料處理面試題與十個方法大總結。接下來,本部落格內會重點分析那些海量資料處理的方法,並重寫十道海量資料處理的面試題。如果有任何問題,歡迎不吝指正。謝謝。bloom filter是一種空間效率很高的隨機資料結構,它的 原理是,當乙個元素被加入集合時,通過k個hash函式將...
Bloom Filter 資料結構的應用
應用1 儲存字典。大家可能對於 word 的拼寫檢查功能非常了解,當你拼錯乙個單詞的時候,word 會自動將這個單詞用紅線標註出來。word 的具體工作原理不得而知,但是在另乙個拼寫檢查器 unix spell checkers 這個軟體中用到了 bloom filter。unix spell ch...