Redis 4.0的布隆過濾器插件


還沒有安裝Redis的同學,可以參考我先前的文章安裝,傳送門《玩轉Redis-Redis安裝、后台啟動、卸載》。Redis 4.0開始以插件形式提供布隆過濾器。

# docker方式安裝

> docker pull redislabs/rebloom # 拉取鏡像
> docker run -p6379:6379 redislabs/rebloom # 運行容器
> redis-cli # 連接容器中的 redis 服務

# linux服務器直接安裝

>git clone git://github.com/RedisLabsModules/rebloom
>cd rebloom
>make
# 當前路徑會生成一個rebloom.so文件
# 在redis的配置中(通常在/etc/redis/redis.conf)增加一行配置 loadmodule /"rebloom.so的絕對路徑"/rebloom.so
# 重啟Redis即可

   上述的安裝提到需要重啟Redis,但是生產環境的Redis可不是你想重啟就重啟的。有什么方式可以不重啟Redis就加載rebloom插件嗎,MODULE LOAD命令就派上用場了。

# 不重啟Redis加載rebloom插件

1、查看redis當前已加載的插件
> MODULE LOAD /"rebloom.so的絕對路徑"/redisbloom.so
> module list
1) 1) "name"
2) "bf"
3) "ver"
4) (integer) 999999
# 看到以上數據則說明redisbloom加載成功了,模塊名name為"bf",模塊版本號ver為999999。

# 動態執行模塊卸載
# MODULE UNLOAD 模塊名

# 當然,為了防止Redis重啟導致動態加載的模塊丟失,我們還是應該在redis.conf 中加上相關配置。

2.2、布隆過濾器的命令詳解及示例
完整指令說明可前往官網查看:https://oss.redislabs.com/redisbloom/Bloom_Commands/。

2.2.1、Bloom命令簡述
【核心命令】添加元素:BF.ADD(添加單個)、BF.MADD(添加多個)、BF.INSERT(添加多個);

【核心命令】檢查元素是否存在:BF.EXISTS(查詢單個元素)、BF.MEXISTS(查詢多個元素)

命令 功能 參數
BF.RESERVE 創建一個大小為capacity,錯誤率為error_rate的空的Bloom BF.RESERVE {key} {error_rate} {capacity} [EXPANSION expansion] [NONSCALING]
BF.ADD 向key指定的Bloom中添加一個元素item BF.ADD {key} {item}
BF.MADD 向key指定的Bloom中添加多個元素 BF.MADD {key} {item} [item…]
BF.INSERT 向key指定的Bloom中添加多個元素,添加時可以指定大小和錯誤率,且可以控制在Bloom不存在的時候是否自動創建 BF.INSERT {key} [CAPACITY {cap}] [ERROR {error}] [EXPANSION expansion] [NOCREATE] [NONSCALING] ITEMS {item…}
BF.EXISTS 檢查一個元素是否可能存在於key指定的Bloom中 BF.EXISTS {key} {item}
BF.MEXISTS 同時檢查多個元素是否可能存在於key指定的Bloom中 BF.MEXISTS {key} {item} [item…]
BF.SCANDUMP 對Bloom進行增量持久化操作 BF.SCANDUMP {key} {iter}
BF.LOADCHUNK 加載SCANDUMP持久化的Bloom數據 BF.LOADCHUNK {key} {iter} {data}
BF.INFO 查詢key指定的Bloom的信息 BF.INFO {key}
BF.DEBUG 查看BloomFilter的內部詳細信息(如每層的元素個數、錯誤率等) BF.DEBUG {key}
2.2.2、BF.RESERVE
參數
BF.RESERVE {key} {error_rate} {capacity}
功能
創建一個大小為capacity,錯誤率為error_rate的空的BloomFilter
時間復雜度
O(1)
參數說明
key:布隆過濾器的key;
error_rate:期望的錯誤率(False Positive Rate),該值必須介於0和1之間。該值越小,BloomFilter的內存占用量越大,CPU使用率越高。
capacity:布隆過濾器的初始容量,即期望添加到布隆過濾器中的元素的個數。當實際添加的元素個數超過該值時,布隆過濾器將進行自動的擴容,該過程會導致性能有所下降,下降的程度是隨着元素個數的指數級增長而線性下降。
可選參數
expansion:當添加到布隆過濾器中的數據達到初始容量后,布隆過濾器會自動創建一個子過濾器,子過濾器的大小是上一個過濾器大小乘以expansion。expansion的默認值是2,也就是說布隆過濾器擴容默認是2倍擴容。
NONSCALING:設置此項后,當添加到布隆過濾器中的數據達到初始容量后,不會擴容過濾器,並且會拋出異常((error) ERR non scaling filter is full)。
返回值
成功:OK;
其它情況返回相應的異常信息。
備注
BloomFilter的擴容是通過增加BloomFilter的層數來完成的。每增加一層,在查詢的時候就可能會遍歷多層BloomFilter來完成,每一層的容量都是上一層的兩倍(默認)。
# 公眾號@zxiaofan
# 創建一個容量為5且不允許擴容的過濾器;
127.0.0.1:6379> bf.reserve bf2 0.1 5 NONSCALING
OK
127.0.0.1:6379> bf.madd bf2 1 2 3 4 5
1) (integer) 1
2) (integer) 1
3) (integer) 1
4) (integer) 1
5) (integer) 1

