Skip to content

布隆过滤器

一、底层基础:Bitmap位图

Bitmap 本质是二进制位数组,数组每个位置仅存储 0 或 1,仅占用 1bit 空间,内存利用率极高。

  • 0:对应下标位置无数据
  • 1:对应下标位置已标记存在数据

二、元素存入规则

以存入 id=1 为例:

  1. 对同一个元素,通过多个不同哈希函数计算出多个位图下标;
  2. 将所有计算出的下标位置的值统一改为 1。 一条数据会占用多个 bit 位,并非只占用单个位置。

三、元素查询规则

  1. 判断不存在:只要任意一个哈希对应下标为 0,数据一定不存在,结果百分百准确。
  2. 判断存在:所有哈希对应下标均为 1,数据大概率存在,存在误判可能。

误判原因

不同元素经过哈希计算后,下标发生碰撞,对应位置都被标记为 1。此时查询不存在的元素,也会判定为存在。 核心特性:只会误判存在,绝不会误判不存在

四、优缺点

优点

  1. 采用 bit 位存储,内存占用极小,可承载海量数据。
  2. 基于哈希与位运算实现,查询、写入速度极快。

缺点

  1. 无法直接删除数据:单个 bit 位会被多个元素共用,删除一个元素会影响其他数据标记。
  2. 存在小概率哈希碰撞,出现误判。

五、Redis 业务应用:解决缓存穿透

  1. 项目启动时,将数据库中所有合法数据 ID 预先加载到布隆过滤器。
  2. 接收用户请求携带 ID:
    • 过滤器判定数据不存在,直接拦截请求,不再访问 Redis 和 MySQL。
    • 过滤器判定数据存在,正常走查询流程:先查 Redis,缓存未命中再查询数据库。

六、两种落地实现方案

一、Guava 布隆过滤器(单机版)

1. 特点

  1. 本地内存实现,数据存储在 JVM 内存中,不依赖第三方中间件。
  2. 不支持集群共享,集群部署时各实例数据相互独立,无法保证一致性;项目重启后数据丢失。
  3. 适用场景:单体项目、数据量较小的业务。

2. 优点

开箱即用,依托 Guava 内置 API,无需额外部署组件。

二、Redisson 布隆过滤器(分布式版,生产主流)

1. 特点

  1. 基于 Redis Bitmap 实现,过滤器数据统一存储在 Redis,集群内所有服务实例共享同一份数据。
  2. 项目重启、多实例部署均不会丢失数据,完美适配微服务分布式架构。

2. 适用场景

分布式微服务项目,是线上防止缓存穿透的首选方案。

三、两者核心对比

方案存储位置分布式支持优缺点
GuavaJVM本地内存不支持集群使用简单,集群环境下失效
RedissonRedis位图支持全服务共享分布式标准实现,依赖Redis

四、业务选型

  1. 单体项目 → 选用 Guava 布隆过滤器
  2. 微服务/分布式项目 → 选用 Redisson 布隆过滤器

七、面试高频问题解析

  1. 问:简述布隆过滤器底层原理与查询特点?

    答: 底层基于 Bitmap 二进制位数组,通过多个哈希函数对元素计算下标并标记为1。查询时,只要有一个下标为0就判定数据不存在;全部为1则判定存在。该结构只会出现“误判存在”,不会误判不存在。

  2. 问:布隆过滤器为什么不能删除数据?

    答: 多个元素会共用同一个 bit 位,直接将位置置0,会导致其他正常数据被误删除,因此原生布隆过滤器不支持删除操作。

  3. 问:布隆过滤器在Redis场景下主要解决什么问题?

    答: 主要用来解决缓存穿透。将合法数据ID提前存入过滤器,非法请求直接拦截,避免大量空请求穿透到数据库,保护MySQL。

  4. 问:Guava和Redisson实现的布隆过滤器有什么区别,如何选型?

    答: Guava是本地内存实现,仅适用于单体项目,集群无法共享数据;Redisson基于Redis实现,支持分布式集群。单体项目选Guava,微服务分布式项目优先使用Redisson。

Powered by VitePress 1.6.4 | 持续更新中