布隆过滤器

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')  判断是否存在
    
  • 测试:

    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
        """
    
原文地址:https://www.cnblogs.com/xujunkai/p/13603167.html