python中有关布隆过滤器
1.redis准备工作
-
redis在4.0版本以后可通过插件的形式添加布隆过滤器,这里使用redis6.0.6
CentOS 7 yum install -y http://rpms.famillecollet.com/enterprise/remi-release-7.rpm # 查看所有可用Redis版本 yum --enablerepo=remi list redis --showduplicates | sort -r # 安装指定版本redis yum --enablerepo=remi install redis-6.0.6 -y
2.布隆过滤器安装
-
首先去github下载源码包:
git clone https://github.com/RedisBloom/RedisBloom.git
-
拖入linux机器中,解压,安装
cd RedisBloo make # 会在文件生成一个redisbloom.so
-
启动:
redis-server myredisconf.conf --loadmodule ~/RedisBloom/redisbloom.so # 也可以在 redis配置文件加入:loadmodule ~/RedisBloom/redisbloom.so
3.测试
127.0.0.1:6379> bf.add xjk 123
(integer) 1
127.0.0.1:6379> bf.exists xjk 123
(integer) 1
- redis常用命令
bf.add 添加单个元素 bf.add key value
bf.madd 添加多个元素 bf.madd one_key a b c
bf.exists 判断一个元素是否存在
bf.mexists 判断多个元素是否存在
bf.reserve 创建一个自定义布隆过滤器, 它有三个参数
key:键
error_rate: 期望错误率
capacity: 初始容量
4.python中使用布隆过滤器
-
通过pip下载 redisbloom
pip install redisbloom
-
简单操作
from redisbloom.client import Client rb = Client(host="redis IP", port=6379) # 创建sring k-v rb.bfAdd("url","google") # 判断是否存在 rb.bfExists("url","baidu") # 删除 rb.delete("url")
-
其他命令
rb.bfCreate('bloom', 0.01, 1000)# 指定key=bloom 错误率0.01%, 容量1000 rb.bfAdd('bloom', 'foo') 添加一个元素 rb.bfExists('bloom', 'foo') 判断是否存在
- 详细可去github查看:https://github.com/RedisBloom/redisbloom-py
-
测试:
import time from redisbloom.client import Client rb = Client(host='114.215.84.163', port=6379) def insert(size, key='book'): """插入数据""" # 一条条插入速度太慢了 # for i in range(size): # rb.bfAdd(key, f'book{i}') s = time.time() step = 1000 # 每次插入1000条数据 for start in range(0, size, step): stop = start + step if stop >= size: stop = size rb.bfMAdd(key, *range(start, stop)) print('插入结束... 花费时间: {:.4f}s'.format(time.time() - s)) def select(size, key='book'): """查询数据""" # 统计误判个数 count = 0 s = time.time() # 单条查询速度太慢了。。。 # for i in range(size, size * 2): # count += rb.bfExists(key, i) step = 1000 # 每次查1000条数据 for start in range(size, size * 2, step): stop = start + step if stop >= size * 2: stop = size * 2 count += rb.bfMExists(key, *range(start, stop)).count(1) # 返回值[1, 0, 1, ...]统计1的个数 print('size: {}, 误判元素个数: {}, 误判率{:.4%}'.format(size, count, count / size)) print('查询结束... 花费时间: {:.4f}s'.format(time.time() - s)) print('*' * 30) def _test1(size, key='book'): """测试size个不存在的""" rb.delete(key) # 先清空原来的key insert(size, key) select(size, key) def _test2(size, error=0.001, key='book'): """指定误差率和初始大小的布隆过滤器""" rb.delete(key) rb.bfCreate(key, error, size) # 误差率为0.1%, 初始个数为size insert(size, key) select(size, key) if __name__ == '__main__': _test1(1000) _test1(10000) _test1(100000) _test2(500000) """ 插入结束... 花费时间: 0.0389s size: 1000, 误判元素个数: 10, 误判率1.0000% 查询结束... 花费时间: 0.0229s ****************************** 插入结束... 花费时间: 0.2465s size: 10000, 误判元素个数: 103, 误判率1.0300% 查询结束... 花费时间: 0.2474s ****************************** 插入结束... 花费时间: 3.0442s size: 100000, 误判元素个数: 1054, 误判率1.0540% 查询结束... 花费时间: 2.6052s ****************************** 插入结束... 花费时间: 15.5183s size: 500000, 误判元素个数: 253, 误判率0.0506% 查询结束... 花费时间: 15.6606s ****************************** """
-
黑名单demo
def create_black(key, error, capacity): """创建黑名单""" rb = Client(connection_pool=pool) rb.bfCreate(key, errorRate=error, capacity=capacity) def get_item(key, item): rb = Client(connection_pool=pool) return rb.bfExists(key, item) def add_item(key, item): rb = Client(connection_pool=pool) return rb.bfAdd(key, item) def remove_imte(key, item): rb = Client(connection_pool=pool) pass if __name__ == '__main__': create_black("blacklist", 0.001, 1000) add_item("blacklist", "user:1") add_item("blacklist", "user:2") add_item("blacklist", "user:3") add_item("blacklist", "user:4") print('user:1是否在黑名单-> ', get_item('blacklist', 'user:1')) print('user:2是否在黑名单-> ', get_item('blacklist', 'user:2')) print('user:6是否在黑名单-> ', get_item('blacklist', 'user:6')) """ user:1是否在黑名单-> 1 user:2是否在黑名单-> 1 user:6是否在黑名单-> 0 """