
布隆过滤器
发布日期:2021-05-06 19:58:41
浏览次数:23
分类:精选文章
本文共 2928 字,大约阅读时间需要 9 分钟。
布隆过滤器
原理
插入
布隆过滤器(BloomFilter) 将待插入的元素通过预先设置的M个哈希函数进行运算,得到M个K值,每个K值表示事先初始化的一个长度为 N的比特位数组上的第K个位置(k<=N),最后将这M位置设置为1。
查询
将要查询的元素经过 M个哈希函数进行运算,得到对应于比特位数组上的 M 个位置,如果M 个位置有一个为 0,则元素肯定不存在,如果 M 个位置全部为 1,则可能存在。
实现
其中,关于M个函数的模拟可以采用如下这种技巧,用2个哈希函数来模拟k个哈希函数。即:
g(x) = h1(x) + ih2(x) ,其中0 <= i <= k-1
@Resource// private StringRedisTemplate stringRedisTemplate; public void put(String target) { int[] offset = getHashOffSet(target); // redis bitmap 保存offset// stringRedisTemplate.executePipelined (new RedisCallback
得到的offset比特位数组我们可以借助redis的bitmap位图数据结构进行保存。
public boolean isExit(String target) { boolean result = true; ListresultList = stringRedisTemplate.execute(new RedisCallback
>() { @Override public List doInRedis(RedisConnection connection) throws DataAccessException { List resultList = Lists.newArrayList(); StringRedisConnection stringRedisConn = (StringRedisConnection) connection; for (int i : offset) { resultList.add(stringRedisConn.getBit(target, i)); } return resultList; } }); for (Boolean isTrue : resultList) { if (!isTrue) { result = false; break; } } return result; }
判断是否存在对应元素时也是通过getHashOffSet得到待查询元素的的比特位数组,然后遍历该数组,数组的值假设为k,则查询redis上该key的第k个位置是否为1,1则返会true,0返回false。
应用
- 热点查询数据预热(譬如特卖商品)
- 网页爬虫时,可用于待爬取的 URL 去重,提高爬取效率
- 反垃圾邮件/短信,用于存放垃圾邮箱/电话号码地址列表,收信时快速查询来信邮箱地址/电话号码是否为垃圾邮箱/骚扰电话,决定接收或者拒收。
- 访问流量统计去重,可应用于大站点/站群访问流量(IP/PV/UV 等)统计,如将来访用户的 IP 存放于布隆过滤器,进而进行去重独立访问计数等。
- 避免缓存穿透
缺点及改进
-
两个不同的元素A、B通过M个哈希函数运算后可能得到同样的bit位数组,如果这时它们存放在redis中的key恰好相同,就可能出现如下这种状况:
-
删除元素A,将2号和4号置为0,查询B时,哦吼,B不在了(其实是有的)
-
可用CounterBloom Filter进行改进,原来的每个bit为是0或1,现在被拓展成一个计数器,会进行累加,删除时就递减
-
不过CounterBloom Filter也有两个问题:计数器存在溢出问题;始终无法保证删除的元素就在布隆过滤器里,可能造成误删
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2025年04月06日 22时36分36秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
【Java远程debug】
2021-05-09
最通俗易懂的囚徒困境
2021-05-09
递推的思维构建与技巧实现
2021-05-09
五道逻辑思维题
2021-05-09
第八届蓝桥杯程序设计大赛 国赛 填空题第一题 平方十位数
2021-05-09
get和post的区别
2021-05-09
MySQL下载安装图文
2021-05-09
liteide错误: 进程无法启动--解决方法
2021-05-09
Java程序中的代理作用和应用场景及实现
2021-05-09
Oracle 用户
2021-05-09
Java 前台后台数据传递、中文乱码解决方法
2021-05-09
Git报错:Permission denied (publickey)
2021-05-09
常见的图文布局
2021-05-09
Laravel - 上手实现 - 文件上传、保存到 public 目录下
2021-05-09
一次性搞懂 PHP 中面向对象的所有知识点。
2021-05-09
JQuery.validate.js 表单验证
2021-05-09
vi 编辑器基本命令
2021-05-09
将mongo设置为windows的服务
2021-05-09