布隆过滤器

一、什么是布隆过滤器

布隆过滤器由很长的bit数组和一组哈希映射函数组成,可用于一个元素是否一定不存在于一个集合中或者可能在集合中。

可以把布隆过滤器理解为一个不怎么精确的set结构,当你使用contains方法判断某个对象是否存在时,他可能会误判。但是布隆过滤器也不是特别的不精准,只要参数设置得合理,它的精准度也可以控制的相对足够精确,只会有小小的误判率。

当布隆过滤器说某个值存在时,这个值可能不存在,而当它说某个值不存在时就一定不存在。

二、布隆过滤器的原理

每个布隆过滤器对应到Redis的数据结构里面就是一个大型的位数组和几个不一样的无偏hash函数,如下图所示的 f, g, h 就是这样的hash函数。所谓的无偏就是能够把元素的hash值算的比较均匀,让元素被hash映射到位数组中的位置比较随机。

布隆过滤器_第1张图片

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

向布隆过滤器询问key是否存在时和add一样也会把hash的几个位置计算出来,看看位数组中的整几个位置是否都为1,只要有一个为0,那么说明布隆过滤器中的key不存在。如果这几个位置都为1并不能说明这个key一定存在,只是极有可能,因为这些位置置为1可能是因为其他key存在导致的。如果这个位数组比较稀疏,判断正确的概率就会很大,如果这个位数组比较拥挤判断正确的概率就会很低。

使用时不用让实际元素数量大于初始化数量,当实际元素数量开始超出初始化数量时应该对布隆过滤器进行重建,重新分配一个size更大的过滤器,再将所有的历史元素批量add进去(这样就要求我们在其他的存储器中记录所有的历史元素)。

三、其他

1. 缓存的更新策略

缓存的策略主要有以下三种:

  • LRU/LFU/FIFO算法剔除:例如max-memory-policy
  • 超时剔除:expire
  • 主动更新:主开发控制生命周期

三种策略对比

策略 一致性 维护成本
LRU/LFU/FIFO算法剔除 最差
超时剔除 较差
主动更新

 

 

 

 

 

策略选择建议

  • 低一致性:最大内存和淘汰策略
  • 高一致性:超时剔除和主动更新结合,最大内存和淘汰策略兜底

2.缓存粒度问题

缓存力度控制的三个角度:

  • 通用性:全量属性更好
  • 占用空间:部分属性更好
  • 代码维护:表面上全量属性更好

3.缓存穿透问题

一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去数据库查询。一些恶意的请求会故意大量查询不存在的key,就会对数据库造成很大的压力。这就叫做缓存穿透。

解决方法:

  • 采用布隆过滤器,将所有可能存在的数据存到一个bitMap中,不存在的数据就会进行拦截。
  • 缓存空对象,缓存时间设置短一点。

缓存空对象如下图所示:

布隆过滤器_第2张图片

布隆过滤器拦截如下图:

布隆过滤器_第3张图片

 

4.缓存雪崩优化 

 缓存雪崩就是指缓存由于某些原因(比如 宕机、cache服务挂了或者不响应)整体crash掉了,导致大量请求到达后端数据库,从而导致数据库崩溃,整个系统崩溃,发生灾难。

优化方案:

  • 保证缓存的高可用性:个别节点,个别机器甚至是机房
  • 依赖组件为后端限流
  • 提前演练:如压力测试

你可能感兴趣的:(redis,布隆过滤器)