Counting Bloom Filter 是一個 使用計數的 Bloom Filter,它可以 儲存元素 並支援 元素的過期處理。
這個過濾器適用於需要 高效存儲大量資料、查詢是否存在的場景,並且 允許對已過期的元素進行清理。
go get github.com/POABOB/counting-bloom-filter你可以使用 NewCountingBloomFilter 或 NewDefaultCountingBloomFilter 來創建一個新的 Counting Bloom Filter。
package main
import (
"fmt"
"time"
bloom "github.com/POABOB/counting-bloom-filter"
)
func main() {
// 創建一個大小為 1MB 的 Counting Bloom Filter,並且每 30 秒定期刪除 1/10 的元素
cbf := bloom.NewCountingBloomFilter(1 * 1024 * 1024, bloom.WithExpiryDuration(bloom.LAZY_EXPIRATION, 30 * time.Second))
// 添加元素
cbf.Add("item1")
cbf.Add("item2")
// 檢查元素是否存在
fmt.Println(cbf.Check("item1")) // true
fmt.Println(cbf.Check("item2")) // true
fmt.Println(cbf.Check("item3")) // false
}package main
import (
"fmt"
bloom "github.com/POABOB/counting-bloom-filter"
)
func main() {
// 使用預設的大小和設置創建 Counting Bloom Filter
cbf := bloom.NewDefaultCountingBloomFilter()
// 添加元素
cbf.Add("item1")
cbf.Add("item2")
// 檢查元素是否存在
fmt.Println(cbf.Check("item1")) // true
fmt.Println(cbf.Check("item2")) // true
fmt.Println(cbf.Check("item3")) // false
}Add(item string):將元素item添加到 Counting Bloom Filter 中。Check(item string) bool:檢查元素item是否在 Bloom Filter 中。若元素已過期或不存在,將返回false。Remove(item string):從 Bloom Filter 中移除元素item。RemoveAll():從 Bloom Filter 中移除所有元素。
Bloom Filter 的 假陽性命中率 (False Positive Rate, FPR) 是指過濾器 錯誤地判斷元素存在的機率。根據設計,FPR 會受到以下因素的影響:
Bloom Filter 的 bit 大小 m。哈希函數的次數 K。插入的元素數量 n。
根據這些因素,我們可以計算 FPR。假設:
- 使用
12次哈希函數(K = 12)。 - 假設平均元素數量是
33,333。 - bit 大小為
1MB(即1024 * 1024位元)。
在這種配置下,布隆過濾器的 FPR 可以通過以下公式計算:
FPR ≈ (1 - e^(-K * n / m))^K
在這種配置下,經過計算,FPR 約為 0.00000165(即 1.65e-06),這代表在平均插入 33,333 個元素的情況下,FPR 非常低。
所以,可以透過 n (平均插入元素數量) 來調整 m (bit 大小),以達到最佳的性能和精確度。
如果希望達到 1.65e-06 的錯誤率且 平均元素有 100 萬個,建議 m = 1_000_000 * 30,m 設定為 30MiB 會比較好。
m:預設大小為1MB(1024 * 1024位元),這在存儲大約 33,333 個元素的情況下,FPR 為0.00000165。K:預設使用12次哈希函數,這可以保證即使在高並發的情況下,FPR 依然保持在合理範圍。
你可以在創建 CountingBloomFilter 時傳入自定義選項來控制過濾器的行為,例如過期策略、清理間隔時間等。
NO_EXPIRATION:不過期。LAZY_EXPIRATION:模擬延遲過期(通過減少計數器來實現過期),每次會減少 1/10 的元素。RESET_EVERY_PERIOD:定期重設所有元素的計數器。EXPIRY_DURATION:基於時間的過期策略,當元素過期時將被移除,記憶體使用量較大,GB級別資料量不建議使用。
例如,若你想設置自定義的過期策略和清理時間間隔,可以這樣配置:
package main
import (
bloom "github.com/POABOB/counting-bloom-filter"
)
opts := bloom.WithExpiryDuration(bloom.LAZY_EXPIRATION, 60 * time.Second))
cbf := bloom_filter.NewCountingBloomFilter(1 * 1024 * 1024, opts)