-
安裝使用
- rebloom作爲插件安裝 centos安裝rebloom
- docker安裝:
// 拉取鏡像 docker pull redislabs/rebloom // 後臺運行,映射到本地6380端口 docker run -d -p 6380:6379 redislabs/rebloom // 連接 redis-cli -p 6380
-
布隆過濾器的主要命令和誤判
- bf.add: 語法:[bf.add key value] 返回1添加成功
- bf.exists: 語法:[bf.exists key value] 返回1表示存在
- madd, mexists是添加和判斷多個value
當布隆過濾器說某個值存在時,這個值可能不存在;當它說不存在時,那就肯定不存在。
-
基本使用
// 連接redis操作 conn, err := redis.Dial("tcp", "127.0.0.1:6380") HandlecError(err, "connect") defer func() { _ = conn.Close() }() // 測試redis的布隆過濾器 res, err := conn.Do("bf.add", "reBloom", "user100") fmt.Println(res, err) res2, err2 := conn.Do("bf.exists", "reBloom", "user1") fmt.Println(res2, err2)
-
go測試誤判小實驗
// 每次生成不同的key testKey := uuid.NewV4().String() // 對已經添加進布隆過濾器的他肯定是能判斷出來是存在的(res=1) for i := 1; i < 100000 ; i++ { _, _ = conn.Do("bf.add", testKey, "user" + strconv.Itoa(i)) res, _ = conn.Do("bf.exists", testKey, "user" + strconv.Itoa(i)) if res.(int64) == 0{ fmt.Println(i) break } } // 測試結果: 不會誤判 // 對於沒添加進布隆過濾器的,他可能會誤判爲存在(res=1) for i := 1; i < 100000 ; i++ { _, _ = conn.Do("bf.add", testKey, "user" + strconv.Itoa(i)) res, _ = conn.Do("bf.exists", testKey, "user" + strconv.Itoa(i + 1)) if res.(int64) == 1{ fmt.Println(i) break } } // 測試結果: i=310就誤判了
布隆過濾器可以自定義參數,需要我們在 add 之前使用 bf.reserve 指令顯式創建。如果對應的 key 已經存在,bf.reserve 會報錯。bf.reserve 有三個參數: 分別是 key, error_rate 和 initial_size。錯誤率越低,需要的空間越大。initial_size 參數表示預計放 入的元素數量,當實際數量超出這個數值時,誤判率會上升。
- 布隆過濾器的原理
- 布隆過濾器的數據結構裏面就是一個大型的位數組和幾個不一樣的無偏(把元素的 hash值算得比較均勻) hash函數, 對每個key都進行多次的hash
- 向布隆過濾器中添加 key 時,會使用多個 hash 函數對 key 進行 hash 算得一個整數索引值, 然後對位數組長度進行取模運算得到一個位置,每個 hash 函數都會算得一個不同的位置。再把位數組的這幾個位置都置爲1 就完成了 add 操作。
- 向布隆過濾器詢問 key 是否存在時,跟 add 一樣,也會把 hash 的幾個位置都算出來,看看位數組中這幾個位置是否都位 1… 只要有一個位爲 0,那麼說明布隆過濾器中這個 key不存在。如果都是 1,這並不能說明這個key 就一定存在,只是極有可能存在,因爲這 些位被置爲 1 可能是因爲其它的 key 存在所致。
- 布隆過濾器的應用場景
- 推薦內容的去重
- 爬蟲URL去重
- 郵箱系統的垃圾郵件過濾