0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

分享一下關(guān)于Linux服務(wù)器開發(fā)中相關(guān)數(shù)據(jù)去重的做法

嵌入式開發(fā)AIoT ? 來源:嵌入式開發(fā)AIoT ? 2023-06-18 17:22 ? 次閱讀

1. 海量數(shù)據(jù)去重的Hash

1.1 背景

● 在使用word文檔時(shí),word如何判斷某個(gè)單詞是否拼寫正確?

網(wǎng)絡(luò)爬蟲程序,怎么讓它不去爬相同的url頁面?

● 垃圾郵件(短信)過濾算法如何設(shè)計(jì)?

● 公安辦案時(shí),如何判斷某嫌疑人是否在網(wǎng)逃名單中?

● 緩存穿透問題如何解決?

5467d778-0db5-11ee-962d-dac502259ad0.png

描述緩存場景,為了減輕落盤數(shù)據(jù)庫(mysql)的訪問壓力,在server端與mysql之間加入一層緩沖數(shù)據(jù)層(用來存放熱點(diǎn)數(shù)據(jù));

緩存穿透發(fā)生的場景是server端向數(shù)據(jù)庫請求數(shù)據(jù)時(shí),緩存數(shù)據(jù)庫(redis)和落盤數(shù)據(jù)庫(mysql)都不包含該數(shù)據(jù),數(shù)據(jù)請求壓力全部涌向落盤數(shù)據(jù)庫(mysql)。

數(shù)據(jù)請求步驟:如上圖2的描述;

發(fā)送原因:黑客利用漏洞偽造數(shù)據(jù)攻擊或者內(nèi)部業(yè)務(wù)bug重復(fù)大量請求不存在的數(shù)據(jù);

解決方法:如上圖3的描述;

1.2 需求

從海量數(shù)據(jù)中查詢某字符串是否存在

1.3 set和map

c++標(biāo)準(zhǔn)庫(STL)中的set和map結(jié)構(gòu)都是采用紅黑樹實(shí)現(xiàn)的,它增刪改查的時(shí)間復(fù)雜度是o(log2n );

圖結(jié)構(gòu)示例:

54873212-0db5-11ee-962d-dac502259ad0.png

對于嚴(yán)格平衡二叉搜索樹(AVL),100w條數(shù)據(jù)組成的紅黑樹,只需要比較20次就能找到該值;對于10億條數(shù)據(jù)只需要比較30次就能找到該數(shù)據(jù);也就是查找次數(shù)跟樹的高度是一致的;

對于紅黑樹來說平衡的黑節(jié)點(diǎn)高度,所以研究次數(shù)需要考慮樹的高度差,最好情況某條樹鏈路全是黑節(jié)點(diǎn),假設(shè)此時(shí)高度為h1,最差情況某條樹鏈路全是黑紅節(jié)點(diǎn)間隔,那么此時(shí)樹高度為2*h1;

在紅黑樹中每一個(gè)節(jié)點(diǎn)都存儲(chǔ)key和val字段,key是用來做比較的字段;紅黑樹并沒有要求key字段唯一,在set和map實(shí)現(xiàn)過程中限制了key字段唯一。我們來看nginx的紅黑樹實(shí)現(xiàn):

