1,定义
布隆过滤器 (Bloom Filter)是由 Burton Howard Bloom 于 1970 年提出,它是一种 space efficient 的概率型数据结构,用于判断一个元素是否在集合中。
当布隆过滤器说某个元素存在时,则此元素可能存在也可能不存在。当过滤器说某个元素不存在时,此元素一定不存在。其中的元素越多,false positive rate(误报率)越大
哈希表也能用于判断元素是否在集合中,但是布隆过滤器只需要哈希表的 1/8 或 1/4 的空间复杂度就能完成同样的问题。
布隆过滤器可以插入元素,但不可以删除已有元素。
2,原理
先分配一块内存作为bit数组,数组内元素全部设为0。
加入元素时,采用k个相互独立的哈希函数计算,然后将数据哈希映射的k个位置值全设为1。
检测时,仍然使用k个哈希函数计算出k个位置,如果全为1,则可能存在,如有一个不为0,则肯定不存在。
3,为什么布隆过滤器会出现误判?
哈希函数会出现碰撞,所以布隆过滤器会存在误判。误判率是指布隆过滤器判断某个值存在,而实际不存在的概率,有概率存在这样的 key,它们内容不同,但多次 Hash 后的 Hash 值都相同。
对于布隆过滤器判断不存在的值,则100%不存在,如果这个 key 存在,那它每次 Hash 后对应的 Hash 值位置肯定是 1,而不会是 0。布隆过滤器判断存在不一定真的存在。
4,为什么布隆过滤器不允许删除元素?
删除意味着需要将对应的 k 个 bits 位置设置为 0,其中有可能是其他元素对应的位。
因此 remove 会引入 false negative,这是绝对不被允许的。
5,redis如何运用布隆过滤器解决缓存穿透?
把要查询的值先过布隆过滤器,判断是否存在,存在就走redis缓存,不存在就直接返回,并且配合缓存空值,可以有效解决缓存穿透问题,虽然存在一定误差,但是在业务范围内允许接受。(允许小部分误判值穿透至数据库进行查询,但数量很少)
- 第一步先查询数据库数据并加入到布隆过滤器中。
- 新请求发送过来布隆过滤器判断是否命中,命中就走缓存,之后接着看是否走数据库还是直接从缓存获取返回。
- 如果布隆过滤器miss,就直接返回空值,不走cache了。