1.1什么是缓存穿透?
查询一个不存在的数据,mysql查询不到数据也不会直接写入缓存,就会导致每次请求都查数据库。
【例】一个get请求:api/news/getById/1
解决方案:
(1)缓存空数据:查询返回的数据为空,仍把这个空结果进行缓存。 {key:1,value:null}
优点:简单。
缺点:消耗内存,可能会发生不一致的问题
(2)布隆过滤器
优点:内存占用少,不存在多余的key
缺点:实现复杂,存在误判
1.2什么是布隆过滤器
布隆过滤器(Bloom Filter)是一种高效的数据结构,用于判断一个元素是否存在于一个集合中。它利用位数组和多个哈希函数来实现快速的成员查询。
bitmap(位图):相当于是一个以(bit)位为单位的数组,数组中每个单元只能存储二进制数0或1。
布隆过滤器的核心思想是用一个位数组(通常用二进制位表示)来表示一个集合,初始时所有位都置为0。然后,对于每个要加入集合的元素,通过多个哈希函数计算出多个哈希值,然后将位数组中对应的位置置为1。
判断一个元素是否存在于集合时,同样使用多个哈希函数计算出对应的哈希值,然后检查位数组中对应的位置是否都为1,如果有任意一个位置为0,则说明该元素不存在于集合中;如果所有位置都为1,则该元素可能存在于集合中(因为有可能发生哈希碰撞),需要进一步查询底层数据结构来确认。
布隆过滤器查询存在误判率:
由于布隆过滤器使用多个哈希函数来映射元素到不同的位置,并且使用二进制位来表示元素的存在状态,这就导致了误判的可能性。具体来说,以下几个因素会导致误判:
(1)哈希碰撞:不同的元素经过哈希函数计算可能映射到相同的二进制位,导致不同元素在布隆过滤器中产生了冲突,从而可能被误判为存在于集合中。
(2)容量限制:布隆过滤器使用有限的二进制位数组来表示集合,当集合中元素数量较多时,可能会导致位的重复使用,从而增加误判的概率。
虽然查询元素是否存在有误判率,但是如果查询元素是否不存在,则没有误判率。
数组越小误判率就越大,数组越大误判率就越小,但是同时带来了更多的内存消耗。一般设置5%的误判率,是可以接受的。