布隆过滤器必须前置在缓存和数据库查询之前,作为第一道硬拦截;Test()需在cache.Get()前调用,输入必须是与Add()完全一致的[]byte,且Add()须与DB写入强同步,实例应为包级变量并配合空值缓存使用。

布隆过滤器必须前置在缓存和数据库查询之前,否则等于没加——它不是补丁,是第一道硬拦截。
filter.Test() 必须在 cache.Get() 之前调用
很多团队把 filter.Test() 放在 cache.Get() 后面,比如先查 Redis,miss 了再测布隆。这完全违背设计初衷:布隆的价值在于「确定不存在就立刻返回」,不产生任何下游开销。
错误链路:cache.Get() → miss → filter.Test() → false → return:此时 Redis 已被查一次,DB 可能也已触发(若没做二次保护)
正确链路:filter.Test([]byte(key)) → false → 直接 return;只有 true 才继续 cache.Get()
-
Test()输入必须是[]byte,且和Add()时的字节序列完全一致——"user:123"和"123"是两个 key,大小写、前缀、编码都不能差一丝一毫 - 如果 key 来自 HTTP 参数且含结构(如 JSON 字符串),建议先哈希再测:
sha256.Sum256([]byte(rawKey)).Sum(nil),避免格式差异导致误判 - 并发场景下
Test()是无锁的,底层读[]byte单字节天然原子,可放心高频调用
filter.Add() 必须与 DB 写入强同步
布隆过滤器不支持删除,也不支持动态扩容,它的可靠性完全依赖「写入即同步」。漏加一个合法 key,真实请求会被误判为不存在;多加一个非法 key,等于主动放行攻击流量。
- 所有写 DB 成功的路径(如
UserService.Create())必须紧跟着调用filter.Add([]byte("user:" + strconv.Itoa(user.ID))) - 确保写 DB 和
Add()在同一个事务或至少是原子性操作:DB 写失败则不Add;Add()失败要告警,不能静默忽略 - 别在初始化阶段只加载历史数据就完事——新注册用户、新上架商品等增量数据,必须走同一路径写入 filter
- 并发写入
Add()时必须加锁:sync.RWMutex的Lock()包一层
选库、建模与内存控制
别自己手写,优先用 github.com/yourbasic/bloom。手写容易在哈希函数分布、位图索引计算、字节对齐上出错,导致误判率远高于理论值,甚至 panic。
golang.org/x/exp/bloom 虽轻量但接口受限(只支持 []byte 输入、不暴露哈希策略),且仍在 x/exp 下,不建议用于生产。
- 用
bloom.New(uint64(n), 0.01)直接按预估总量和误判率建模,内部自动算位数组大小和哈希轮数 - 预计总量
n = 5_000_000(500 万用户),就用bloom.New(5_000_000, 0.01);误判率不是越低越好,0.01 是多数业务的甜点值 - 底层层用
[]uint64位图,比bool切片省内存、位操作更快;实测 1000 万 key、1% 误判下内存约 16MB,吞吐 >5M ops/sec - filter 实例必须声明为包级变量,初始化一次,全服务共用;不能每次 new,也不能存 Redis 或序列化到磁盘——网络 IO 和反序列化开销会成瓶颈
空值缓存必须配合布隆使用,且类型显式
布隆说「可能存在」,你得继续查缓存;缓存 miss 后查 DB 仍为空,这时空值缓存是第二道防线。但它极易因类型混乱失效。
- 绝对不要传
nil给redis.Set():Go-Redis v9 会存成空字符串或 panic,后续redis.String()解包失败,业务逻辑直接崩 - 统一用结构体兜底,例如:
type Null struct{};查不到时json.Marshal(Null{})再写入 - 读取后用
if _, ok := val.(Null); ok判断,避免类型混淆 - TTL 要短(建议
2 * time.Second到5 * time.Second),防止恶意 key 长期占内存 - 所有空值缓存必须走和正常值相同的序列化路径(如都过
json.Marshal)
最容易被忽略的是 key 格式一致性——写时用 "user:123",查时也必须用 "user:123",别一个用 int 转 string,另一个直接拼接 raw int;还有就是 Add() 漏掉任意一条写 DB 路径,防护就形同虚设。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