# 添加第6個元素時即提示BloomFilter已滿;
127.0.0.1:6379> bf.madd bf2 6
1) (error) ERR non scaling filter is full
127.0.0.1:6379> bf.info bf2
1) Capacity
2) (integer) 5
3) Size
4) (integer) 155
5) Number of filters
6) (integer) 1
7) Number of items inserted
8) (integer) 5
9) Expansion rate
10) (integer) 2

2.2.3、BF.ADD
參數
BF.ADD {key} {item}
功能
向key指定的Bloom中添加一個元素item。
時間復雜度
O(log N),N是過濾器的層數。
參數說明
key:布隆過濾器的名字;
item:待插入過濾器的元素;
返回值
元素不存在插入成功:返回1;
元素可能已經存在:返回0;
其它情況返回相應的異常信息。
2.2.3、BF.MADD
參數
BF.MADD {key} {item} [item…]
功能
向key指定的Bloom中添加多個元素item。
時間復雜度
O(log N),N是過濾器的層數。
參數說明
key:布隆過濾器的名字;
item:待插入過濾器的元素,可插入多個;
返回值
成功:返回一個數組,數組的每一個元素可能為1或0,當item一定不存在時數組元素值為1,當item可能已經存在時數組元素值為0。
其它情況返回相應的異常信息。
2.2.5、BF.EXISTS
參數
BF.EXISTS {key} {item}
功能
檢查一個元素是否可能存在於key指定的Bloom中
時間復雜度
O(log N),N是過濾器的層數。
參數說明
key:布隆過濾器的名字;
item:待檢查的元素;
返回值
元素一定不存在:0;
元素可能存在:1;
其它情況返回相應的異常信息。
2.2.6、BF.MEXISTS
參數
BF.MEXISTS [item…]
功能
檢查多個元素是否可能存在於key指定的Bloom中
時間復雜度
O(log N),N是過濾器的層數。
參數說明
key:布隆過濾器的名字;
item:待檢查的元素,可設置多個;
返回值
成功:返回一個數組,數組的每一個元素可能為1或0,當item一定不存在時數組元素值為0,當item可能已經存在時數組元素值為1。
其它情況返回相應的異常信息。
# 公眾號@zxiaofan
# 向BloomFilter添加單個元素
127.0.0.1:6379> bf.add bf1 itemadd1
(integer) 1

# 向BloomFilter批量添加多個元素
127.0.0.1:6379> bf.madd bf1 itemmadd1 itemmadd2
1) (integer) 1
2) (integer) 1
127.0.0.1:6379> bf.exists itemmadd1
(error) ERR wrong number of arguments for 'bf.exists' command
127.0.0.1:6379> bf.exists bf1 itemmadd1
(integer) 1

# 批量檢查多個元素是否存在於BloomFilter
127.0.0.1:6379> bf.mexists bf1 itemadd1 itemmadd1 itemmadd2
1) (integer) 1
2) (integer) 1
3) (integer) 1

2.2.7、BF.INSERT
參數
BF.INSERT {key} [CAPACITY {cap}] [ERROR {error}] [EXPANSION expansion] [NOCREATE] [NONSCALING] ITEMS {item…}
功能
向key指定的Bloom中添加多個元素,添加時可以指定大小和錯誤率,且可以控制在Bloom不存在的時候是否自動創建
時間復雜度
O(log N),N是過濾器的層數。
參數說明
key:布隆過濾器的名字;
CAPACITY:[如果過濾器已創建,則此參數將被忽略]。更多的信息參考<BF.RESERVE>;
ERROR:[如果過濾器已創建,則此參數將被忽略]。更多的信息參考<BF.RESERVE>;
expansion:布隆過濾器會自動創建一個子過濾器,子過濾器的大小是上一個過濾器大小乘以expansion。expansion的默認值是2,也就是說布隆過濾器擴容默認是2倍擴容。
NOCREATE:如果設置了該參數,當布隆過濾器不存在時則不會被創建。用於嚴格區分過濾器的創建和元素插入場景。該參數不能與CAPACITY和ERROR同時設置。
NONSCALING:設置此項后,當添加到布隆過濾器中的數據達到初始容量后,不會擴容過濾器,並且會拋出異常((error) ERR non scaling filter is full)。
ITEMS:待插入過濾器的元素列表,該參數必傳。
返回值
成功:返回一個數組,數組的每一個元素可能為1或0,當item一定不存在時數組元素值為1,當item可能已經存在時數組元素值為0。
其它情況返回相應的異常信息。
127.0.0.1:6379> del bfinsert
(integer) 1

