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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

布隆过滤器及其应用

發(fā)布時(shí)間:2024/1/11 windows 31 coder
生活随笔 收集整理的這篇文章主要介紹了 布隆过滤器及其应用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

什么是布隆過濾器?

布隆過濾器是一種數(shù)據(jù)結(jié)構(gòu),具有快速插入和查找的特性,能確定某個(gè)字符串一定存在或者可能存在。布隆過濾器有著高效的空間利用率,它不存儲(chǔ)具體數(shù)據(jù),只存儲(chǔ)數(shù)據(jù)的關(guān)鍵標(biāo)識(shí),所以占用的空間較小。它的查詢結(jié)果可能會(huì)存在一定誤差,但是誤差總體可控,同時(shí)不支持刪除操作。布隆過濾器的應(yīng)用場景豐富,在任何僅需要知道數(shù)據(jù)是否存在,并不關(guān)心具體數(shù)據(jù)內(nèi)容的場景都可以使用布隆過濾器,例如在網(wǎng)頁爬蟲中URL去重防止重爬、可以應(yīng)用在緩存系統(tǒng)中,避免緩存穿透等問題、在安全領(lǐng)域,也可以使用它來快速判斷一個(gè)請(qǐng)求是否屬于黑名單ip,防止惡意攻擊等。
布隆過濾器擁有的快速插入和查找的特性是否很像散列表?普通散列表一般依賴數(shù)組實(shí)現(xiàn),而布隆過濾器為了節(jié)省空間,使用的Bitmap結(jié)構(gòu),即位圖。

位圖

位圖本質(zhì)上其實(shí)也是散列表的一種實(shí)現(xiàn),不同的是位圖節(jié)省空間體現(xiàn)在它利用二進(jìn)制位存儲(chǔ)數(shù)據(jù)狀態(tài)。我們知道在ASCII編碼中,一個(gè)英文字符占用一個(gè)字節(jié)(Byte),也就是8位(bit)。若是UTF8編碼,中文或者特殊字符可能會(huì)占用更多字節(jié)。例如存在一個(gè)數(shù)組如下:

  Integer[] array = new Integer[5]{0,1,3,5,7};

以上的數(shù)組中,不考慮數(shù)組對(duì)象本身占用的空間,只計(jì)算元素空間,每個(gè)元素若只占8位,存儲(chǔ)這5個(gè)元素就要占用40位。假如用二進(jìn)制位存儲(chǔ)這5個(gè)元素,則只需要8位即可。

如上圖,對(duì)應(yīng)槽位的二進(jìn)制位中,0代表不存在元素,1表示存在元素,當(dāng)我們需要查詢是否存在某個(gè)數(shù)字時(shí),只需要看對(duì)應(yīng)槽位的值是不是1即可,這樣只需要一個(gè)8位空間即可表示0,1,3,5,7這幾個(gè)元素了。

布隆過濾器的原理

上面說過,布隆過濾器是依賴位圖實(shí)現(xiàn)的,它的原理是在位圖的基礎(chǔ)之上,定義了若干個(gè)散列函數(shù)。當(dāng)需要向布隆過濾器中插入數(shù)據(jù)時(shí),首先利用這幾個(gè)散列函數(shù)分別計(jì)算出散列值,并且將位圖上對(duì)應(yīng)槽位的值設(shè)置成1,如果已經(jīng)是1的話就不做任何操作。需要檢查某個(gè)數(shù)據(jù)是否存在時(shí)也是同理,計(jì)算出要檢查的數(shù)據(jù)的多個(gè)散列值,并且檢查位圖中對(duì)應(yīng)槽位是否全都為1,但凡有一位不為1就可以斷定值不存在,都為1的話值可能存在。

為什么是可能存在呢?隨著計(jì)算的數(shù)據(jù)越來越多,查詢的結(jié)果也會(huì)慢慢出現(xiàn)一定幾率誤差。因?yàn)樯⒘泻瘮?shù)存在結(jié)果碰撞的問題,兩個(gè)不同的值通過散列函數(shù)計(jì)算出的結(jié)果有概率相同。所以當(dāng)某個(gè)值即便從來沒有被插入過,通過這多個(gè)散列函數(shù)計(jì)算的出的槽位也可能和之前值相同,所以會(huì)誤判為已存在。為了降低誤差幾率,需要按照具體需求調(diào)整散列函數(shù)的算法\個(gè)數(shù)和位圖大小,確保通過散列函數(shù)計(jì)算出來的槽位足夠均勻分布到位圖上。
布隆過濾器不支持刪除操作,是因?yàn)樵谖粓D中每個(gè)槽位只存在兩種狀態(tài),即0和1。一個(gè)槽位被設(shè)置為1,但無法確定它被多少個(gè)關(guān)鍵字,通過哪些散列函數(shù)設(shè)置了多少次1,只知道它被置為了1,所以無法刪除。

布隆過濾器的應(yīng)用

Google提供的guava工具里面包含了布隆過濾器的實(shí)現(xiàn)。

<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
			<version>30.0-jre</version>
		</dependency>
  public static void main(String[] args) {
        Integer size = 1000000;
        BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(StandardCharsets.UTF_8), size, new Double(0.001));

        for (Integer i = 0; i < size; i++) {
            bloomFilter.put(String.valueOf(i));
        }

        Integer count = 0;
        for (Integer i = size; i < size * 2; i++) {
            if (bloomFilter.mightContain(String.valueOf(i))) {
                count++;
            }
        }

        System.out.println("誤判率:" + count / new Double(size));
    }
誤判率:0.00101

Process finished with exit code 0

測試結(jié)果和我們配置的參數(shù)大致吻合。

緩存穿透問題的產(chǎn)生,是當(dāng)有大量的惡意流量去請(qǐng)求系統(tǒng)中不存在的數(shù)據(jù)時(shí),緩存中沒有對(duì)應(yīng)數(shù)據(jù),導(dǎo)致請(qǐng)求直接去查數(shù)據(jù)庫,使數(shù)據(jù)庫承受壓力。而將布隆過濾器放在緩存之前則可以避免此問題,每當(dāng)有流量來請(qǐng)求數(shù)據(jù)時(shí)會(huì)先在布隆過濾器中查詢,請(qǐng)求是否是系統(tǒng)中的正常數(shù)據(jù),如果是則放行流量去查緩存或數(shù)據(jù)庫,否則直接忽略請(qǐng)求或者執(zhí)行其他處理策略。

總結(jié)

以上是生活随笔為你收集整理的布隆过滤器及其应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。