redis缓存穿透中的布隆过滤器详解

布隆过滤器详解


基本概念

布隆过滤器(Bloom Filter)是一种概率型数据结构,用于快速判断元素是否存在于集合中。具有以下特点:

  • 空间效率极高
  • 查询时间复杂度O(k)(k为哈希函数数量)
  • 允许误判(False Positive)
  • 绝不漏判(False Negative)

数据结构组成

  • 位数组(Bit Array):长度为m的二进制向量

  • 哈希函数组:k个相互独立且均匀分布的哈希函数

工作原理

在这里插入图片描述

图片来自小林coding

添加元素

使用k个哈希函数计算元素值

将对应的位数组位置置1

输入元素
哈希函数H1计算
哈希函数H2计算
...
哈希函数Hk计算
位置1置1
位置2置1
...
位置k置1

查询元素

使用相同的k个哈希函数计算

检查所有对应位置是否都为1

查询元素
哈希函数H1计算
哈希函数H2计算
...
哈希函数Hk计算
位置1=1?
位置2=1?
...
位置k=1?
所有位置为1?
可能存在
绝对不存在

特性分析

特性描述
空间效率O(m) 空间复杂度,m为位数组长度
时间效率插入和查询都是O(k)
确定性结论返回"不存在"时100%可靠
概率性结论返回"存在"时有一定误判概率
数据不可逆无法从位数组恢复原始数据
不支持删除因多个元素可能共享位标志

误判率计算

误判概率公式:
P ≈ (1 - e(-kn/m))k

m:位数组长度

k:哈希函数个数

n:已插入元素数量

最佳实践公式(最小误判率时):
k = (m / n) * ln(2)

应用场景

  • 缓存系统:防止缓存穿透
  • 分布式系统:快速判断数据是否存在
  • 爬虫系统:URL去重
  • 数据库:减少磁盘查询
  • 安全领域:恶意网址检测
  • 推荐系统:已读内容过滤

优化方向

  • 动态扩容:自动扩展位数组大小
  • 参数调优:
    • 根据预期元素量选择m
    • 根据m/n比值选择k值
  • 哈希函数优化:使用更均匀分布的哈希算法
  • 变种方案:
    • 计数布隆过滤器(支持删除)
    • 分块布隆过滤器
    • 动态布隆过滤器

参数选择参考表

预期元素量(n)推荐位数组大小(m)推荐哈希函数数(k)理论误判率
10,00095,893 bits71%
100,000958,506 bits71%
1,000,0009.58MB71%
10,000,00095.8MB71%

关键结论

  • 位数组越大,误判率越低
  • 哈希函数数量需要权衡:
    • 过少:容易冲突
    • 过多:位数组快速饱和
  • 实际使用需要根据业务场景:
    • 选择可接受的误判率
    • 平衡内存使用和准确性

redis缓存穿透中布隆过滤器的应用

缓存穿透问题概述

缓存穿透是指在高并发场景下,大量请求查询数据库中不存在的数据,导致请求直接穿透缓存层打到数据库,给数据库带来巨大压力。例如,攻击者恶意构造大量不存在的商品 ID 来请求商品信息,由于缓存中没有这些数据,每次请求都要访问数据库,可能导致数据库性能下降甚至崩溃。

布隆过滤器的应用

  • 初始化布隆过滤器:在 Redis 中,可以使用第三方库(如 RedisBloom)来实现布隆过滤器。首先,根据预期的元素数量和可接受的误判率,设置布隆过滤器的参数,如位数组大小(m)和哈希函数数量(k)。例如,预期要存储 10000 个元素,希望误判率控制在 1%,可以根据相关公式计算出合适的 m 和 k 值。
  • 数据写入:当有新数据写入数据库时,同时将该数据的相关标识(如商品 ID)添加到布隆过滤器中。以添加商品信息为例,假设商品 ID 为 12345,通过 RedisBloom 的命令将其添加到布隆过滤器中。具体命令可能如下(不同库的命令可能略有差异):
BF.ADD myBloomFilter product:12345

这里 myBloomFilter 是布隆过滤器的名称,product:12345 是要添加的元素。

  • 请求处理:当有请求到来时,首先根据请求的参数(如请求的商品 ID),在布隆过滤器中进行查询。例如,请求商品 ID 为 67890 的商品信息,使用以下命令查询布隆过滤器:
BF.EXISTS myBloomFilter product:67890

如果查询结果为该元素不存在(返回 0),则直接返回结果,无需查询数据库,避免了缓存穿透。如果查询结果为该元素可能存在,则继续查询 Redis 缓存。

  • 缓存查询与处理:如果布隆过滤器判断元素可能存在,接着查询 Redis 缓存中是否存在对应的数据。如果缓存中有数据,直接返回给客户端;如果缓存中没有数据,则查询数据库,将查询到的数据存入 Redis 缓存(同时设置合适的过期时间),然后返回给客户端。在将数据存入缓存的同时,也可以再次将相关标识添加到布隆过滤器中,以确保布隆过滤器的准确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cider瞳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值