127.0.0.1:6379> bf.insert bfinsert CAPACITY 5 ERROR 0.1 EXPANSION 2 NONSCALING ITEMS item1 item2
1) (integer) 1
2) (integer) 1
127.0.0.1:6379> bf.exists bfinsert item5
(integer) 0
127.0.0.1:6379> bf.insert bfinsert CAPACITY 5 ERROR 0.1 EXPANSION 2 NONSCALING ITEMS item1 item2 item3 item4 item5
1) (integer) 0
2) (integer) 0
3) (integer) 1
4) (integer) 1
5) (integer) 0
127.0.0.1:6379> bf.add bfinsert item5
(integer) 0
127.0.0.1:6379> bf.info bfinsert
1) Capacity
2) (integer) 5
3) Size
4) (integer) 155
5) Number of filters
6) (integer) 1
7) Number of items inserted
8) (integer) 4
9) Expansion rate
10) (integer) 2
127.0.0.1:6379> bf.add bfinsert item6
(integer) 1
127.0.0.1:6379> bf.add bfinsert item5
(integer) 0
127.0.0.1:6379> bf.exists bfinsert item5
(integer) 1

# 這里有個比較有意思的現象,item5未顯示添加成功,但是后續卻顯示exists
# 這說明發生了hash沖突,誤判就是這樣產生的。
2.2.8、BF.SCANDUMP
參數
BF.SCANDUMP {key} {iter}
功能
對Bloom進行增量持久化操作(增量保存);
時間復雜度
O(log N),N是過濾器的層數。
參數說明
key:布隆過濾器的名字;
iter:首次調用傳值0,或者上次調用此命令返回的結果值;
返回值
返回連續的(iter, data)對,直到(0,NULL),表示DUMP完成。
備注
127.0.0.1:6378> bf.madd bfdump d1 d2 d3 d4 d5 d6 d7
1) (integer) 1
2) (integer) 1
3) (integer) 1
4) (integer) 1
5) (integer) 1
6) (integer) 1
7) (integer) 1
127.0.0.1:6378> bf.scandump bfdump 0
1) (integer) 1
2) "\a\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x02\x00\x00\x00\x8a\x00\x00\x00\x00\x00\x00\x00P\x04\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00{\x14\xaeG\xe1zt?\xe9\x86/\xb25\x0e&@\b\x00\x00\x00d\x00\x00\x00\x00\x00\x00\x00\x00"
127.0.0.1:6378> bf.scandump bfdump 1
1) (integer) 139
2) "\x80\x00\b\n\x00$\x00 \b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x00\x82$\x04\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x04\x00\x00\x00\x00\x00\x00\x04\x01@\xa0\x00@\x00\x00\x00\x00\x00\x10@\x00\x02\"\x00 \x00\x00\x04\x00\x00\x00\x00\x00 \x00\x80\x00\x00\"\x04\x04\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00 \x80$\x00 \x00\x00 \x0c$\x00\x00\x00\b`\x00\x00\x00\x00\x00\x00\x00\x00\b\x80\x02 \x04\x00\x00\x00\x00\x00"
127.0.0.1:6378> bf.scandump bfdump 139
1) (integer) 0
2) ""
2.2.9、BF.LOADCHUNK
參數
BF.LOADCHUNK {key} {iter} {data}
功能
加載SCANDUMP持久化的Bloom數據;
時間復雜度
O(log N),N是過濾器的層數。
參數說明
key:目標布隆過濾器的名字;
iter:SCANDUMP返回的迭代器的值,和data一一對應;
data:SCANDUMP返回的數據塊(data chunk);
返回值
成功則返回OK。
# Python 偽代碼
# 來源於:https://oss.redislabs.com/redisbloom/Bloom_Commands/

chunks = []
iter = 0
# SCANDUMP
while True:
iter, data = BF.SCANDUMP(key, iter)
if iter == 0:
break
else:
chunks.append([iter, data])

