【布隆过滤器】如何防止缓存穿透、海量邮箱的垃圾邮件过滤等问题?
目录
一、布隆过滤器是什么?
二、布隆过滤器的模拟实现
2.1、模拟实现
2.2、布隆过滤器的优点和缺点
优点:
缺点:
2.3、布隆过滤器的删除功能
2.4、布隆过滤器的使用场景
一、布隆过滤器是什么?
它是一种概率型数据结构,特点是高效的插入和查询,作用是可以告诉你“某个数据一定不存在,或是可能存在”,原理是通过多个哈希函数,将一个数据映射到位图中,好处是不仅提高了查询效率,也可以节省大量的内存空间,底层相当于 哈希+位图;
解读:为什么能知道“某样东西一定不存在,或者可能存在”?
哈希冲突。因为他的原理是通过多个哈希函数来进行映射,好比我要存放两个字符串,有可能,这两个字符串经过哈希函数计算,映射到的位置正好相同,如下图:
但是,不难理解的一点是,假设有三个哈希函数进行哈希,那么如果我要查找某一个字符串,是否一定不存在,那么一定是肯定的,因为三个位置上只要有一个不为1,就说明要查找的这个字符串一定不存在;
PS:
1.一般使用布隆过滤器来说,是会给定一个误判率的;
2.布隆过滤器没有存储当前的数据(如上图);
二、布隆过滤器的模拟实现
2.1、模拟实现
这里的逻辑实现太简单了,就不展开论述了,对于添加和查找功能,就是通过不同的哈希函数进行哈希来存入或查找不同元素,查找元素时,一旦有一个数值经过哈希函数无法在位图中找到,就说明一定不存在;
代码如下:
class SimpleHash {public int cap;//容量public int seed;//随机public SimpleHash(int cap, int seed) {this.cap = cap;this.seed = seed;}/*** 根据seed的不同,创建不同点哈希函数* @param key* @return*/int hash(String key) {int h;return (key == null) ? 0 : (seed * (cap-1)) & ((h = key.hashCode()) ^ (h >>> 16));}}
public class MyBloomFilter {//bitSet的初始化大小public static final int DEFAULT_SIZE = 1 << 20;//位图public BitSet bitSet;//记录存储的数据数量public int usedSize;public static final int[] seeds = {3,5,12,6,24,32};public SimpleHash[] simpleHashes;public MyBloomFilter() {bitSet = new BitSet(DEFAULT_SIZE);//创建哈希函数simpleHashes = new SimpleHash[seeds.length];for(int i = 0; i < simpleHashes.length; i++) {simpleHashes[i] = new SimpleHash(DEFAULT_SIZE, seeds[i]);}}/*** 添加元素到布隆过滤器* @param val*/public void add(String val) {//让每个哈希函数分别处理当前数据,并存入位图中for(int i = 0; i < simpleHashes.length; i++) {bitSet.set(simpleHashes[i].hash(val));}}/*** 是否包含val,这里会存在一定的误判* @param val 一定是通过这几个哈希函数看对应的位置* @return*/public boolean contains(String val) {//只要有1个为0 那么一定不存在for(int i = 0; i < simpleHashes.length; i++) {if(!bitSet.get(simpleHashes[i].hash(val))) {return false;}}return true;}//测试public static void main(String[] args) {MyBloomFilter myBloomFilter = new MyBloomFilter();myBloomFilter.add("hello");myBloomFilter.add("hello2");myBloomFilter.add("hello3");myBloomFilter.add("hehe");myBloomFilter.add("haha");System.out.println(myBloomFilter.contains("hello4"));}
}
PS:布隆过滤器不支持删除工作,因为删除元素时,可能会影响到其他元素;例如有两个字符串在位图中若有一个占用相同的比特位,那么删除其中任意一个字符串,都有可能造成另一个字符串找不到的情况;
2.2、布隆过滤器的优点和缺点
优点:
1.增加和查询时间复杂度都是:O(k) ,这里k是哈希函数的个数;
2.布隆过滤器不需要存储元素本身,对有保密要求的场合有一定优势;
3.能够承受一定的误判;
4.因为底层是位图实现,因此可以存放海量数据,其他数据结构不行;
缺点:
1.有误判率,即假阳性,不能准确判断元素是否在集合中(补救方法:再建立一个白名单,存储可能会误判的数据)
2.不能获取元素本身;
3.一般情况下布隆过滤器不能删除元素;
4.如果采用计数方式删除,可能会存在计数回绕问题。
2.3、布隆过滤器的删除功能
布隆过滤器不能直接删除数据,因为删除元素时可能会影响到其他元素。
但是办法总还是有的(计数器):将布隆过滤器中的每一个bit位扩展成一个小的计数器,插入元素时给计数器加一,删除元素时给计数器减一,这是一种多占用几倍的存储空间代价来进行删除功能;
存在缺陷:
1.无法确认元素是否真正在布隆过滤器中;
2.存在计数回绕
2.4、布隆过滤器的使用场景
1.去重功能;
2.判断给定数据是否存在:海量数据(数据亿级)存储校验、防止缓存穿透、邮箱的垃圾邮件过滤、黑名单功能等;
【布隆过滤器】如何防止缓存穿透、海量邮箱的垃圾邮件过滤等问题?相关推荐
- 布隆过滤器避免redis缓存穿透
缓存穿透及布隆过滤器 Redis的基于缓存,极大地提升了应用程序的性能和效率,特别是数据查询方面,但是也带来了一些问题,比如典型的 缓存穿透.缓存雪崩.缓存击穿. 本篇先讲缓存穿透及其解决办法. (1 ...
- 一个基于Flask框架做的仿QQ邮箱系统(收发邮件、贝叶斯模型训练、垃圾邮件过滤、个性化标签)
一个基于Flask框架做的仿QQ邮箱系统(收发## 标题邮件.贝叶斯模型训练.垃圾邮件过滤.个性化标签) 1.贝叶斯邮件垃圾邮件分类 对上千封邮件进行贝叶斯模型分类训练,对基本邮件实现垃圾分类效果. ...
- Redis 布隆过滤器实战「缓存击穿、雪崩效应」
Java高级互联网架构 2019-03-22 13:52:38 为什么引入 我们的业务中经常会遇到穿库的问题,通常可以通过缓存解决. 如果数据维度比较多,结果数据集合比较大时,缓存的效果就不明显了. ...
- 163邮箱注册申请哪个好?163邮箱如何处理垃圾邮件?
有很多人用过免费个人电子邮箱,但又升级到VIP邮箱是为什么呢?因为VIP邮箱容量大,安全防护更有保障,可以撤回误发的邮件,也可以找回误删除的邮件,最重要的是垃圾邮件少. 如何拒收垃圾邮件? TOMV ...
- python垃圾邮件过滤_垃圾邮件过滤器Python newbi
我需要能够处理数据集,应用我的分类算法(我选择了3个朴素的bayes版本),打印精度得分到终端,并执行5到10倍交叉验证,找出有多少电子邮件是垃圾邮件. 正如你所看到的,我已经完成了一些任务,但是没有 ...
- 5 Redis缓存穿透、击穿、雪崩、分布式锁、布隆过滤器
1 Redis 应用问题解决 1.1 缓存穿透 1.1.1 问题描述 key 对应的数据在数据源并不存在,每次针对此 key 的请求从缓存获取不到,请求都会压到数据源(数据库),从而可能压垮数据源.比 ...
- 布隆过滤器误判怎么办为什么会_说一说布隆过滤器
介绍 布隆过滤器在wiki上的介绍: 布隆过滤器(Bloom Filter)是1970年由布隆提出的.它实际上是一个很长的二进制向量和一系列随机映射函数.布隆过滤器可以用于检索一个元素是否在一个集合中 ...
- 清空缓存的命令_布隆过滤器应用——解决Redis缓存穿透问题
1. 布隆过滤器 简要介绍布隆过滤器的概念和特点,详细知识请参考几篇参考文献或其它文章. 1.1 概念 简单点说,布隆过滤器本质是一个位数组. 当一个元素加入过滤器时,使用多个hash函数对元素求值, ...
- 解决Redis缓存穿透之布隆过滤器详解
文章目录 1. 什么是Bloom Filter(布隆过滤器) 1.1 布隆过滤器优点 1.2 布隆过滤器缺点 1.3 布隆过滤器使用场景 1.4 布隆过滤器检索过程 1.5 布隆过滤器的算法描述 2. ...
最新文章
- python编程django遇到问题Passing a 3-tuple to include() is not supported.解决方案
- php依赖注入解决什么问题,php – 了解依赖注入的问题
- 【Web】MVC模式
- Android逆向笔记-大部分内购游戏破解思路
- oracle查询保留小数点后三位,关于Oracle中查询的数字值的显示格式需要保留小数点后两位(或者三位,及其他位数)...
- Asp.net MVC Pager分页实现
- sqlite 附加和分离数据库
- 大数据分析需掌握哪些方面
- python爬人人贷代码视频_利用python爬取人人贷网的数据
- 学习一些和redux一样作用的mobx知识
- Python : bitcoin库
- 教你微星电脑按f几重装系统
- Unity 法线翻转
- 【AnySDK】接入必读及常见问题
- 如何在Ubuntu上方便使用OpenAI API key
- 给旧安卓手机安卓linux系统,手机秒变服务器(Linux Deploy)
- ActiveMQ —— Spring 整合 ActiveMQ
- 仿京东天猫商品详情页
- scroll-view 下滑列表加载的使用
- PageRank 笔记
热门文章
- 【看论文】之《基于双目视觉的棚室番茄采摘关键技术研究_胡慧明》
- C语言——分支语句 and 循环语句
- Android clean kernel
- 吉林省工信厅王大宁副厅长一行莅临麒麟信安考察调研
- USB描述符都是什么意思你看懂了吗?
- 关于Web的学习(18.5.18)——css篇
- android:layout_marginleft 代码设置,在android的java代码中对控件的layout_marginLeft进行设置...
- Tkinter 组件详解(四):Radiobutton
- nessus全端口禁ping扫_nessus自定义扫描策略
- H5小程序中实现emoji表情