zoukankan      html  css  js  c++  java
  • 布隆过滤器

    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
          """
      
  • 相关阅读:
    剑指offer--38.左旋转字符串
    剑指offer--37.和为S的两个数字
    剑指offer--35.数组中只出现一次的数字
    剑指offer--34.数字在排序数组中出现的次数
    剑指offer--33.丑数
    剑指offer--36.整数中1出现的次数(从1到n整数中1出现的次数)
    剑指offer--32.把数组排成最小的数
    剑指offer--31.二叉树中和为某一值的路径
    剑指offer--30.二叉搜索树的后序遍历序列
    剑指offer--29.从上往下打印二叉树
  • 原文地址:https://www.cnblogs.com/xujunkai/p/13603167.html
Copyright © 2011-2022 走看看