布隆過濾器在redis中的使用


簡介:

布隆過濾器是一種實現去重的思想,不屬於redis,它也可以在其他地方單獨使用。

布隆過濾器也是做去重的,那和Hyperloglog有什么區別.

Hyperloglog用來來估值,有偏差,它里面主要提供了兩個方法:

  1. pfadd
  2. pfcount

       但是沒有判斷是否包含的命令,例如pfexist,pfcontains這樣的命令。舉個例子:在刷進入頭條的時候,每次推送的內容都相似,但都不一樣,那有什么解決方案呢?,可以將每個用戶的瀏覽歷史記錄下來,然后每次推送的時候去判斷,但是這種的在高並發,數據量很大的時候就不適用。因此這里可以使用布隆過濾器去處理。

        bloom Filter:是專門用來做去重操作的,它相比於緩存的話,它不那么浪費空間,但是和Hyperloglog一樣都是不太精確的,但是這個精確度可以自己調節。當數據量小的時候,精確度高一點,占用的空間就多,當數據量很大的時候,可以把精確度調低一點,這樣占用的空間就小一點。

        bloom Filter相當於一個不太精確的set集合,我們可以使用contains方法去判斷某個對象是否存在,但是這個判斷不太精確,當判斷不存在的時候 ,他一定不存在,當判斷它存在的時候,它不一定存在。以今日頭條為例,假設我們將用戶的瀏覽記錄用 B 表示,A 表示用戶沒有瀏覽的新聞,現在要給用戶推送消息,先去 B 里邊判斷這條消息是否已經推送過,如果判斷結果說沒推送過(B 里邊沒有這條記錄),那就一定沒有推送過。如果判斷結果說有推送過(B 里邊也有可能沒有這條消息),這個時候該條消息就不會推送給用戶,導致用戶錯過該條消息。

原理:

     每個布隆過濾器就相當於一個大型的位數組,和幾個不同的hash函數。

      所謂add操作,就是根據幾個不同的hash函數元素進行hash算出一個整數索引值,拿到這個索引值后,對維數組進行取模運算,得到一個位置,每個hash函數都會得到一個位置,將位數組中對應的位置設置為1,這樣就完成添加操作。

      當判斷元素是否存在的時候,依然對元素先進行hash運算,將運算結果和位數組的長度取模,然后在對應的位置查看是否有相應的數據,如果有,表示元素可能存在(因為有可能是其他元素存進來的),如果沒有,那就一定沒有。

      誤判的概率和位數組的大小有關,位數組越大,誤判概率越小,所占用的空間就越大。

安裝:

   安裝完成后,如果 bf.add命令有提示的話,就表示安裝成功。
基本用法:
    主要兩個命令:添加和判斷
bf.add\bf.madd(添加和批量添加)
bf.exists\bf.mexists(判斷和批量判斷)
使用jedis操作布隆過濾器:
1.添加依賴(jrebloom)
2.測試:
public class BloomFilter {
    public static void main(String[] args) {
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        config.setMaxIdle(300);
        config.setMaxTotal(1000);
        config.setMaxWaitMillis(30000);
        config.setTestOnBorrow(true);
        JedisPool pool = new JedisPool(config, "192.168.91.128", 6379, 30000, 
"zl");
        Client client = new Client(pool);
        //存入數據
        for (int i = 0; i < 100000; i++) {
            client.add("name", "zl-" + i);
       }
        //檢查數據是否存在
        boolean exists = client.exists("name", "zl-9999999");
        System.out.println(exists);
   }
}

      默認布隆過濾器的錯誤率是0.01,默認元素的大小為100,當然也可以存超過100個,只不過錯誤率會上升。

這兩個參數可以去配置的:bf.reserve

應用場景:

新聞推送過濾

解決redis穿透,或者緩存擊穿問題

假設我有 1億 條用戶數據,現在查詢用戶要去數據庫中查,效率低而且數據庫壓力大,所以我們會把請
求首先在 Redis 中處理(活躍用戶存在 Redis 中),Redis 中沒有的用戶,再去數據庫中查詢。
現在可能會存在一種惡意請求,這個請求攜帶上了很多不存在的用戶,這個時候 Redis 無法攔截下來請
求,所以請求會直接跑到數據庫里去。這個時候,這些惡意請求會擊穿我們的緩存,甚至數據庫,進而
引起“雪崩效應”。
為了解決這個問題,我們就可以使用布隆過濾器。將 1億條用戶數據存在 Redis 中不現實,但是可以存
在布隆過濾器中,請求來了,首先去判斷數據是否存在,如果存在,再去數據庫中查詢,否則就不去數據庫中查詢。
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM