日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql开启布隆过滤器_海量数据去重之布隆过滤器

發布時間:2023/12/10 数据库 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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开启布隆过滤器_海量数据去重之布隆过滤器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。