缓存穿透则指的是由于缓存和数据库都不存在数据,导致请求永远不会止步于缓存,每次都会打到DB,缓存就跟透明的一样。
- 这可能会被不怀好意的人利用,大量请求不存在的key频繁攻击我们的数据库;
- 或者在高并发场景,我们要查询的数据刚好不在数据库中,缓存中也没有,也会导致DB压力增加。比如大促场景,商品突然被误删了,或者用户注册场景校验用户名是否存在的时候,如果缓存设计不合理,很可能导致大量请求查库。
我们可以通过如下的措施,避免缓存穿透:
- 使用Bloom Filter校验数据是否存在,从而阻挡大部分流量。例如用户注册用户名校验场景,可以把用户名存在的状态在Bloom Filter中 设置为1,这样就可以快速判断用户名是否存在了。
- 要注意的是:Bloom Filter判定不在的数据一定不存在,存在的数据不一定存在。对于不存在的数据误判为存在的情况,需要评估业务是否接受这种结果,对于注册业务来说影响不大。
- 缓存空结果。如果我们要读取的不仅仅是二状值,而是一个完整的数据,那么就可以把空结果也缓存起来,从而让不存在的数据也走缓存;
- 对于恶意请求,我们则可以多从网关层下功夫,比如设置限流避免同一个IP大量请求到服务器,入参合法性校验等。