布隆過濾器為什麼能對海量資料去重的學習筆記

2021-10-14 18:37:51 字數 3536 閱讀 4053

快取場景:請求資料的時候,server 快取 db

快取穿透:redis, mysql 都沒有資料存在,黑客可以利用此漏洞不斷請求資料導致 mysql 壓力過大,如此以來整個系統陷入癱瘓。

場景:用字串去海量字串庫查詢是否存在

// 這個是擷取 nginx 的紅⿊樹的實現,這段**是 insert 操作中的⼀部分,執⾏完這個函式還需要檢測插⼊節點後是否平衡(主要是看他的⽗節點是否也是紅⾊節點)

// 調⽤ ngx_rbtree_insert_value 時,temp傳的引數為 紅⿊樹的根節點,node傳的引數為待插⼊的節點

void

ngx_rbtree_insert_value

(ngx_rbtree_node_t *temp, ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)

temp =

*p;}

*p = node;

node-

>parent = temp;

node-

>left = sentinel;

node-

>right = sentinel;

ngx_rbt_red

(node);}

// 如果我們插⼊key = 12,如上圖紅⿊樹,12號節點應該在哪個位置? 如果我們要實現插⼊存在的節點變成修改操作,該怎麼改上⾯的函式

void

ngx_rbtree_insert_value_ex

(ngx_rbtree_node_t *temp, ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)

// }-------------add-------------

p =(node-

>key < temp-

>key)

?&temp-

>left :

&temp-

>right;

// 這⾏很重要if(

這兩種都會導致同類hash聚集; 也就是近似值它的 hash 值也近似,那麼它的陣列槽位也相近,形成hash聚集。

另外可以用雙重雜湊解決上面出現的 hash 聚集現象

.net hashtable類的 hash 函式定義如下:

hk

(key)=[

gethash

(key)

+ k *(1

+(((gethash*

(key)

>>5)

+1)&

(hashsize -1)

))]% hashsize;

在 (1+(

((gethash*

(key)

>>5)

+1)&

(hashsize -1)

)) 與 hashsize 互為素數(兩數互為素數表示兩者額公尺有共同的質因子)

hash + k * hash2

執行了 hashsize 次探查後,雜湊表中的每乙個位置都有且只有一次被訪問到,也就是說,對於給定的 key, 對雜湊表中的同一位置不會同時使用 hi 和 hj

同樣,hashtable 中結點儲存了 key 和 value,且沒有要求 key 的大小順序

優點:訪問速度更快;不需要進行字串比較

缺點:需要引入策略避免衝突,儲存效率不高;空間換時間

對於海量資料來說,上面兩種結構都不適合做海量資料去重,記憶體不夠大。所以引入了布隆過濾器

n -- 布隆過濾器中元素的個數,如上圖 只有str1和str2 兩個元素 那麼 n=2

p -- 假陽率,在0-1之間

m -- 點陣圖所佔空間

k -- hash函式的個數

公式如下:

n =c

eil(

m−kl

og(1

−exp⁡(

log(

p)k)

))p=

(1−exp⁡(

−km/

n))k

m=ce

il(n

∗log

(p)l

og(1

2log

2))k

=rou

nd(m

n∗lo

g(2)

)\begin n &= ceil(\frac))}}) \\ p &= (1-\exp(\frac))^k \\ m &= ceil(\frac})})\\ k &= round(\frac*log(2)) \end

npmk​=

ceil

(log

(1−exp(k

log(

p)​)

)−k​

m​)=

(1−exp(m

/n−k

​))k

=cei

l(lo

g(2l

og21

​)n∗

log(

p)​)

=rou

nd(n

m​∗l

og(2))​

// 採⽤⼀個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函式

布隆過濾器

布隆過濾器 bloom filter 是1970年由布隆提出的。它實際上是乙個很長的二進位制向量和一系列隨機對映函式。布隆過濾器可以用於檢索乙個元素是否在乙個集合中。它的優點是空間效率和查詢時間都遠遠超過一般的演算法,缺點是有一定的誤識別率和刪除困難。如果想要判斷乙個元素是不是在乙個集合裡,一般想到...

布隆過濾器

布隆過濾器的概念 如果想要判斷乙個元素是不是在乙個集合裡,一般想到的是將所有元素儲存起來,然後通過比較確定。鍊錶,樹等等資料結構都是這種思路.但是隨著集合中元素的增加,我們需要的儲存空間越來越大,檢索速度也越來越慢 o n o logn 不過世界上還有一種叫作雜湊表 又叫 雜湊表,hash tabl...

布隆過濾器

如果想判斷乙個元素是不是在乙個集合裡,一般想到的是將集合中所有元素儲存起來,然後通過比較確定。鍊錶 樹 雜湊表 又叫雜湊表,hash table 等等資料結構都是這種思路。但是隨著集合中元素的增加,我們需要的儲存空間越來越大。同時檢索速度也越來越慢。bloom filter 是一種空間效率很高的隨機...