//這個(gè)是截取nginx的紅?樹的實(shí)現(xiàn),這段代碼是insert操作中的?部分,執(zhí)?完這個(gè)函數(shù)還
需要檢測插?節(jié)點(diǎn)后是否平衡(主要是看他的?節(jié)點(diǎn)是否也是紅?節(jié)點(diǎn))
//調(diào)?ngx_rbtree_insert_value時(shí),temp傳的參數(shù)為紅?樹的根節(jié)點(diǎn),node傳的參數(shù)為
待插?的節(jié)點(diǎn)
voidngx_rbtree_insert_value(ngx_rbtree_node_t*temp,ngx_rbtree_node_t
*node,
{
ngx_rbtree_node_t**p;
for(;;){
p=(node->keykey)?&temp->left:&temp->right;//這?很重要
if(*p==sentinel){
break;
}
temp=*p;
}
*p=node;
node->parent=temp;
node->left=sentinel;
node->right=sentinel;
ngx_rbt_red(node);
}
//不插?相同節(jié)點(diǎn)如果插?相同讓它變成修改操作此時(shí)紅?樹當(dāng)中就不會(huì)有相同的key了
定時(shí)器key時(shí)間戳
//如果我們插?key = 12,如上圖紅?樹,12號(hào)節(jié)點(diǎn)應(yīng)該在哪個(gè)位置?如果我們要實(shí)現(xiàn)插?存在
的節(jié)點(diǎn)變成修改操作,該怎么改上?的函數(shù)
voidngx_rbtree_insert_value_ex(ngx_rbtree_node_t*temp,ngx_rbtree_node_t
*node,
ngx_rbtree_node_t*sentinel)
{
ngx_rbtree_node_t**p;
for(;;){
//{-------------add-------------
if(node->key==temp->key){
temp->value=node->value;
return;
}
//}-------------add-------------
p=(node->keykey)?&temp->left:&temp->right;//這?很重要
if(*p==sentinel){
break;
}
temp=*p;
}
*p=node;
node->parent=temp;
node->left=sentinel;
node->right=sentinel;
ngx_rbt_red(node);
}

另外set和map的關(guān)鍵區(qū)別是set不存儲(chǔ)val字段;

優(yōu)點(diǎn):存儲(chǔ)效率高,訪問速度高效;

缺點(diǎn):對于數(shù)據(jù)量大且查詢字符串比較長且查詢字符串相似時(shí)將會(huì)是噩夢;

1.4 unordered_map

c++標(biāo)準(zhǔn)庫(STL)中的unordered_map是采?hashtable實(shí)現(xiàn)的;

構(gòu)成:數(shù)組+hash函數(shù);

它是將字符串通過hash函數(shù)?成?個(gè)整數(shù)再映射到數(shù)組當(dāng)中;它增刪改查的時(shí)間復(fù)雜度是o(1);

圖結(jié)構(gòu)示例:

54a751a0-0db5-11ee-962d-dac502259ad0.png

hash函數(shù)的作?:避免插入的時(shí)候字符串的?較;hash函數(shù)計(jì)算出來的值通過對數(shù)組?度的取模

能隨機(jī)分布在數(shù)組當(dāng)中;

hash函數(shù)?般返回的是64位整數(shù),將多個(gè)?數(shù)映射到?個(gè)?數(shù)組中,必然會(huì)產(chǎn)?沖突;

如何選取hash函數(shù)?

選取計(jì)算速度快;

哈希相似字符串能保持強(qiáng)隨機(jī)分布性(防碰撞);

murmurhash1,murmurhash2,murmurhash3,siphash(redis6.0當(dāng)中使?,rust等?多數(shù)語?選?的hash算法來實(shí)現(xiàn)hashmap),cityhash都具備強(qiáng)隨機(jī)分布性;測試地址如下:https://github.com/aappleby/smhasher

負(fù)載因?:數(shù)組存儲(chǔ)元素的個(gè)數(shù)/數(shù)組?度;負(fù)載因?越?,沖突越?;負(fù)載因?越?,沖突越?;

hash沖突解決?案:○ 鏈表法引?鏈表來處理哈希沖突;也就是將沖突元素?鏈表鏈接起來;這也是常?的處理沖突的?式;但是可能出現(xiàn)?種極端情況,沖突元素?較多,該沖突鏈表過?,這個(gè)時(shí)候可以將這個(gè)鏈表轉(zhuǎn)換為紅?樹;由原來鏈表時(shí)間復(fù)雜度 o(n) 轉(zhuǎn)換為紅?樹時(shí)間復(fù)雜度o(log2n) ;那么判斷該鏈表過?的依據(jù)是多少?可以采?超過256(經(jīng)驗(yàn)值)個(gè)節(jié)點(diǎn)的時(shí)候?qū)㈡湵斫Y(jié)構(gòu)轉(zhuǎn)換為紅?樹結(jié)構(gòu);○ 開放尋址法將所有的元素都存放在哈希表的數(shù)組中,不使?額外的數(shù)據(jù)結(jié)構(gòu);?般使?線性探查的思路解決;

