布隆过滤器(bloom filter)的原理及在推荐去重中的应用

遇到的问题

在业务中,我须要给每一个用户保存1w条浏览记录,以后每一次的返回值都要和历史记录作一个去重,即保证用户不会重复看到同一篇文章.redis

这个需求有两个比较麻烦的地方:算法

1.空间问题

每一个用户1w条,10w用户就是10亿条数据,应该保存在哪里呢?sql

Redis?哪里有那么大内存给你用.数据库

Hbase?Hbase我不太了解具体原理,听说每次全量查询有点慢啊(后来听大佬说这点数据无压力的).数组

Mysql?却是能存下这么多,可是太影响性能了.缓存

2.时间问题

这个需求对即时性要求仍是比较高的,用户两次刷新的间隔可能只有几秒钟,在此期间就要完成历史数据的添加以及过滤.安全

每次返回用户10条数据,每一条都须要和数据库中的1w条作比对,听起来效率就不好的样子.网络

在大佬的推荐下,我去了解了一下布隆过滤器,最后初步使用布隆过滤器+Redis+Hbase完成了一个版本,效率和空间占用都还能够.函数

布隆过滤器

介绍

如下摘自维基百科:性能

布隆过滤器(英语:Bloom Filter)是1970年由布隆提出的。它其实是一个很长的二进制向量和一系列随机映射函数。布隆过滤器能够用于检索一个元素是否在一个集合中。它的优势是空间效率和查询时间都远远超过通常的算法,缺点是有必定的误识别率和删除困难。

说直白一点就是:布隆过滤器用本身的算法,实现了快速的检索一个元素是否在一个较大的元素列表之中.

原理

当一个元素被加入集合时,经过K个散列函数将这个元素映射成一个位数组中的K个点,把它们置为1。检索时,咱们只要看看这些点是否是都是1就(大约)知道集合中有没有它了:若是这些点有任何一个0,则被检元素必定不在;若是都是1,则被检元素极可能在。这就是布隆过滤器的基本思想。

假设咱们如今得到了一个size=10000的布隆过滤器,分配给咱们的实际上是10000个二进制位,假设k=8,那么当新添加huyanshi这个元素时,经过8个不一样的hash函数,能够拿到8个index值,假设为1,2300,222,11...,咱们就将这8个index为下标的位置,置为1.

当咱们想要检索huyanshi是否存在时,再次用8个hash函数得到8个index,若是这8个index的位置都为1,那么这个元素就很可能存在.若是其中有一位为0,则该元素必定不存在.

注意上面的可能加粗了,下面就要说优缺点了.

优势

  1. 效率高,插入和查询操做都是O(k).
  2. 空间节省,每个元素映射为一个二进制位,必须节省.
  3. 安全,保存了数据的全集,可是没有保存数据自己.

缺点

  1. 误算率,使用了Hash算法,那么久必然会存在极限巧合下的hash碰撞.会将不存在的数据认为是存在的.可是存在的数据必定是能够正确判断的.
  2. 很难删除数据.

使用场景

根据优缺点,咱们能够分析出他的使用场景,那么就是的正确率要求不是100%,同时存在海量的数据集.

  • 字处理软件中,须要检查一个英语单词是否拼写正确
  • 在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上
  • 在网络爬虫里,一个网址是否被访问过
  • yahoo, gmail等邮箱垃圾邮件过滤功能

具体实现

布隆过滤器做为一个成熟的过滤器,应该学会实现本身了.

啊,不对,是网上有许多的简易版实现,代码不到100行就能够,所以这里不贴代码了.

我在项目中使用了google guava项目下的BloomFilter,挺好用的.

个人解决方案

1. hbase部分

hbase负责存储用户浏览记录的原始数据,只保存用户浏览的文章的id或者url,这里以id为例.

经过范围查询能够得到name:huyanshi,history=[1,2,4,5,6]格式的数据.

2. redis部分

在这里面使用redis,主要是考虑到,针对活跃用户,及频繁刷新的用户,每次请求都全量从Hbase拉取数据,而后构造布隆过滤器,即时Hbase扛得住,我以为这个构造过滤器的时间也太长了.所以使用redis对过滤器进行缓存.

在redis中存储序列化后的布隆过滤器对象,时间为30分钟,30分钟内用户若是再次访问,直接从redis中获取过滤器,而后进行过滤操做.

3. 布隆过滤器部分

主要是添加以及查询两个操做,从hbase拿到数据以后,构造过滤器,而后对当前返回的10条内容进行判重.以后将新的10条内容加入过滤器,再次写入redis.

流程图

很久没画图了,,,慌得一批.

完.





ChangeLog

2018-12-18 完成

以上皆为我的所思所得,若有错误欢迎评论区指正。

欢迎转载,烦请署名并保留原文连接。

联系邮箱:huyanshi2580@gmail.com

更多学习笔记见我的博客------>呼延十

相关文章
相关标签/搜索