5.數(shù)據(jù)量龐大時如何去重和泌?

1.布隆過濾器

我們平時刷今日頭條村缸,今日頭條會給我們推薦新的內(nèi)容,它每次推薦時要去重武氓,去掉那些已經(jīng)看過的內(nèi)容梯皿。問題來了,如何實現(xiàn)推送去重呢县恕?

下意識會想到东羹,我們在數(shù)據(jù)庫里記錄好給用戶推薦過的新聞,每次給用戶推薦前忠烛,我們先去記錄表里查一下百姓,看是否推薦過。

存在問題:當數(shù)據(jù)量和并發(fā)量都很高時况木,數(shù)據(jù)庫扛不住

此時有小伙伴會說垒拢,那我存redis里,存redis里當數(shù)據(jù)量大時火惊,會占用大量空間求类,也不是一個好的方案。

布隆過濾器可以理解為一個不怎么精確的 set 結構屹耐,當你使用它的 contains 方法判斷某個對象是否存在時尸疆,它可能會誤判。但是布隆過濾器也不是特別不精確惶岭,只要參數(shù)設置的合理寿弱,它的精確度可以控制的相對足夠精確,只會有小小的誤判概率按灶。

當布隆過濾器說某個值存在時症革,這個值可能不存在;當它說不存在時鸯旁,那就肯定不存在噪矛。

布隆過濾器能準確過濾掉那些已經(jīng)看過的內(nèi)容,那些沒有看過的新內(nèi)容铺罢,它也會過濾掉極小一部分(誤判)艇挨,但是絕大多數(shù)新內(nèi)容它都能準確識別。這樣就可以完全保證推薦給用戶的內(nèi)容都是無重復的韭赘。

Redis 官方提供的布隆過濾器到了 Redis 4.0 提供了插件功能之后才正式登場缩滨。布隆過濾器作為一個插件加載到 Redis Server 中,給 Redis 提供了強大的布隆去重功能。

2.基本使用

bf.add 添加元素脉漏,bf.exists 查詢元素是否存在蛋勺。

布隆過濾器插件安裝

[root@izuf65itgtxe1lpfpb***** redis]# git clone https://github.com/RedisBloom/RedisBloom.git
[root@izuf65itgtxe1lpfpb***** redis]# cd RedisBloom/
[root@izuf65itgtxe1lpfpb***** RedisBloom]# make
[root@izuf65itgtxe1lpfpb***** RedisBloom]# vi /usr/local/redis/redis.conf 
## 增加配置
loadmodule /usr/local/redis/RedisBloom/redisbloom.so
## 重啟redis就行
127.0.0.1:6379> bf.add bloomFilterKey user1
(integer) 1
127.0.0.1:6379> bf.add bloomFilterKey user2
(integer) 1
127.0.0.1:6379> bf.exists bloomFilterKey user2
(integer) 1
127.0.0.1:6379> bf.exists bloomFilterKey user3
(integer) 0

3.原理

添加元素時,先把value轉化為字節(jié)(getBytes(value,”UTF-8"))鸠删,通過算法對元素計算出k(14)個獨立的hash值,然后用這k個獨立的hash值與位圖長度( 201978)進行取余贼陶,對應位置設置1刃泡。

判斷元素是否存在,對元素計算出k個獨立的hash值碉怔,然后用這k個獨立的hash值與位圖長度(201978)進行取余烘贴,所有的位置都是1表示存在,只要有一位為0都是不存在撮胧。

使用時不要讓實際元素遠大于初始化大小桨踪,當實際元素開始超出初始化大小時,應該對布隆過濾器進行重建芹啥,重新分配一個 size 更大的過濾器锻离,再將所有的歷史元素批量 add 進去(這就要求我們在其它的存儲器中記錄所有的歷史元素)。 因為 error_rate 不會因為數(shù)量超出就急劇增加墓怀,這就給我們重建過濾器提供了較為寬松的時間汽纠。

為什么會存在誤差?

因為這個位置為1傀履,有可能是其他key設置的

建議:使用時不要讓實際元素遠大于初始化大小虱朵,當實際元素開始超出初始化大小時,應該對布隆過濾器進行重建钓账,重新分配一個 size 更大的過濾器碴犬,再將所有的歷史元素批量 add 進去(這就要求我們在其它的存儲器中記錄所有的歷史元素)。因為 error_rate 不會因為數(shù)量超出就急劇增加梆暮,這就給我們重建過濾器提供了較為寬松的時間服协。

注意:位圖長度越長錯誤率越低,但是需要很大的空間啦粹,一般這里都是用預計放入元素量蚯涮,當實際數(shù)量超出這個值時,誤判率會上升

錯誤率計算器:https://krisives.github.io/bloom-calculator/

4.實戰(zhàn)

還是用最開始我們說的需求卖陵,實現(xiàn)新聞推送去重遭顶,假設需求需要我們保證100%的正確率,我們該如何優(yōu)化呢泪蔫?

我們需要設計兩層校驗棒旗,第一層是布隆過濾器,第二層是MySQL。

public void exist(String data) {
  // 數(shù)據(jù)是否存在
  boolean existFlag = false;
  // 1.先去布隆過濾器判斷
  if(bloomFilter.exist(data)) {
    // 2.如果布隆過濾器存在铣揉,需要在MySQL中進行二次校驗
    if(mysqlService.exist(data)) {
      // 3.數(shù)據(jù)存在
      existFlag = true;
    }
  }
  return existFlag;
}

public void insertRecord() {
  // 1.先插入布隆過濾器
  // 2.插入到數(shù)據(jù)庫
}

有些同學說饶深,我的Redis版本低于4.0怎么辦?

我們可以使用redis位圖自己實現(xiàn)一個布隆過濾器

</br>

布隆過濾器使用場景:

  • 黑名單
  • 爬蟲逛拱,爬網(wǎng)頁前先判斷url是否已經(jīng)爬過敌厘,若爬過就不再爬取
  • 緩存穿透
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市朽合,隨后出現(xiàn)的幾起案子俱两,更是在濱河造成了極大的恐慌,老刑警劉巖曹步,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宪彩,死亡現(xiàn)場離奇詭異,居然都是意外死亡讲婚,警方通過查閱死者的電腦和手機尿孔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來筹麸,“玉大人活合,你說我怎么就攤上這事∥锔希” “怎么了芜辕?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長块差。 經(jīng)常有香客問我侵续,道長,這世上最難降的妖魔是什么憨闰? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任状蜗,我火速辦了婚禮,結果婚禮上鹉动,老公的妹妹穿的比我還像新娘轧坎。我一直安慰自己,他們只是感情好泽示,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布缸血。 她就那樣靜靜地躺著,像睡著了一般械筛。 火紅的嫁衣襯著肌膚如雪捎泻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天埋哟,我揣著相機與錄音笆豁,去河邊找鬼。 笑死,一個胖子當著我的面吹牛闯狱,可吹牛的內(nèi)容都是我干的煞赢。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼哄孤,長吁一口氣:“原來是場噩夢啊……” “哼照筑!你這毒婦竟也來了?” 一聲冷哼從身側響起瘦陈,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤凝危,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后双饥,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡弟断,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年咏花,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片阀趴。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡昏翰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出刘急,到底是詐尸還是另有隱情棚菊,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布叔汁,位于F島的核電站统求,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏据块。R本人自食惡果不足惜码邻,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望另假。 院中可真熱鬧像屋,春花似錦、人聲如沸边篮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽戈轿。三九已至凌受,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間思杯,已是汗流浹背胁艰。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人腾么。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓奈梳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親解虱。 傳聞我的和親對象是個殘疾皇子攘须,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容