布隆過濾器
布隆過濾器(英語:Bloom Filter)是1970年由布隆提出的。它實際上是一個很長的二進制向量和一系列隨機映射函數。元素可以添加到集合中,但不能刪除(計數布魯姆過濾器變體支持刪除);
作用
布隆過濾器可以用於判斷一個元素可能存在或者一定不存在。
參考文章
go-zero 中的實現
go-zero 中基於 redis 實現了布隆過濾器
通過 lua 腳本 setbit 和 getbit
setScript = `
for _, offset in ipairs(ARGV) do
redis.call("setbit", KEYS[1], offset, 1)
end
`
testScript = `
for _, offset in ipairs(ARGV) do
if tonumber(redis.call("getbit", KEYS[1], offset)) == 0 then
return false
end
end
使用
package main
import (
"fmt"
"github.com/zeromicro/go-zero/core/bloom"
"github.com/zeromicro/go-zero/core/stores/redis"
)
func main() {
store := redis.New("localhost:6379")
filter := bloom.New(store, "testbloom", 64)
filter.Add([]byte("kevin"))
filter.Add([]byte("wan"))
fmt.Println(filter.Exists([]byte("kevin")))
fmt.Println(filter.Exists([]byte("wan")))
fmt.Println(filter.Exists([]byte("nothing")))
}
應用場景
- 網頁爬蟲對 URL 去重,避免爬取相同的 URL 地址
- 反垃圾郵件,從數十億個垃圾郵件列表中判斷某郵箱是否垃圾郵箱
- Google Chrome 使用布隆過濾器識別惡意 URL
- Medium 使用布隆過濾器避免推薦給用戶已經讀過的文章
- Google BigTable,Apache HBbase 和 Apache Cassandra 使用布隆過濾器減少對不存在的行和列的查找
- 解決緩存穿透
解決緩存穿透問題
- 預先把數據查詢的主鍵,比如用戶 ID 或文章 ID 緩存到過濾器中。
- 當根據 ID 進行數據查詢的時候,先通過布隆過濾器判斷數據是否存在,如果不存在,則直接返回,這樣就減少觸發後續的數據庫查詢。由於布隆過濾器只能判斷數據可能存在或者一定不存在,所以無法完全解決緩存穿透的問題,但可以將其控制在一個可容忍的範圍內。