布隆过滤器误判_布隆过滤器原理
布隆过滤器
布隆过滤器拥有极高的性能,无论是写入操作还是读取操作,时间复杂度是O(1)。
在空间上相对于其他数据结构,有很大优势, 20亿的数据需要 2000000000bit/8/1024/1024 = 238 M ,如果使用数组来存储,假设每个用户 ID 占用 4个字节的空间,存储20亿用户需要 2000000000byte/4/8/1024/1024 = 7600M 的空间,是布隆过滤器的32倍。
布隆过滤器(Bloom Filter)
hash 函数
布隆过滤器的缺点
- 在判断元素是否在集合中有一定的错误几率,会误判,把不是在集合中的元素判断为处在集合中。
- 不支持删除元素
布隆过滤器误判是怎么回事?
hash 算法也叫做 摘要算法,作用是对任意一组数据输入,得到一个固定长度的输出摘要。
误判的原因,主要是Hash算法的问题。布隆过滤器是由于一个二进制和一个 Hash 算法组成的,Hash 算法存在着一定的碰撞几率。Hash 碰撞的含义是不同的输入值经过 hash 得到相同的 hash 结果。
hash 算法的输入值是无限的,输出值空间是固定的,比如 16位 hash 值的之空间是 65535 这样碰撞几率就是 1/65535 ,即输入值的个数超过 65535 就一定会发生碰撞。
但是,如果使用更长的 hash 值会带来更高的存储成本和计算成本,32 位的 hash 算法,值空间长度是 2^32-1 大概 42亿,如果有 20亿用户数据,碰撞的概率高达 50%。hash 碰撞造成两个用户,A 和 B 会计算出相同的两个 hash 值,如果A 是注册用户,B不是注册用户, 但是 A 和 B 在的的数组中是相同的,然后产生误判。
布隆过滤器的误判有一个特点,只会出现 false positive 的情况,当布隆过滤器判断元素在集合中,这个元素可能不在集合中,但是布隆过滤器判断这个元素不在集合时,它一定不在集合中,这一点非常适合解决缓存穿透的问题。
布隆过滤器有一个可预测的误判率(FPP):
- n 是已经添加元素的数量;
- k 哈希的次数;
- m 布隆过滤器的长度(如比特数组的大小);
怎么减少这个误判几率
布隆过滤器存在误判,但是依然可以减少缓存穿透的发,但是为了尽量减少误判,可以使用如下解决方案:
使用多个 hash 算法为元素计算出多个 Hash 值,只有所有的hash 值对应的数组都为1个小时,才会认定这个元素在集合中。
布隆过滤器不支持删除元素的缺点也合 Hash 碰撞有关
有这样的场景,A 和 B 都是集合中的元素,他没有相同的 hash 值,会映射到数组同一个位置,但是如果此时上次了A,数组中对应位置从1 编程0 ,但是判断 B 时,会发现值是0 ,认为 B 不存在集合中。这样产生误判。
解决这个问题,一般有这样的解决方案:
数组上不再是1 和 0 两个值,而是存储一个计数,如果 A 和 B 命中同一个位置 值就是 2 ,如果 A 删除就把这个值改成1,但是这样数组就不存在 1bit ,而是存储数值,会增加空间的消耗。
布隆过滤器使用
- 选择多个 Hash 函数计算多个 hash 值,可以减少误判
- 布隆过滤器会消耗一定的内存空间,所以在使用时需要评估业务场景需要多大的内存消耗。
如果出现了一个极热数据,一旦失效,会有大量数据穿透到数据库。给数据库造成极大压力。
如何解决热点数据失效问题
极热数据缓存失效,也叫"狗壮效应"
热点数据失效后启动一个线程,将数据加载到缓存中,在缓存数据加载前,所有访问的请求都不穿透数据库直接返回。
通过 Redis 设置分布式锁,只有获得锁,才能够穿透到数据库。
布隆过滤器使用
pom.xml 依赖
com.google.guavaguava28.0-jre
Java 代码
import com.google.common.base.Charsets;import com.google.common.hash.BloomFilter;import com.google.common.hash.Funnels;
public class BloomFilterDemo { public static void main(String[] args) { int total = 1000000; // 总数量 BloomFilter bf = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8), total); // 初始化 1000000 条数据到过滤器中for (int i = 0; i bf.put("" + i); } // 判断值是否存在过滤器中 int count = 0;for (int i = 0; i if (bf.mightContain("" + i)) { count++; } } System.out.println("已匹配数量 " + count); }}
总结
布隆过滤器可以一定程度上解决缓存穿透的问题,解决缓存穿透的问题核心是减少数据库的并发访问。由于 hash 碰撞的原因,布隆过滤器存在一定的误判几率,也存在不支持删除元素的问题。
欢迎关注公众号:程序员开发者者社区
布隆过滤器误判_布隆过滤器原理相关推荐
- 布隆过滤器速度_布隆过滤器,你也可以处理十几亿的大数据
文章收录在 GitHub JavaKeeper ,N线互联网开发必备技能兵器谱 什么是 BloomFilter 布隆过滤器(英语:Bloom Filter)是 1970 年由布隆提出的.它实际上是一个 ...
- 布隆过滤器速度_布隆过滤器的分析和实现
腾讯曾经出过这样一道面试题. 给40亿个不重复的无符号整数,没排过序.给一个无符号整数,如何快速判断一个数是否在这40亿个数中. 拿到这个题目,我们首先想到的是遍历这40亿的数字,然后一个一个找.显然 ...
- 布隆过滤器速度_布隆过滤器(Bloom Filter)详解
布隆过滤器[1](Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的.它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元 ...
- 布隆过滤器误判怎么办为什么会_五分钟小知识:布隆过滤器原理和应用分析
布隆过滤器出现的背景和要解决的问题 Wikipedia 上面提到布隆过滤器早在 1970 年就被提出来,很难想象在当时那个年代它的主要用途是什么,估计当时提出也是一个数据模型吧. 在互联网时代,每天会 ...
- mysql布隆过滤器源码_布隆过滤器(Bloom Filter)的原理和实现
什么情况下需要布隆过滤器? 先来看几个比较常见的例子 字处理软件中,需要检查一个英语单词是否拼写正确 在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上 在网络爬虫里,一个网址是否被访问过 yahoo, ...
- 布隆过滤器速度_详解布隆过滤器的原理、使用场景和注意事项
今天碰到个业务,他的 Redis 集群有个大 Value 用途是作为布隆过滤器,但沟通的时候被小怼了一下,意思大概是 "布隆过滤器原理都不懂,还要我优化?".技术菜被人怼认了.怪不 ...
- 判断数组中某个元素除自身外是否和其他数据不同_布隆过滤器,我也是个处理过 10 亿数据的人...
❝ 文章收录在 GitHub JavaKeeper ,N线互联网开发必备技能兵器谱 什么是 BloomFilter 布隆过滤器(英语:Bloom Filter)是 1970 年由布隆提出的.它实际上是 ...
- 【恋上数据结构】布隆过滤器(Bloom Filter)原理及实现
布隆过滤器(Bloom Filter) 引出布隆过滤器(判断元素是否存在) 布隆过滤器介绍(概率型数据结构) 布隆过滤器的原理(二进制 + 哈希函数) 布隆过滤器的误判率(公式) 布隆过滤器的实现 布 ...
- 硬核 | Redis 布隆(Bloom Filter)过滤器原理与实战
在Redis 缓存击穿(失效).缓存穿透.缓存雪崩怎么解决?中我们说到可以使用布隆过滤器避免「缓存穿透」. 码哥,布隆过滤器还能在哪些场景使用呀? 比如我们使用「码哥跳动」开发的「明日头条」APP 看 ...
最新文章
- SAP HUM已知一个内部HU号码,如何得到HU号码?
- vs开发工具报错:参数错误 异常来自 HRESULT:0x80070057 E_INVALIDARG
- 01-----JavaScript简介
- python大学课程-大学只安排了C和Python课程,是否有必要学习一下Java
- dine with the dean judge business school
- python调用父类对象的几个方法
- ie浏览器在线使用_关于登录深圳市住房公积金管理中心网站在线办理平台的温馨提示...
- jq怎么更换json对象的key_toString如何转json
- 程序员计算器使用方法介绍(快速计算十六进制、八进制的方法)
- IT趣谈:关于所谓”XcodeGhost”的澄清
- PLC编程实例(一) 基本电路
- 关于互联网金融的安全、监管
- vue 中 用showdown预览markdown文件,并用highlight.js 实现代码高亮
- ak和sk的意思及用法
- 某app登录协议逆向分析
- 前端——获取手机验证码案例
- Economics Overview
- 外汇MT4 CRM源代码出售 -935423577
- fanuc机器人基于程序号码选择(PNS)的自动运转
- 语音识别数据增强方法(google2019年7月论文)
热门文章
- 【Elasticsearch】为Elasticsearch启动https访问
- 【Elasticsearch】es 的 translog
- 【hortonworks/registry】registry 如何创建 互相依赖的 schema
- Spark报错:Bad response ERROR for block BP-78092257-8.xx-121xxx
- 78-spark2.2的编译
- 95-170-046-源码-Time-Flink时间系统系列之ProcessFunction使用分析
- FastDFS 入门简介
- Gitee同步GitHub仓库如何操作
- ef 批量保存 oracle,mybatis-oracle与mysql批量添加
- Java多线程学习二十六:原子类是如何利用 CAS 保证线程安全的?