前言
在昨天我们介绍了什么是布隆过滤器,而相信如果了解布隆过滤器的朋友应该都知道,布隆过滤器虽然可以解决Redis的穿透问题,但是由于它自身特性,布隆过滤器也是存在不少的缺点,例如随着哈希函数的增多或者哈希函数散列范围的增加,会造成一定程度的空间浪费;并且布隆过滤器是无法实现删除操作的。因此我们今天来介绍一种新的过滤器:布谷鸟过滤器
目录

引入:
在中国有一个成语,叫做鸠占鹊巢,字面意思就是说:鸠这种动物,从来不会自己搭建巢穴,在下蛋的时候就会把蛋下到鹊的巢穴里,挤占鹊的蛋的生存空间。而鸠就是布谷鸟,布谷鸟过滤器的思想就是挤占
布谷鸟过滤器的底层用的是布谷鸟哈希结构。 因此我们先来介绍一下布谷鸟哈希结构
布谷鸟哈希结构:
布谷鸟哈希结构本质上是为了解决哈希冲突,所以我们先来介绍一下什么是哈希冲突:
哈希冲突指的是在哈希函数计算过程中,不同的输入值得到了相同的哈希值的情况。由于哈希函数将输入映射到有限的输出空间,而输入的范围通常是无限的,所以哈希冲突是不可避免的。
而最原始的布谷鸟哈希结构采用以下步骤来解决哈希冲突:
- 对输入的Key使用两个Hash函数,得到桶中的两个位置
- 如果两个位置都为空,就把Key随机选择一个位置放入
- 如果两个位置只有一个为空,就把Key放入到这个空的位置
- 如果两个位置都不为空,则随机踢出一个元素,踢出的元素再重新计算哈希找到相应的位置
其实这样说可能还是有点模糊,所以我们搭配图片来说明一下:
第一次插入元素:插入"张三",经过哈希后得到两个位置:3和5,选择位置3进行插入

第二次插入元素 : 插入"赵四",经过哈希后,得到两个位置3和4,选择位置3进行插入

而此时当“赵四”想要插入位置3的时候,就会发生挤占,将"张三"从原位置挤占出去了

此时就要重新为张三进行hash,得到位置3和5 选择位置5进行插入。
而在这种情况下,我们就完成了一次"挤占"的过程 。并且为被挤占的元素重新安排了位置
挤占循环 :
如果发生挤占循环怎么办?也就是说:当重新为张三进行hash后,我们没有选择位置5,而是选择了位置3,此时就又会把“赵四”挤占出去了,而重新为“赵四”进行Hash的时候,赵四又选择了位置3,再次把“张三”挤占出去,此时“张三”又要重新进行Hash,无限循环这种情况..........
或者是不同数据之间的相互挤占,也就是A数据的插入挤占出了B数据,B数据的插入挤占出了C数据,C数据的插入挤占了D数据,这样不断的循环
而挤占循环这种问题,是没有办法真正解决的,我们能做的只有尽量抑制挤占循环,有如下思路:
- 设置最大挤占次数,如果达到最大挤占次数后,说明空间不够用了,要进行桶的扩容操作。
- 设置更多的哈希函数,使得一个Key有更多的位置可以选择。
而通过这两种方法,其实就可以很好的控制循环挤占的问题
而我们单独讲一下桶的扩容操作,因为桶可以使我们自己定义的数据结构,因此我们可以把让一个位置存储多个元素,类似二维数组的形式,我们来看一下代码:
type bucket [4]byte // 一个桶,4个座位I
type cuckoo_filter struct [
buckets [size]bucket // 一维数组
nums int // 容纳的元素的个数
kick_max // 最大挤兑次数
}
如图所示

这样我们就使得一个桶中可以

本文介绍了布谷鸟过滤器,一种基于布谷鸟哈希结构的过滤器,解决了布隆过滤器的空间浪费和不可删除的问题。通过指纹标记元素并优化空间使用,尽管存在误判风险,但提供了数据删除功能。
https://blog.youkuaiyun.com/fckbb/article/details/134226419?spm=1001.2014.3001.5501
最低0.47元/天 解锁文章





