• REDIS布隆过滤器原理、安装使用


    1 布隆过滤器介绍

    Hash、Set、String的BitMap等可以实现判断元素是否存在的功能,但这些实现方式要么随着元素增多会占用大量内存(Hash、Set),要么无法动态伸缩和保持误判率不变(BitMap)。因此,我们非常需要一种可以高效判断大量数据是否存在且允许一定误判率的数据结构。

    1.1 什么是布隆过滤器(Bloom Filter)

    布隆过滤器由Burton Howard Bloom于1970年提出,用于判断一个元素是否在集合中。
      布隆过滤器(Bloom filter)是一种非常节省空间的概率数据结构(space-efficient probabilistic data structure),运行速度快(时间效率),占用内存小(空间效率),但是有一定的误判率且无法删除元素。本质上由一个很长的二进制向量和一系列随机映射函数组成。

    1.2 布隆过滤器特点

    • 一个很长的二进制向量 (位数组)
    • 一系列随机函数 (哈希)
    • 空间效率和查询效率高
    • 有一定的误判率(哈希表是精确匹配)
    • 布隆过滤器支持添加元素、检查元素,但是不支持删除元素;
    • 检查结果分为2种:一定不在集合中、可能在集合中(误判率问题);

    检查到的结果:
    1.元素不存在该集合,就一定不存在该集合
    2.元素存在该集合,就不一定是存在(此处是误判率的问题)

    官方redisboom地址:
    https://docs.redislabs.com/latest/modules/redisbloom/
    https://oss.redislabs.com/redisbloom/Quick_Start/
    https://oss.redislabs.com/redisbloom/#command-references
    https://docs.redislabs.com/latest/modules/redisbloom/redisbloom-quickstart/?_ga=2.234894149.555262092.1603270995-1549265601.1603270995

    2.安装REDIS

    #下载
    [root@localhost redis]# /root/redis
    [root@localhost redis]# wget https://download.redis.io/releases/redis-5.0.5.tar.gz
    
    #解压安装
    [root@localhost redis]# tar -zxvf redis-5.0.5.tar.gz
    [root@localhost redis]# ls
    redis-5.0.5  redis-5.0.5.tar.gz
    [root@localhost redis]# cd redis-5.0.5
    [root@localhost redis-5.0.5]# make
    

      

    3.下载REDISBLOOM插件

    redis官网下载即可
    https://github.com/RedisLabsModules/redisbloom/

    tag:https://github.com/RedisBloom/RedisBloom/tags

    3.1 下载压缩包

    [root@localhost redis]# wget https://github.com/RedisBloom/RedisBloom/archive/v2.2.1.tar.gz
    

      3.2 解压并安装,生成.so文件

    [root@localhost redis]# tar -zxf v2.2.1.tar.gz 
    [root@localhost redis]# ls
    redis-5.0.5  redis-5.0.5.tar.gz  RedisBloom-2.2.1  v2.2.1.tar.gz
    [root@localhost redis]# cd RedisBloom-2.2.1/
    [root@localhost RedisBloom-2.2.1]# make
    [root@localhost RedisBloom-2.2.1]# ls
    changelog  contrib  Dockerfile  docs  LICENSE  Makefile  mkdocs.yml  ramp.yml  README.md  redisbloom.so  rmutil  src  tests

    3.3 在redis配置文件(redis.conf)中加入该模块即可

    [root@localhost redis-5.0.5]# pwd
    /root/redis/redis-5.0.5
    [root@localhost redis-5.0.5]# ls
    00-RELEASENOTES  CONTRIBUTING  deps     Makefile   README.md   runtest          runtest-moduleapi  sentinel.conf  tests
    BUGS             COPYING       INSTALL  MANIFESTO  redis.conf  runtest-cluster  runtest-sentinel   src            utils
    [root@localhost redis-5.0.5]# ls |grep redis.conf
    redis.conf
    #配置文件添加.so文件
    [root@localhost redis-5.0.5]# vim redis.conf
    

      

    4 启动REDIS

    [root@localhost redis-5.0.5]# ./src/redis-server ./redis.conf &
    
    #查看是否启动成功
    [root@localhost redis-5.0.5]# ps -ef|grep 6379
    root       4234   4176  0 22:12 pts/0    00:00:07 ./redis-server *:6379
    root       8744   4176  0 23:06 pts/0    00:00:00 grep --color=auto 6379
    
    #连接客户端
    [root@localhost redis-5.0.5]# ./src/redis-cli 
    127.0.0.1:6379> keys *
    (empty list or set)
    127.0.0.1:6379> 

    5 操作REDISBLOOM

    基本操作命令:

    命令格式说明
    bf.reserve bf.reserve {key} {error_rate} {initial_size} 创建一个大小为initial_size位向量长度,错误率为error_rate的空的Bloom过滤器
    bf.add bf.add{key} {item} 向key指定的Bloom中添加一个元素item
    bf.madd bf.madd {key} {item} {item2} {item3} … 一次添加多个元素
    bf.exists bf.exists {key} {item} 查询元素是否存在
    bf.mexists bf.mexists {key} {item} {item2} {item3} … 检查多个元素是否存在
    bf.info bf.info {key} 查询key指定的Bloom的信息
    bf.debug bf.debug {key} 查看BloomFilter的内部详细信息(如每层的元素个数、错误率等)
    cf.reserve cf.reserve {key} {initial_size} 创建一个initial_size位向量长度的空的Bloom过滤器
    cf.add cf.add {key} {item} 向key指定的Bloom中添加一个元素item
    cf.exists cf.exists {key} {item} 检查该元素是否存在
    bf.scandump bf.scandump {key} {iter} (key:布隆过滤器的名字,iter:首次调用传值0,或者上次调用此命令返回的结果值)对Bloom进行增量持久化操作(增量保存)
    bf.localchunk bf.localchunk {key} {iter} {data} 加载SCANDUMP持久化的Bloom数据(key:目标布隆过滤器的名字,iter:SCANDUMP返回的迭代器的值,和data一一对应,data:SCANDUMP返回的数据块(data chunk))

    【说明redis布隆过滤器不支持修改元素,只能重新创建】

    redis中有两个值决定布隆过滤器的准确率:

    说明
    error_rate 允许布隆过滤器的错误率,这个值越低过滤器的位数组的大小越大,占用空间就越大 (默认值0.01)
    initial_size 布隆过滤器可以存储的元素个数(位存储),当实际存在的元素个数超过这个值之后,过滤器的准确率会下降(默认值100)

    redis 设置redisbloom的这两个值:
    demo:bf.reserve test 0.1 100000000
    说明: bf.reserve 过滤器的名字 错误率(error_rate 的值) 位向量长度(initial_size 的值)

    参数说明
    test 是过滤器的名字
    0.1 错误率( error_rate 的值)
    1000000 位向量长度(initial_size 的值)

    (注意必须在add之前使用bf.reserve指令显式创建,如果对应的key已经存在,bf.server会报错。同事设置的错误率越低,需要的空间越大。如果不使用bf.serve,默认的error_rate是0.01,默认的initial_size是100)

    6 REDISBLOOM示例

    6.1 redis-cli操作

    #新建一个过滤器
    127.0.0.1:6379> bf.reserve test 0.1 1000000     # test是布隆过滤器名称,0.1是误判率,1000000是位向量长度
    OK
    
    #向过滤器中添加元素
    127.0.0.1:6379> bf.add test one  
    (integer) 1
    127.0.0.1:6379> bf.add test two
    (integer) 1
    #test是布隆过滤器名称,one,two是需要判断的元素
    
    #批量添加
    127.0.0.1:6379> bf.madd test 1 2 3 4
    1) (integer) 1
    2) (integer) 1
    3) (integer) 1
    4) (integer) 1
    
    
    
    #判断元素是否在过滤器中
    127.0.0.1:6379> bf.exists test one
    (integer) 1
    127.0.0.1:6379> bf.exists test two
    (integer) 1
    127.0.0.1:6379> bf.exists test three
    (integer) 0    
    #test是布隆过滤器名称,one,two是需要判断的元素存在返回1,不存在返回0
    
    #批量判断该元素是否存在
    127.0.0.1:6379> bf.mexists test 1 2 3 5
    1) (integer) 1
    2) (integer) 1
    3) (integer) 1
    4) (integer) 0
    
    
    #查看指定的key的Bloom信息
    127.0.0.1:6379> bf.info test
     1) Capacity
     2) (integer) 1000000
     3) Size
     4) (integer) 779555
     5) Number of filters
     6) (integer) 1
     7) Number of items inserted
     8) (integer) 7
     9) Expansion rate
    10) (integer) 2
    
    #查看BloomFilter的内部详细信息(如每层的元素个数、错误率等)
    127.0.0.1:6379> bf.debug test
    1) "size:7"
    2) "bytes:779403 bits:6235224 hashes:5 hash64 capacity:1000000 size:7 ratio:0.05"
    
    #添加一个位向量长度为100000000的空的布隆过滤器
    127.0.0.1:6379> cf.reserve test3 100000000
    OK
    
    #添加元素
    127.0.0.1:6379> cf.add test3 1
    (integer) 1
    127.0.0.1:6379> cf.add test3 2
    (integer) 1
    
    #检查该元素是否存在
    127.0.0.1:6379> cf.exists test3 2
    (integer) 1
    
    #对Bloom进行增量持久化操作(增量保存
    127.0.0.1:6379> bf.scandump test 0
    1) (integer) 1
    2) "ax00x00x00x00x00x00x00x01x00x00x00x05x00x00x00x02x00x00x00x8bxe4x0bx00x00x00x00x00X$_x00x00x00x00x00ax00x00x00x00x00x00x00x9ax99x99x99x99x99xa9?Jxf7xd4x9exdexf0x18@x05x00x00x00@Bx0fx00x00x00x00x00x00"

    6.2 php使用

    #添加php-redisbloom.php文件
    <?php
    $redis=new Redis();
    $redis->connect('127.0.0.1',6379);
    $result=$redis->rawCommand('bf.exists','test','one');
    var_dump($result);
                  
    #执行
    [root@localhost redis]# php php-redisbloom.php 
    int(1)
    

      

    【添加:在向redis set值的之后,调用bf.add添加到过滤器。 检查:在穿过了redis去到Mysql之前,调用bf.exists检查一下,如果不存在则不连接mysql查询】

     
    版权声明:本文为yinjinshui原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
    本文链接:https://blog.csdn.net/yinjinshui/article/details/109196693
  • 相关阅读:
    HDU 5444 Elven Postman (2015 ACM/ICPC Asia Regional Changchun Online)
    POJ 1577 Falling Leaves 二叉搜索树
    HDU 3791 二叉搜索树
    Problem: Godfather 树的重心
    Problem: [Poi0202]Travelling Salesman 最近公共祖先
    Problem: 最优连通子集
    Problem: 扫雪系列II
    Problem: 扫雪系列I
    Problem: [Ural1039]没有上司的晚会
    Problem: 八中教室的灯
  • 原文地址:https://www.cnblogs.com/yszr/p/14963109.html
Copyright © 2020-2023  润新知