布隆过滤器--推荐系统去重

布隆过滤器--推荐系统去重

    • 使用场景
    • 基本思路1
    • 基本思路2
    • Redis布隆过滤器实现思路
    • 基本指令
    • 自定义参数的布隆过滤器
    • 布隆过滤器实现原理

使用场景

我们在使用新闻客户端看新闻时,它会给我们不停地推荐新的内容,它每次推荐时要去重,去掉那些已经看过的内容。

基本思路1

服务器记录了用户看过的所有历史记录,当推荐系统推荐新闻时会从每个用户的历史记录里进行筛选,过滤掉那些已经存在的记录。但当用户量很大、每个用户看过的新闻又很多的情况下,去重就需要频繁地对数据库中每个用户的历史记录表进行 exists 查询,在高并发情况下非常影响系统性能。

基本思路2

使用缓存,将每个用户的历史浏览记录缓存起来,虽然查询速度提高了,但这需要耗费大量的内存。

Redis布隆过滤器实现思路

布隆过滤器相当于一个Redis中不精确的Set,它有exists方法判断某元素是否在集合中。通过设置其参数来确定精度,从而设置误判概率。当布隆过滤器说某个值存在时,这个值可能不存在;当它说不存在时,那就肯定不存在。也就是说,推荐系统认为该用户浏览过某条新闻时,用户实际上可能有小概率并没有浏览过这条新闻,但系统认为该用户没有浏览过某条新闻,用户一定没有浏览过这条新闻。这样就能确保用户一定不会浏览重复的内容。

基本指令

bf.add key value //往集合中添加元素(集合名 值)
bf.madd key value1 value2 value3 //往集合中添加多个元素(集合名 值1 值2 值3)

bf.exists key value //判断集合中是否存在该元素(集合名 值)
bf.mexists key value1 value2 value3 //判断集合中是否存在指定的多个元素(集合名 值1 值2 值3)

自定义参数的布隆过滤器

bf.reserve key 0.001 50000 //(集合名 错误率(越低越占空间) 预计元素数量(实际数量超过该值,错误率会上升))
bf.add key value //往集合中添加元素(集合名 值)

布隆过滤器实现原理

布隆过滤器--推荐系统去重_第1张图片
每个布隆过滤器对应到 Redis 的数据结构里面就是一个大型的位数组和几个不一样的无偏 hash 函数。所谓无偏就是能够把元素的 hash 值算得比较均匀。

向布隆过滤器中添加 value 时,会使用多个 hash 函数对 value 进行 hash 算得一个整数索引值然后对位数组长度进行取模运算得到一个位置,每个 hash 函数都会算得一个不同的位置。再把位数组的这几个位置都置为 1 就完成了 add 操作。

向布隆过滤器询问 value 是否存在时,跟 add 一样,也会把 hash 的几个位置都算出来,看看位数组中这几个位置是否都为 1,只要有一个位为 0,那么说明布隆过滤器中这个 value 不存在。如果都是 1,这并不能说明这个 value 就一定存在,只是极有可能存在,因为这些位被置为 1 可能是因为其它的 value 存在所致。如果这个位数组比较稀疏,判断正确的概率就会很大,如果这个位数组比较拥挤,判断正确的概率就会降低。具体的概率计算公式比较复杂,感兴趣可以阅读扩展阅读,非常烧脑,不建议读者细看。

使用时不要让实际元素远大于初始化大小,当实际元素开始超出初始化大小时,应该对布隆过滤器进行重建,重新分配一个 size 更大的过滤器,再将所有的历史元素批量 add 进去 (这就要求我们在其它的存储器中记录所有的历史元素)。因为 error_rate 不会因为数量超出就急剧增加,这就给我们重建过滤器提供了较为宽松的时间。

你可能感兴趣的:(Redis)