當(dāng)插?新元素的時(shí),使?哈希函數(shù)在哈希表中定位元素位置;

檢查數(shù)組中該槽位索引是否存在元素。如果該槽位為空,則插?,否則3;

在 2 檢測的槽位索引上加?定步?接著檢查2;加?定步?分為以下?種:

i+1,i+2,i+3,i+4 ... i+n

i-1^2^ ,i+2^2^ ,i-3^2^ ,1+4^2^ ...這兩種都會(huì)導(dǎo)致同類hash聚集;也就是近似值它的hash值也近似,那么它的數(shù)組槽位也靠近,形成hash聚集;第一種同類聚集沖突在前,第二種只是將聚集沖突延后;另外還可以使用雙重哈希來解決上面出現(xiàn)hash聚集現(xiàn)象:

在.net HashTable類的hash函數(shù)Hk定義如下:Hk(key) = [GetHash(key) + k * (1 + (((GetHash(key) >> 5) + 1) % (hashsize – 1)))] % hashsize在此 (1 + (((GetHash(key) >> 5) + 1) % (hashsize – 1))) 與 hashsize 互為素?cái)?shù)(兩數(shù)互為素?cái)?shù)表示兩者沒有共同的質(zhì)因?);執(zhí)?了 hashsize 次探查后,哈希表中的每?個(gè)位置都有且只有?次被訪問到,也就是說,對于給定的 key,對哈希表中的同?位置不會(huì)同時(shí)使? Hi 和 Hj;

同樣的hashtable中節(jié)點(diǎn)存儲(chǔ)了key和val,hashtable并沒有要求key的??順序,我們同樣可以修改代碼讓插?存在的數(shù)據(jù)變成修改操作;

優(yōu)點(diǎn):訪問速度更快;不需要進(jìn)行字符串比較;

缺點(diǎn):需要引?策略避免沖突,存儲(chǔ)效率不?;空間換時(shí)間;

1.5 總結(jié)

紅?樹和hashtable都不能解決海量數(shù)據(jù)問題,它們都需要存儲(chǔ)具體字符串,如果數(shù)據(jù)量大,提供不了?百G的內(nèi)存;所以需要嘗試探尋不存儲(chǔ)key的?案,并且擁有hashtable的優(yōu)點(diǎn)(不需要?較字符串);

2. 布隆過濾器

定義:布隆過濾器是?種概率型數(shù)據(jù)結(jié)構(gòu),它的特點(diǎn)是?效的插入和查詢,能明確告知某個(gè)字符串?定不存在或者可能存在;

布隆過濾器相?傳統(tǒng)的查詢結(jié)構(gòu)(例如:hash,set,map等數(shù)據(jù)結(jié)構(gòu))更加高效,占?空間更?。坏瞧淙秉c(diǎn)是它返回的結(jié)果是概率性的,也就是說結(jié)果存在誤差的,雖然這個(gè)誤差是可控的;同時(shí)它不支持刪除操作;

組成:位圖(bit數(shù)組)+ n個(gè)hash函數(shù)

54b3ed70-0db5-11ee-962d-dac502259ad0.png

原理:當(dāng)?個(gè)元素加?位圖時(shí),通過k個(gè)hash函數(shù)將這個(gè)元素映射到位圖的k個(gè)點(diǎn),并把它們置為1;當(dāng)檢索時(shí),再通過k個(gè)hash函數(shù)運(yùn)算檢測位圖的k個(gè)點(diǎn)是否都為1;如果有不為1的點(diǎn),那么認(rèn)為不存在;如果全部為1,則可能存在(存在誤差);

54d1c1ba-0db5-11ee-962d-dac502259ad0.png

在位圖中每個(gè)槽位只有兩種狀態(tài)(0或者1),?個(gè)槽位被設(shè)置為1狀態(tài),但不明確它被設(shè)置了多少 次;也就是不知道被多少個(gè)str1哈希映射以及是被哪個(gè)hash函數(shù)映射過來的;所以不?持刪除操作;

