BloomFilter 緩存穿透

需求: BloomFilter 如何防止DB 回源攻擊?

介紹:?

Bloomfilter: 布隆過濾器,?它是由一個(gè)很長的二進(jìn)制向量和一系列隨機(jī)映射函數(shù)組成,布隆過濾器可以用于檢索一個(gè)元素是否在一個(gè)集合中。它的優(yōu)點(diǎn)是空間效率和查詢時(shí)間都遠(yuǎn)遠(yuǎn)超過一般的算法,缺點(diǎn)是有一定的誤識(shí)別率。即Bloom Filter報(bào)告某一元素存在于某集合中,但是實(shí)際上該元素并不在集合中。但是如果某個(gè)元素確實(shí)沒有在該集合中,那么Bloom Filter 是不會(huì)報(bào)告該元素存在于集合中的,所以不會(huì)漏報(bào)。

Bloomfilter 算法邏輯:?

1.??首先需要k個(gè)hash函數(shù),每個(gè)函數(shù)可以把key散列成為1個(gè)整數(shù)?

2.?初始化時(shí),需要一個(gè)長度為n比特的數(shù)組,每個(gè)比特位初始化為0

3.?某個(gè)key加入集合時(shí),用k個(gè)hash函數(shù)計(jì)算出k個(gè)散列值,并把數(shù)組中對(duì)應(yīng)的比特位置為1

4.?判斷某個(gè)key是否在集合時(shí),用k個(gè)hash函數(shù)計(jì)算出k個(gè)散列值,并查詢數(shù)組中對(duì)應(yīng)的比特位,如果所有的比特位都是1,認(rèn)為在集合中

那么需要多少個(gè)K函數(shù)呢? 是不是覺得很神奇。那下面來算一算。K 是hash 函數(shù)的個(gè)數(shù),m 是?位數(shù)組大小。插入元素個(gè)數(shù) n

最優(yōu)的 k 如下

k = (m/n)ln2.

接下來看看緩存:

緩存問題,一共有以下幾類:

1. 緩存穿透: 請(qǐng)求去查詢一條數(shù)據(jù)庫中不存在的數(shù)據(jù),就是數(shù)據(jù)庫和緩存中都不存在,但是請(qǐng)求每次都會(huì)打到數(shù)據(jù)庫上面去。

2. 緩存擊穿: 大量的請(qǐng)求同時(shí)查詢一個(gè)key的時(shí)候,此時(shí)key正好失效,就會(huì)導(dǎo)正大量的請(qǐng)求打到數(shù)據(jù)庫中去

3.緩存雪崩: 某一時(shí)刻發(fā)生大規(guī)模緩存失效的情況, 比如緩存數(shù)據(jù)庫crash掉了,導(dǎo)致大量請(qǐng)求打到數(shù)據(jù)庫,DB撐不住就掛掉了。

4.熱點(diǎn)數(shù)據(jù)失效: 設(shè)置緩存的時(shí)候,一般會(huì)設(shè)置失效時(shí)間,對(duì)于一些熱點(diǎn)數(shù)據(jù),當(dāng)緩存失效的時(shí)候會(huì)存在大量的請(qǐng)求打到數(shù)據(jù)庫中去,從而導(dǎo)致數(shù)據(jù)庫崩掉。

根據(jù)上面·BloomFilter 的介紹,針對(duì)第一個(gè)問題,緩存穿透。可以把存在key的集合都放到BoolmFilter里面,再訪問某個(gè)key的時(shí)候,先會(huì)去BloomFilter 查看有沒有key,存在的話,再去查緩存,緩存沒有再去查DB, BloomFilter 判斷沒有key,就直接返回。?

BloomFilter在時(shí)間和空間上占有優(yōu)勢,但是會(huì)有一定的錯(cuò)誤率。

具體的使用,可以采用guava 的BloomFilter, 很簡單。

private static int size = 1000000;

private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size);

? ? public static void main(String[] args) {

? ? ? ? for (int i = 0; i < size; i++) {

? ? ? ? ? ? bloomFilter.put(i);

? ? ? ? }

? ? ? ? long startTime = System.nanoTime(); // 獲取開始時(shí)間

? ? ? ? //判斷這一百萬個(gè)數(shù)中是否包含29999這個(gè)數(shù)

? ? ? ? if (bloomFilter.mightContain(29999)) {

? ? ? ? ? ? System.out.println("命中了");

? ? ? ? }

? ? ? ? long endTime = System.nanoTime();? // 獲取結(jié)束時(shí)間

? ? ? ? System.out.println("程序運(yùn)行時(shí)間: " + (endTime - startTime) + "納秒");

? ? }

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一.簡述如何安裝配置apache 的一個(gè)開源的hadoop 1.使用root賬戶登陸 2.修改ip 3.修改hos...
    梔子花_ef39閱讀 5,069評(píng)論 0 52
  • Java8張圖 11、字符串不變性 12、equals()方法、hashCode()方法的區(qū)別 13、...
    Miley_MOJIE閱讀 3,899評(píng)論 0 11
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,673評(píng)論 1 32
  • 沁園春《國慶》 作者:柳亞子 華夏神州,萬里河山, 換盡舊顏??达L(fēng)云世界, 五湖四海,巨龍聳立, 上下千年。 春夏...
    劉偉書法_沈陽閱讀 449評(píng)論 0 6
  • 玖月,她是一個(gè)不一樣的女子??梢哉f她是一個(gè)逆襲達(dá)人,總是一次次刷新周圍人對(duì)她的看法。從只能上普通??频某煽?,逆襲到...
    玖月的喵閱讀 164評(píng)論 0 2

友情鏈接更多精彩內(nèi)容