# LOADCHUNK
for chunk in chunks:
iter, data = chunk
BF.LOADCHUNK(key, iter, data)
2.2.10、BF.INFO
參數
BF.INFO {key}
功能
返回BloomFilter的相關信息;
時間復雜度
O(1);
參數說明
key:目標布隆過濾器的名字;
返回值
Capacity:預設容量;
Size:實際占用情況,但如何計算待進一步確認;
Number of filters:過濾器層數;
Number of items inserted:已經實際插入的元素數量;
Expansion rate:子過濾器擴容系數(默認2);
127.0.0.1:6379> bf.info bf2
1) Capacity
2) (integer) 5
3) Size
4) (integer) 155
5) Number of filters
6) (integer) 1
7) Number of items inserted
8) (integer) 5
9) Expansion rate
10) (integer) 2
2.2.11、BF.DEBUG
參數
BF.DEBUG {key}
功能
查看BloomFilter的內部詳細信息(如每層的元素個數、錯誤率等);
時間復雜度
O(log N),N是過濾器的層數;
參數說明
key:目標布隆過濾器的名字;
返回值
size:BloomFilter中已插入的元素數量;
每層BloomFilter的詳細信息
bytes:占用字節數量;
bits:占用bit位數量,bits = bytes * 8;
hashes:該層hash函數數量;
hashwidth:hash函數寬度;
capacity:該層容量(第一層為BloomFilter初始化時設置的容量,第2層容量 = 第一層容量 * expansion,以此類推);
size:該層中已插入的元素數量(各層size之和等於BloomFilter中已插入的元素數量size);
ratio:該層錯誤率(第一層的錯誤率 = BloomFilter初始化時設置的錯誤率 * 0.5,第二層為第一層的0.5倍,以此類推,ratio與expansion無關);
# 公眾號 @zxiaofan
# 創建一個容量為5的BloomFilter,其key為“bfexp”;
127.0.0.1:6379> bf.reserve bfexp 0.1 5
OK

# 查看BloomFilter的內部信息,此時BloomFilter的層數為1
127.0.0.1:6379> bf.debug bfexp
1) "size:0"
2) "bytes:4 bits:32 hashes:5 hashwidth:64 capacity:5 size:0 ratio:0.05"

127.0.0.1:6379> bf.madd bfexp 1 2 3 4 5
1) (integer) 1
2) (integer) 1
3) (integer) 1
4) (integer) 1
5) (integer) 1
127.0.0.1:6379> bf.debug bfexp
1) "size:5"
2) "bytes:4 bits:32 hashes:5 hashwidth:64 capacity:5 size:5 ratio:0.05"

127.0.0.1:6379> bf.madd bfexp 11 12 13 14 15
1) (integer) 1
2) (integer) 1
3) (integer) 1
4) (integer) 0
5) (integer) 1

# 添加10個元素后,此時BloomFilter的層數變為2;
# BloomFilter的元素數量為2層過濾器之和(5+4=9),添加“14”時實際因為hash沖突沒添加成功;
127.0.0.1:6379> bf.debug bfexp
1) "size:9"
2) "bytes:4 bits:32 hashes:5 hashwidth:64 capacity:5 size:5 ratio:0.05"
3) "bytes:10 bits:80 hashes:6 hashwidth:64 capacity:10 size:4 ratio:0.025"

127.0.0.1:6379> bf.madd bfexp 21 22 23
1) (integer) 1
2) (integer) 1
3) (integer) 1
127.0.0.1:6379> bf.debug bfexp
1) "size:12"
2) "bytes:4 bits:32 hashes:5 hashwidth:64 capacity:5 size:5 ratio:0.05"
3) "bytes:10 bits:80 hashes:6 hashwidth:64 capacity:10 size:7 ratio:0.025"
127.0.0.1:6379> bf.madd bfexp 24 25
1) (integer) 1
2) (integer) 1
127.0.0.1:6379> bf.debug bfexp
1) "size:14"
2) "bytes:4 bits:32 hashes:5 hashwidth:64 capacity:5 size:5 ratio:0.05"
3) "bytes:10 bits:80 hashes:6 hashwidth:64 capacity:10 size:9 ratio:0.025"
127.0.0.1:6379> bf.madd bfexp 31 32 33 34 35
1) (integer) 1
2) (integer) 1
3) (integer) 1
4) (integer) 1
5) (integer) 1

# 添加20個元素后,此時BloomFilter的層數變為3;
127.0.0.1:6379> bf.debug bfexp
1) "size:19"
2) "bytes:4 bits:32 hashes:5 hashwidth:64 capacity:5 size:5 ratio:0.05"
3) "bytes:10 bits:80 hashes:6 hashwidth:64 capacity:10 size:10 ratio:0.025"
4) "bytes:23 bits:184 hashes:7 hashwidth:64 capacity:20 size:4 ratio:0.0125"

原文鏈接:https://blog.csdn.net/u010887744/article/details/108700911


免責聲明!

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



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