首页 > 数据库 >Redis中的布隆过滤器

Redis中的布隆过滤器

时间:2022-10-25 16:44:56浏览次数:68  
标签:... bf 元素 Redis 布隆 key 过滤器

一、前戏

Redis提供了HyperLogLog来解精确度不是很高的统计需求,相比set空间减少了很多,也更方便,但是HyperLogLog只是提供了pfadd添加元素,pfcount统计元素,基于HyperLogLog数据结构的实现,无法判断某个数是否存在与这个key中,故没有pfcontain这种指令一说。
举个栗子,当我们刷短视频时,会不停的给我们推荐视频,它每次推荐都需要进行去重,去掉那些我们已经看到过的视频,那么像人均一天刷100个视频/小时,这种数据该怎么去重了,
假如服务端记录每个人的浏览记录,需要查询时再从这个集合中过滤掉已经存在的记录,如果存在关系型数据库当中,每次进行大量的exists查询,存在缓存当中,假如每个人每天存一个key,用户量很大,数据量很大时,推荐的去重性能能跟的上么,存储空间会随着时间线性增长。
基于这种大数据量的去重问题,布隆过滤器(Bloom Filter)闪亮登场,它就是专门解决这种去重问题的,在去重的同时,存储空间可以减少90%以上,但是布隆过滤器也不是那么的准确,存在一定的误判率。

二、布隆过滤器介绍

布隆过滤器可以看成一个不怎么精确的set结构,当使用contains方法判断某个值是否存在时,它可能会误判,默认布隆过滤器实际上是一个很长的二进制向量或者位图和一系列的随机映射函数组成,初始状态,给定长度的位数组所有位置都位1。

向布隆过滤器中添加元素时,会使用多个hash函数对元素算得一个整数索引值,然后对位数组进行取模运算得到一个位置,每个hash函数都会算得一个不同的位置,,再把位数组的这个位置设置为1,就完成了添加操作。

  1. 将要添加的元素给k个哈希函数
    2.得到位于位数组的k个位置
    3.将位数组这k个位置设置为1
    向布隆过滤器中查询是否存在某个元素时也一样,根据这些hash函数把这几个位置算出来,算完查看对应值是否为1,只要有一个位为0,那么说明这个元素一定不在布隆过滤器当中,如果所有位的值都为1,这并不能说明这个值一定存在,因为某个位置的1可能是其他元素hash运算出来的,所以会发生误判。因为不确定这个位的1是哪个元素产生并置为1的,(所以布隆过滤器没有删除操作,删除某个位的1可能导致其他元素不准确,增大了误判率)如果这个位数组比较稀疏,这个概率就会很大, 相反,如果这个位数组比较密集,这个概率就会很低
    1.将要查询的元素给k个哈希函数
    2.得到位于位数组的k个位置
    3.判断k个位置是否全部位1,如果全部为1,可能存在,如果有一位为0,则一定不存在
    布隆过滤器的优缺点:
    一个事物不可能好的不得了,凡事都有优缺点,只是孰轻孰重由自己判读,布隆过滤器的优点在于相比其他数据结构,空间和时间都存在巨大优势,由于Redis的最开始是由位数字实现的,占用的空间可以很小,存储和查询的时间都位O(1),散列函数相互没有关系,方便由硬件并行实现,布隆过滤器并不需要存储元素本身,所以在需要相对保密的场合也有一定优势。
    缺点:随着元素的增加,误算率会随之增加,在需要绝对精确的场合,以及小量数据情况下,不推荐使用布隆过滤器。
    三、redis使用
    Redis官方提供的布隆过滤器到了Redis4.0之后提供了插件功能之后正式登场,布隆过滤器作为一个插件加载到Redis server当中,给redis提供了强大的去重功能。
    Docker安装:
    https://hub.docker.com/r/redislabs/rebloom
docker pull redislabs/rebloom
docker run -p6379:6379 redislabs/rebloom
redis-cli

命令:
添加元素

bf.add key ...options...


返回值为1表示添加成功,bf.add一次只能插入一个元素,如果想插入多个,可以使用下面这个命令

bf.madd key ...options...

查询某个元素是否已经存在

bf.exists key ...options...


如果想一次性查询多个元素,使用下面的命令

bf.mexists key ...options...

bf.info key [CAPACITY | SIZE | FILTERS | ITEMS | EXPANSION]
查看过滤器的信息

标签:...,bf,元素,Redis,布隆,key,过滤器
From: https://www.cnblogs.com/LiuFqiang/p/16825378.html

相关文章

  • Redis 为什么这么快?
    思维导图 基于内存实现这点在一开始就提到过了,这里再简单说说。Redis是基于内存的数据库,那不可避免的就要与磁盘数据库做对比。对于磁盘数据库来说,是需......
  • Redis 的数据被删除,为什么占用内存没减少?
    通过CONFIGSETmaxmemory100mb或者在redis.conf配置文件设置maxmemory100mbRedis内存占用限制。当达到内存最大值值,会触发内存淘汰策略。除此之外,当key达到过期......
  • Redis数据结构(一)-Redis的数据存储及String类型的实现
    1引言Redis作为基于内存的非关系型的K-V数据库。因读写响应快速、原子操作、提供了多种数据类型String、List、Hash、Set、SortedSet、在项目中有着广泛的使用,今天我们来......
  • Nodejs+Redis实现简易消息队列
    前言消息队列是存储数据的一个中间件,可以理解为一个容器。生产者生产消息投递到队列中,消费者可以拉取消息进行消费,如果消费者目前没有消费的打算,则消息队列会保留消息,直......
  • Redis Cluster 原理说的头头是道,这些配置不懂就是纸上谈兵
    RedisCluster原理说的头头是道,这些配置不懂就是纸上谈兵RedisCluster集群相关配置,使用集群方式的你必须重视和知晓。别嘴上原理说的头头是道,而集群有哪些配置?如何配置......
  • Redis Cluster 原理说的头头是道,这些配置不懂就是纸上谈兵
    RedisCluster原理说的头头是道,这些配置不懂就是纸上谈兵RedisCluster集群相关配置,使用集群方式的你必须重视和知晓。别嘴上原理说的头头是道,而集群有哪些配置?如何配置......
  • Redis数据结构(一)-Redis的数据存储及String类型的实现
    1引言Redis作为基于内存的非关系型的K-V数据库。因读写响应快速、原子操作、提供了多种数据类型String、List、Hash、Set、SortedSet、在项目中有着广泛的使用,今天我们......
  • Redis的数据类型详解
    作者:IT邦德中国DBA联盟(ACDU)成员,目前从事DBA及程序编程(Web\java\Python)工作,主要服务于生产制造现拥有Oracle11gOCP/OCM、Mysql、Oceanbase(OBCA)认证分布式TBase\TDSQL数......
  • Prometheus监控Redis
    redis-exporter监控Redis一、单节点监控#启动,密码带特殊字符时需要用\进行转义dockerrun-dit-p9121:9121-eREDIS_ADDR=IP:6379-eREDIS_PASSWORD=password--na......
  • 认识 Redis client-output-buffer-limit 参数与源码分析
    概述Redis的​​client-output-buffer-limit​​可以用来强制断开无法足够快从redis服务器端读取数据的客户端。保护机制规则如下:[hardlimit]大小限制,当某一客户端缓......