mysql开启布隆过滤器_海量数据去重之布隆过滤器
背景
在使?word?檔時,word如何判斷某個單詞是否拼寫正確?
?絡爬?程序,怎么讓它不去爬相同的url???
垃圾郵件(短信)過濾算法如何設計?
公安辦案時,如何判斷某嫌疑?是否在?逃名單中?
緩存穿透問題如何解決?
先來看一個場景,假如我們的數據庫使用的是 mysql,緩存使用 redis。
server
redis
mysql
數據讀取步驟是這樣的:
先訪問 redis ,如果數據存在直接返回;如果不存在則進行步驟 2;
訪問 mysql ,如果數據不存在,直接返回;如果存在則進行步驟 3;
將 mysql 中存在的 key 寫回 redis;
出現的問題: 如果 redis 和 mysql 中都沒有相應的數據,此時又有大量的該數據的請求(偽造數據攻擊),最終的壓力還是會全部涌向 mysql。這就是所謂的 緩存穿透。
解決方案:
在 redis 端設置 鍵值對,以避免訪問 mysql。當然缺點是如果 過多時會占用過多的內存。我們可以給 key 設置過期時間,比如 exoire key 600ms, 停止攻擊后最終由 redis 自動清除這些無用的 key ;
在 server 端設置一個布隆過濾器,將 mysql 中包含的 key 放入布隆過濾器中;布隆過濾器能過濾一定不存在的數據。
布隆過濾器
假設我么你現在提出一個需求:從海量數據中查詢某字符串是否存在。
在 c++ 中我們首先想到的應該是使用 STL 中的 set 或者 map。
set 和 map
c++ 標準庫(STL)中的 set 和 map 結構都是采?紅?樹實現的,它增刪改查的時間復雜度是:
o
(
l
o
g
2
n
)
o(log_{2}n)o(log2?n)
對于嚴格平衡?叉搜索樹(AVL),100w 條數據組成的紅?樹,只需要?較20次就能找到該值;對于10億條數據只需要?較30次就能找到該數據;也就是查找次數跟樹的?度是?致的;
對于紅?樹來說平衡的是?節點?度,所以研究?較次數需要考慮樹的?度差,最好情況某條樹鏈路全是?節點,假設此時?度為 h1,最差情況某條樹鏈路全是?紅節點間隔,那么此時樹?度為 2*h1;
在紅?樹中每?個節點都存儲 key 和 val 字段,key 是?來做?較的字段;紅?樹并沒有要求 key 字段唯?,在 set 和 map 實現過程中限制了 key 字段唯?。
另外 set 和 map 的關鍵區別是 set 不存儲 val 字段;
優點:存儲效率?,訪問速度?效;
缺點:對于數據量?且查詢字符串?較?且查詢字符串相似時將會是噩夢;
unordered_map
c++ 標準庫(STL)中的 unordered_map 是采? hashtable 實現的;
構成:數組 + hash 函數;
它是將字符串通過 hash 函數?成?個整數再映射到數組當中;它增刪改查的時間復雜度是 o(1);
hash 函數的作?:避免插?的時候字符串的?較;hash函數計算出來的值通過對數組?度的取模能隨機分布在數組當中;
hash 函數?般返回的是 64 位整數,將多個?數映射到?個?數組中,必然會產?沖突;
如何選取 hash 函數?
選取標準:
選取計算速度快;
哈希相似字符串能保持強隨機分布性(防碰撞);
murmurhash1,murmurhash2,murmurhash3,siphash( redis6.0 當中使?,rust 等?多數語?選?的 hash 算法來實現 hashmap),cityhash 都具備強隨機分布性;測試地址如下:https://github.com/aappleby/smhasher
負載因?:數組存儲元素的個數/數組?度;負載因?越?,沖突越?;負載因?越?,沖突越?;
hash沖突解決?案
鏈表法
引?鏈表來處理哈希沖突;也就是將沖突元素?鏈表鏈接起來;這也是常?的處理沖突的?式;但是可能出現?種極端情況,沖突元素?較多,該沖突鏈表過?,這個時候可以將這個鏈表轉換為紅?樹;由原來鏈表時間復雜度 o(n) 轉換為紅?樹時間復雜度 ;那么判斷該鏈表過?的依據是多少?可以采?超過256(經驗值)個節點的時候將鏈表結構轉換為紅?樹結構;
開放尋址法
將所有的元素都存放在哈希表的數組中,不使?額外的數據結構;?般使?線性探查的思路解決;
當插?新元素的時,使?哈希函數在哈希表中定位元素位置;
檢查數組中該槽位索引是否存在元素。如果該槽位為空,則插?,否則進行第 3 步;
在第 2 步檢測的槽位索引上加?定步?接著檢查第 2 步;
加?定步?分為以下?種:
i+1,i+2,i+3,i+4 ... i+n
i- ,i+ ,i- ,1+ ...
這兩種都會導致同類 hash 聚集;也就是近似值它的 hash 值也近似,那么它的數組槽位也靠近,形成 hash 聚集;第?種同類聚集沖突在前,第?種只是將聚集沖突延后;
另外還可以使?雙重哈希來解決上?出現 hash 聚集現象。
在 .net HashTable 類的 hash 函數 Hk 定義如下:
Hk(key) = [GetHash(key) + k * (1 + (((GetHash(key) >> 5) + 1) %(hashsize – 1)))] % hashsize
在此 (1 + (((GetHash(key) >> 5) + 1) % (hashsize – 1))) 與 hashsize互為素數(兩數互為素數表示兩者沒有共同的質因?);執?了 hashsize 次探查后,哈希表中的每?個位置都有且只有?次被訪問到,也就是說,對于給定的 key,對哈希表中的同?位置不會同時使? Hi 和 Hj。
具體原理:https://www.cnblogs.com/organic/p/6283476.html
同樣的 hashtable 中節點存儲了 key 和 val,hashtable 并沒有要求 key 的??順序,我們同樣可以修改代碼讓插?存在的數據變成修改操作;
優點:訪問速度更快;不需要進?字符串?較;
缺點:需要引?策略避免沖突,存儲效率不?;空間換時間;
總結
紅?樹和 hashtable 都不能解決海量數據問題,它們都需要存儲具體字符串,如果數據量?,提供不了?百 G 的內存;所以需要嘗試探尋不存儲 key 的?案,并且擁有 hashtable 的優點(不需要?較字符串);
布隆過濾器
布隆過濾器是?種概率型數據結構,它的特點是?效的插?和查詢,能明確告知某個字符串?定不存在或者可能存在;相?傳統的查詢結構(例如:hash,set,map等數據結構)更加?效,占?空間更?;但是其缺點是它返回的結果是概率性的,也就是說結果存在誤差的,雖然這個誤差是可控的;同時它不?持刪除操作;
組成:位圖(bit 數組)+ n 個 hash 函數
原理:當?個元素加?位圖時,通過 k 個 hash 函數將這個元素映射到位圖的 k 個點,并把它們置為 1;當檢索時,再通過 k 個 hash 函數運算檢測位圖的 k 個點是否都為 1;如果有不為 1 的點,那么認為不存在;如果全部為1,則可能存在(存在誤差);
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ahhhbjn3-1610794049644)(原理.png)]
在位圖中每個槽位只有兩種狀態(0 或者 1),?個槽位被設置為 1 狀態,但不明確它被設置了多少次;也就是不知道被多少個 str1 哈希映射以及是被哪個 hash 函數映射過來的;所以不?持刪除操作;
在實際應?過程中,布隆過濾器該如何使??要選擇多少個 hash 函數,要分配多少空間的位圖,存儲多少元素?另外如何控制假陽率(布隆過濾器能明確?定不存在,不能明確?定存在,那么存在的判斷是有誤差的,假陽率就是錯誤判斷存在的概率)?
n -- 布隆過濾器中元素的個數,如上圖 只有str1和str2 兩個元素 那么 n=2
p -- 假陽率,在0-1之間 0.000000
m -- 位圖所占空間
k -- hash函數的個數
公式如下:
n = ceil(m / (-k / log(1 - exp(log(p) / k))))
p = pow(1 - exp(-k / (m / n)), k)
m = ceil((n * log(p)) / log(1 / pow(2, log(2))));
k = round((m / n) * log(2));
假定我們選取這四個值為:
n = 4000
p = 0.000000001
m = 172532
k = 30
四個值的關系:
在實際應?中,我們確定 n 和 p,通過上?的計算算出 m 和 k;也可以在?站上選取合適的值:https://hur.st/bloomfilter
已知 k,如何選擇 k 個 hash 函數?
// 采??個hash函數,給hash傳不同的種?偏移值
// #define MIX_UINT64(v) ((uint32_t)((v>>32)^(v)))
uint64_t hash1 = MurmurHash2_x64(key, len, Seed);
uint64_t hash2 = MurmurHash2_x64(key, len, MIX_UINT64(hash1));
for (i = 0; i < k; i++) // k 是hash函數的個數
{
Pos[i] = (hash1 + i*hash2) % m; // m 是位圖的??
}
// 通過這種?式來模擬 k 個hash函數 跟我們前?開放尋址法 雙重hash是?樣的思路
總結
以上是生活随笔為你收集整理的mysql开启布隆过滤器_海量数据去重之布隆过滤器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 离线网页 HTML+CSS+DIV
- 下一篇: KVM学习笔记