python入門學習篇二十八
阿新 • • 發佈:2022-02-27
https://www.one-tab.com/page/0bEKXW4PQC6yYTPmotOOnw
布隆過濾器
主要用於判斷一個元素是否在一個集合中。假如某個資料集很大 ,比如說在 Mysql 中 ,資料量很大 ,即使加上了索引 ,大量的查詢也會影響效能 (缺頁,底層IO等)而布隆過濾器就是為了解決這種問題 ,
可以看到一個值通過多個 hash 函式在一個 bitmap 中進行 01
賦值 .
查詢某個變數的時候我們只要看看這些點是不是都是 1 就可以大概率知道集合中有沒有它了 - 如果這些點有任何一個 0,則被查詢變數一定不在; - 如果都是 1,則被查詢變數很可能存在 為什麼說是可能存在,而不是一定存在呢?那是因為對映函式本身就是雜湊函式,雜湊函式是會有碰撞的。
詳細的布隆過濾器原理見這篇文章
布隆過濾器特徵
- 一個元素如果判斷結果為存在的時候元素不一定存在,但是判斷結果為不存在的時候則一定不存在。
- 布隆過濾器可以新增元素,但是不能刪除元素。因為刪掉元素會導致誤判率增加。
布隆過濾器實戰
瞭解完布隆過濾器, 我們看一下實戰章節, 有以下場景 :
有一批資料數量在 15w 左右 , 需要定時從外部同步回來篩選出有哪些資料是新增的, 哪些是更新的, 其中資料有兩個欄位一個 (no
和 name
欄位) , 假設 15w 資料都去資料庫一一比對 ,這個過程非常消耗時間 ,當允許少量誤差率的情況下我們使用兩個布隆過濾器
方案流程圖
安裝 redis布隆過濾器
redis: image: redis:5 container_name: redis command: redis-server /conf/redis.conf volumes: - ./mydata/redis/data:/data #資料檔案掛載 - ./mydata/redis/conf/redis.conf:/conf/redis.conf #配置檔案掛載 - ./mydata/redis/conf/sentinel.conf:/conf/sentinel.conf #配置檔案掛載 - ./mydata/redis/bloom/redisbloom.so:/data/redisbloom.so #載入布隆過濾器 - ./mydata/redis/bloom/bankcspn.lua:/data/bankcspn.lua #資料插入過濾器lua指令碼 ports: - 6379:6379
建立 no
的布隆過濾器 :
BF.RESERVE bankCspn 0.00001 160000
然後是插入資料的初始化指令碼
local key ='bankCspn'
redis.call("BF.ADD" , key,"000132800023")
redis.call("BF.ADD" , key,"000998800006")
redis.call("BF.ADD" , key,"001100011002")
redis.call("BF.ADD" , key,"001110012009")
redis.call("BF.ADD" , key,"001110012017")
redis.call("BF.ADD" , key,"001121013007")
redis.call("BF.ADD" , key,"001121013015")
redis.call("BF.ADD" , key,"001121013023")
redis.call("BF.ADD" , key,"001121013031")
redis.call("BF.ADD" , key,"001121013040")
redis.call("BF.ADD" , key,"001121013058")
redis.call("BF.ADD" , key,"001121013066")
redis.call("BF.ADD" , key,"001121013074")
redis.call("BF.ADD" , key,"001121013082")
redis.call("BF.ADD" , key,"001121013099")
.....
建立完了之後長這個樣子 :
後續就是程式碼程式設計的工作了. 一個簡單的實戰就完成了.