在實(shí)際應(yīng)?過程中,布隆過濾器該如何使??要選擇多少個(gè)hash函數(shù),要分配多少空間的位圖,存儲(chǔ)多少元素?另外如何控制假陽率(布隆過濾器能明確?定不存在,不能明確?定存在,那么存在的判斷是有誤差的,假陽率就是錯(cuò)誤判斷存在的概率)?

n--布隆過濾器中元素的個(gè)數(shù),如上圖只有str1和str2兩個(gè)元素那么n=2
p--假陽率,在0-1之間0.000000
m--位圖所占空間
k--hash函數(shù)的個(gè)數(shù)
公式如下:
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));

假定我們選取這四個(gè)值為:n = 4000p = 0.000000001m = 172532k = 30

四個(gè)值的關(guān)系:

54e590b4-0db5-11ee-962d-dac502259ad0.png54fd5ffa-0db5-11ee-962d-dac502259ad0.png5516ecfe-0db5-11ee-962d-dac502259ad0.png

在實(shí)際應(yīng)?中,我們確定n和p,通過上?的計(jì)算算出m和k;也可以在?站上選取合適的值:https://hur.st/bloomfilter

已知k,如何選擇k個(gè)hash函數(shù)?

//采??個(gè)hash函數(shù),給hash傳不同的種?偏移值
//#defineMIX_UINT64(v)((uint32_t)((v>>32)^(v)))
uint64_thash1=MurmurHash2_x64(key,len,Seed);
uint64_thash2=MurmurHash2_x64(key,len,MIX_UINT64(hash1));
for(i=0;i




審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • Linux系統(tǒng)
    +關(guān)注

    關(guān)注

    4

    文章

    588

    瀏覽量

    27262
  • AVL
    AVL
    +關(guān)注

    關(guān)注

    0

    文章

    14

    瀏覽量

    10028
  • STL
    STL
    +關(guān)注

    關(guān)注

    0

    文章

    85

    瀏覽量

    18279
  • Hash算法
    +關(guān)注

    關(guān)注

    0

    文章

    43

    瀏覽量

    7378

原文標(biāo)題:Linux服務(wù)器 | 數(shù)據(jù)去重hash與布隆過濾器

文章出處:【微信號(hào):嵌入式開發(fā)AIoT,微信公眾號(hào):嵌入式開發(fā)AIoT】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    linux服務(wù)器和windows服務(wù)器

    Linux服務(wù)器表現(xiàn)出更好的性能和穩(wěn)定性,因此廣泛應(yīng)用于科學(xué)計(jì)算、大數(shù)據(jù)處理和網(wǎng)絡(luò)服務(wù)器等領(lǐng)域。 另方面,Windows
    發(fā)表于 02-22 15:46

    求教:linux系統(tǒng)和WEB服務(wù)器什么關(guān)系?WEB服務(wù)器和網(wǎng)頁又是什么關(guān)系?

    最近在學(xué)習(xí)arm上linux系統(tǒng)移植以及WEB服務(wù)器,有幾個(gè)問題非常非常困惑,希望大家能幫忙解答一下。1.linux操作系統(tǒng)和web服務(wù)器
    發(fā)表于 10-10 20:20

    如何在linux服務(wù)器上使用hanlp

    `關(guān)于如何在linux服務(wù)器上使用hanlp也有分享過篇,但分享的內(nèi)容與湘笑的這篇還是不同的。此處分享一下湘笑的這篇hanlp在
    發(fā)表于 03-04 10:29

    Linux和Windows的登錄和使用Linux服務(wù)器的方式

    關(guān)于登錄Linux服務(wù)器的方式有很多種,本文重點(diǎn)介紹了Linux和Windows的登錄和使用Linux
    發(fā)表于 07-05 07:54

    探討一下關(guān)于STM32的中斷系統(tǒng)

    大大增加,而且中斷的設(shè)置也更加復(fù)雜。今天就將來探討一下關(guān)于STM32的中斷系統(tǒng)。1 基本概念A(yù)RM Coetex-M3內(nèi)核共支持256個(gè)中斷,其中16個(gè)內(nèi)部中斷,2
    發(fā)表于 08-17 08:29

    探討一下關(guān)于電機(jī)軸承的數(shù)據(jù)

    這篇和大家探討一下關(guān)于電機(jī)軸承的數(shù)據(jù)集電機(jī)軸承的數(shù)據(jù)集目前較多采用的是CWRU(凱斯西儲(chǔ)大學(xué)軸承數(shù)據(jù)中心)這是個(gè)針對于全球?qū)W者的公開
    發(fā)表于 09-08 06:52

    請問一下怎樣安裝種TFTP服務(wù)器

    請問一下怎樣安裝種TFTP服務(wù)器呢?有哪些安裝步驟呢?
    發(fā)表于 12-27 07:25

    基于Linux系統(tǒng)的FTP服務(wù)器的實(shí)現(xiàn)

    為了在Linux系統(tǒng)實(shí)現(xiàn)安全、高效的FTP服務(wù)器,選擇了具有小巧輕快、安全易用等優(yōu)點(diǎn)的服務(wù)器軟件vsftpd。通過對Linux平臺(tái)下FTP
    發(fā)表于 07-24 15:36 ?39次下載

    linuxsamba服務(wù)器搭建配置

    linuxsamba服務(wù)器搭建配置是使用linux開發(fā)系統(tǒng)時(shí)經(jīng)常要配置的步,只有這頻配置好,
    發(fā)表于 03-19 18:59 ?13次下載

    簡單探討一下關(guān)于電線電纜的結(jié)構(gòu)材料的相關(guān)知識(shí)

    是什么?接下來,淇玥高溫線纜小編和大家探討一下關(guān)于電線電纜的結(jié)構(gòu)材料的相關(guān)知識(shí)。 從電線電纜的橫截面來觀察分析不同種類的產(chǎn)品,在結(jié)構(gòu)元件上,總體可以分為導(dǎo)線、絕緣層、屏蔽和護(hù)層以及填充元件和承拉元件,其中導(dǎo)線和
    發(fā)表于 09-10 10:07 ?838次閱讀

    LinuxApache服務(wù)器的安裝和配置

    LinuxApache服務(wù)器的安裝和配置(現(xiàn)代電源技術(shù)的發(fā)展概況)-LinuxApache服務(wù)器
    發(fā)表于 08-31 16:22 ?8次下載
    <b class='flag-5'>Linux</b><b class='flag-5'>下</b>Apache<b class='flag-5'>服務(wù)器</b>的安裝和配置

    如何在linux服務(wù)器打開端口

    有時(shí)我們可能需要在Linux服務(wù)器打開端口或在Linux服務(wù)器的防火墻啟用端口來運(yùn)行特定的應(yīng)
    的頭像 發(fā)表于 10-17 16:22 ?1.2w次閱讀

    如何使用Checkmk監(jiān)控Linux服務(wù)器

    `Checkmk` 是用于監(jiān)控 Linux 服務(wù)器的最常用和用戶友好的應(yīng)用程序之。它可以檢查與您的 Linux 服務(wù)器連接的
    的頭像 發(fā)表于 02-17 10:46 ?1092次閱讀
    如何使用Checkmk監(jiān)控<b class='flag-5'>Linux</b><b class='flag-5'>服務(wù)器</b>?

    服務(wù)器數(shù)據(jù)恢復(fù)-LINUX誤刪除/格式化的數(shù)據(jù)恢復(fù)方案

    服務(wù)器數(shù)據(jù)恢復(fù)環(huán)境: 基于EXT2/EXT3/EXT4/Reiserfs/Xfs文件系統(tǒng)的Linux操作系統(tǒng)。 服務(wù)器故障: LINUX
    的頭像 發(fā)表于 09-15 15:29 ?863次閱讀

    服務(wù)器數(shù)據(jù)恢復(fù)—Linux網(wǎng)站服務(wù)器硬盤出現(xiàn)壞扇區(qū)的數(shù)據(jù)恢復(fù)案例

    服務(wù)器數(shù)據(jù)恢復(fù)環(huán)境: 臺(tái)linux操作系統(tǒng)網(wǎng)站服務(wù)器,該服務(wù)器上部署了幾十個(gè)網(wǎng)站,使用
    的頭像 發(fā)表于 10-09 16:26 ?109次閱讀