真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

redis緩存穿透怎么理解

本篇內(nèi)容主要講解“redis緩存穿透怎么理解”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“redis緩存穿透怎么理解”吧!

創(chuàng)新互聯(lián)建站主營南樂網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,重慶APP軟件開發(fā),南樂h5重慶小程序開發(fā)搭建,南樂網(wǎng)站營銷推廣歡迎南樂等地區(qū)企業(yè)咨詢

Bloom Filter 概念

布隆過濾器(英語:Bloom Filter)是1970年由一個叫布隆的小伙子提出的。它實際上是一個很長的二進制向量和一系列隨機映射函數(shù)。布隆過濾器可以用于檢索一個元素是否在一個集合中。它的優(yōu)點是空間效率和查詢時間都遠遠超過一般的算法,缺點是有一定的誤識別率和刪除困難。

Bloom Filter 原理

布隆過濾器的原理是,當(dāng)一個元素被加入集合時,通過K個散列函數(shù)將這個元素映射成一個位數(shù)組中的K個點,把它們置為1。檢索時,我們只要看看這些點是不是都是1就(大約)知道集合中有沒有它了:如果這些點有任何一個0,則被檢元素一定不在;如果都是1,則被檢元素很可能在。這就是布隆過濾器的基本思想。

Bloom Filter跟單哈希函數(shù)Bit-Map不同之處在于:Bloom Filter使用了k個哈希函數(shù),每個字符串跟k個bit對應(yīng)。從而降低了沖突的概率。

redis緩存穿透怎么理解

緩存穿透

redis緩存穿透怎么理解

(2)哈希函數(shù)選擇

由預(yù)估數(shù)據(jù)量n以及bit數(shù)組長度m,可以得到一個hash函數(shù)的個數(shù)k:

img

哈希函數(shù)的選擇對性能的影響應(yīng)該是很大的,一個好的哈希函數(shù)要能近似等概率的將字符串映射到各個Bit。選擇k個不同的哈希函數(shù)比較麻煩,一種簡單的方法是選擇一個哈希函數(shù),然后送入k個不同的參數(shù)。

哈希函數(shù)個數(shù)k、位數(shù)組大小m、加入的字符串?dāng)?shù)量n的關(guān)系可以參考Bloom Filters - the math,Bloom_filter-wikipedia

要使用BloomFilter,需要引入guava包:

 
            com.google.guava
            guava
            23.0
 

測試分兩步:

1、往過濾器中放一百萬個數(shù),然后去驗證這一百萬個數(shù)是否能通過過濾器

2、另外找一萬個數(shù),去檢驗漏網(wǎng)之魚的數(shù)量

/**
 * 測試布隆過濾器(可用于redis緩存穿透)
 */
public class TestBloomFilter {

    private static int total = 1000000;
    private static BloomFilter bf = BloomFilter.create(Funnels.integerFunnel(), total);
//    private static BloomFilter bf = BloomFilter.create(Funnels.integerFunnel(), total, 0.001);

    public static void main(String[] args) {
        // 初始化1000000條數(shù)據(jù)到過濾器中
        for (int i = 0; i < total; i++) {
            bf.put(i);
        }

        // 匹配已在過濾器中的值,是否有匹配不上的
        for (int i = 0; i < total; i++) {
            if (!bf.mightContain(i)) {
                System.out.println("有壞人逃脫了~~~");
            }
        }

        // 匹配不在過濾器中的10000個值,有多少匹配出來
        int count = 0;
        for (int i = total; i < total + 10000; i++) {
            if (bf.mightContain(i)) {
                count++;
            }
        }
        System.out.println("誤傷的數(shù)量:" + count);
    }

}

運行結(jié)果:

redis緩存穿透怎么理解

運行結(jié)果表示,遍歷這一百萬個在過濾器中的數(shù)時,都被識別出來了。一萬個不在過濾器中的數(shù),誤傷了320個,錯誤率是0.03左右。

看下BloomFilter的源碼:

public static  BloomFilter create(Funnel funnel, int expectedInsertions) {
        return create(funnel, (long) expectedInsertions);
    }  

    public static  BloomFilter create(Funnel funnel, long expectedInsertions) {
        return create(funnel, expectedInsertions, 0.03); // FYI, for 3%, we always get 5 hash functions
    }

    public static  BloomFilter create(
          Funnel funnel, long expectedInsertions, double fpp) {
        return create(funnel, expectedInsertions, fpp, BloomFilterStrategies.MURMUR128_MITZ_64);
    }

    static  BloomFilter create(
      Funnel funnel, long expectedInsertions, double fpp, Strategy strategy) {
     ......
    }

BloomFilter一共四個create方法,不過最終都是走向第四個??匆幌旅總€參數(shù)的含義:

  1. funnel:數(shù)據(jù)類型(一般是調(diào)用Funnels工具類中的)

  2. expectedInsertions:期望插入的值的個數(shù)

  3. fpp 錯誤率(默認值為0.03)

  4. strategy 哈希算法(我也不懂啥意思)Bloom Filter的應(yīng)用

在最后一個create方法中,設(shè)置一個斷點:

redis緩存穿透怎么理解

上面的numBits,表示存一百萬個int類型數(shù)字,需要的位數(shù)為7298440,700多萬位。理論上存一百萬個數(shù),一個int是4字節(jié)32位,需要481000000=3200萬位。如果使用HashMap去存,按HashMap50%的存儲效率,需要6400萬位。可以看出BloomFilter的存儲空間很小,只有HashMap的1/10左右

上面的numHashFunctions,表示需要5個函數(shù)去存這些數(shù)字

使用第三個create方法,我們設(shè)置下錯誤率:

private static BloomFilter bf = BloomFilter.create(Funnels.integerFunnel(), total, 0.0003);

再運行看看:

redis緩存穿透怎么理解

當(dāng)錯誤率設(shè)為0.0003時,所需要的位數(shù)為16883499,1600萬位,需要12個函數(shù)

和上面對比可以看出,錯誤率越大,所需空間和時間越小,錯誤率越小,所需空間和時間約大

常見的幾個應(yīng)用場景:

  • cerberus在收集監(jiān)控數(shù)據(jù)的時候, 有的系統(tǒng)的監(jiān)控項量會很大, 需要檢查一個監(jiān)控項的名字是否已經(jīng)被記錄到db過了, 如果沒有的話就需要寫入db.

  • 爬蟲過濾已抓到的url就不再抓,可用bloom filter過濾

  • 垃圾郵件過濾。如果用哈希表,每存儲一億個 email地址,就需要 1.6GB的內(nèi)存(用哈希表實現(xiàn)的具體辦法是將每一個 email地址對應(yīng)成一個八字節(jié)的信息指紋,然后將這些信息指紋存入哈希表,由于哈希表的存儲效率一般只有 50%,因此一個 email地址需要占用十六個字節(jié)。一億個地址大約要 1.6GB,即十六億字節(jié)的內(nèi)存)。因此存貯幾十億個郵件地址可能需要上百 GB的內(nèi)存。而Bloom Filter只需要哈希表 1/8到 1/4 的大小就能解決同樣的問題。

到此,相信大家對“redis緩存穿透怎么理解”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!


文章名稱:redis緩存穿透怎么理解
轉(zhuǎn)載來源:http://weahome.cn/article/ipjsjs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部