布隆过滤器

布隆过滤器拥有极高的性能,无论是写入操作还是读取操作,时间复杂度是O(1)。

在空间上相对于其他数据结构,有很大优势, 20亿的数据需要 2000000000bit/8/1024/1024 = 238 M ,如果使用数组来存储,假设每个用户 ID 占用 4个字节的空间,存储20亿用户需要 2000000000byte/4/8/1024/1024 = 7600M 的空间,是布隆过滤器的32倍。

布隆过滤器(Bloom Filter)

Bloom

hash  函数

hash

布隆过滤器的缺点

  1. 在判断元素是否在集合中有一定的错误几率,会误判,把不是在集合中的元素判断为处在集合中。
  2. 不支持删除元素

布隆过滤器误判是怎么回事?

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):

image
  • 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 ,而是存储数值,会增加空间的消耗。

布隆过滤器使用

  1. 选择多个 Hash 函数计算多个 hash 值,可以减少误判
  2. 布隆过滤器会消耗一定的内存空间,所以在使用时需要评估业务场景需要多大的内存消耗。

如果出现了一个极热数据,一旦失效,会有大量数据穿透到数据库。给数据库造成极大压力。

如何解决热点数据失效问题

极热数据缓存失效,也叫"狗壮效应"

  1. 热点数据失效后启动一个线程,将数据加载到缓存中,在缓存数据加载前,所有访问的请求都不穿透数据库直接返回。

  2. 通过 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 碰撞的原因,布隆过滤器存在一定的误判几率,也存在不支持删除元素的问题。

欢迎关注公众号:程序员开发者者社区
微信号:程序员开发者社区博客:CSDN 王小明关注我们,了解更多

布隆过滤器误判_布隆过滤器原理相关推荐

  1. 布隆过滤器速度_布隆过滤器,你也可以处理十几亿的大数据

    文章收录在 GitHub JavaKeeper ,N线互联网开发必备技能兵器谱 什么是 BloomFilter 布隆过滤器(英语:Bloom Filter)是 1970 年由布隆提出的.它实际上是一个 ...

  2. 布隆过滤器速度_布隆过滤器的分析和实现

    腾讯曾经出过这样一道面试题. 给40亿个不重复的无符号整数,没排过序.给一个无符号整数,如何快速判断一个数是否在这40亿个数中. 拿到这个题目,我们首先想到的是遍历这40亿的数字,然后一个一个找.显然 ...

  3. 布隆过滤器速度_布隆过滤器(Bloom Filter)详解

    布隆过滤器[1](Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的.它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元 ...

  4. 布隆过滤器误判怎么办为什么会_五分钟小知识:布隆过滤器原理和应用分析

    布隆过滤器出现的背景和要解决的问题 Wikipedia 上面提到布隆过滤器早在 1970 年就被提出来,很难想象在当时那个年代它的主要用途是什么,估计当时提出也是一个数据模型吧. 在互联网时代,每天会 ...

  5. mysql布隆过滤器源码_布隆过滤器(Bloom Filter)的原理和实现

    什么情况下需要布隆过滤器? 先来看几个比较常见的例子 字处理软件中,需要检查一个英语单词是否拼写正确 在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上 在网络爬虫里,一个网址是否被访问过 yahoo, ...

  6. 布隆过滤器速度_详解布隆过滤器的原理、使用场景和注意事项

    今天碰到个业务,他的 Redis 集群有个大 Value 用途是作为布隆过滤器,但沟通的时候被小怼了一下,意思大概是 "布隆过滤器原理都不懂,还要我优化?".技术菜被人怼认了.怪不 ...

  7. 判断数组中某个元素除自身外是否和其他数据不同_布隆过滤器,我也是个处理过 10 亿数据的人...

    ❝ 文章收录在 GitHub JavaKeeper ,N线互联网开发必备技能兵器谱 什么是 BloomFilter 布隆过滤器(英语:Bloom Filter)是 1970 年由布隆提出的.它实际上是 ...

  8. 【恋上数据结构】布隆过滤器(Bloom Filter)原理及实现

    布隆过滤器(Bloom Filter) 引出布隆过滤器(判断元素是否存在) 布隆过滤器介绍(概率型数据结构) 布隆过滤器的原理(二进制 + 哈希函数) 布隆过滤器的误判率(公式) 布隆过滤器的实现 布 ...

  9. 硬核 | Redis 布隆(Bloom Filter)过滤器原理与实战

    在Redis 缓存击穿(失效).缓存穿透.缓存雪崩怎么解决?中我们说到可以使用布隆过滤器避免「缓存穿透」. 码哥,布隆过滤器还能在哪些场景使用呀? 比如我们使用「码哥跳动」开发的「明日头条」APP 看 ...

最新文章

  1. SAP HUM已知一个内部HU号码,如何得到HU号码?
  2. vs开发工具报错:参数错误 异常来自 HRESULT:0x80070057 E_INVALIDARG
  3. 01-----JavaScript简介
  4. python大学课程-大学只安排了C和Python课程,是否有必要学习一下Java
  5. dine with the dean judge business school
  6. python调用父类对象的几个方法
  7. ie浏览器在线使用_关于登录深圳市住房公积金管理中心网站在线办理平台的温馨提示...
  8. jq怎么更换json对象的key_toString如何转json
  9. 程序员计算器使用方法介绍(快速计算十六进制、八进制的方法)
  10. IT趣谈:关于所谓”XcodeGhost”的澄清
  11. PLC编程实例(一) 基本电路
  12. 关于互联网金融的安全、监管
  13. vue 中 用showdown预览markdown文件,并用highlight.js 实现代码高亮
  14. ak和sk的意思及用法
  15. 某app登录协议逆向分析
  16. 前端——获取手机验证码案例
  17. Economics Overview
  18. 外汇MT4 CRM源代码出售 -935423577
  19. fanuc机器人基于程序号码选择(PNS)的自动运转
  20. 语音识别数据增强方法(google2019年7月论文)

热门文章

  1. 【Elasticsearch】为Elasticsearch启动https访问
  2. 【Elasticsearch】es 的 translog
  3. 【hortonworks/registry】registry 如何创建 互相依赖的 schema
  4. Spark报错:Bad response ERROR for block BP-78092257-8.xx-121xxx
  5. 78-spark2.2的编译
  6. 95-170-046-源码-Time-Flink时间系统系列之ProcessFunction使用分析
  7. FastDFS 入门简介
  8. Gitee同步GitHub仓库如何操作
  9. ef 批量保存 oracle,mybatis-oracle与mysql批量添加
  10. Java多线程学习二十六:原子类是如何利用 CAS 保证线程安全的?