缓存穿透是指在缓存中查询大量不存在的数据,导致无效请求直接落到后端数据库,从而造成数据库负载过高,甚至引起数据库超负荷的情况。缓存穿透通常发生在恶意攻击或非法请求的情况下,攻击者故意查询不存在的数据,导致大量无效请求直接访问数据库。
解决方案:
不存在的key也维护:
对于那些经常被查询但实际不存在的数据,可以将其作为特殊的缓存对象,存储在缓存中,即使这些数据在后端数据库中不存在。
同时,为了避免缓存数据过多积累,可以为这些不存在的key设置较短的过期时间,确保缓存中的无效数据会被及时清理。
使用布隆过滤器:
布隆过滤器是一种快速判断元素是否存在于集合中的数据结构。可以将大量的缓存键放入布隆过滤器中,当查询请求到来时,先通过布隆过滤器判断该key是否存在。
如果布隆过滤器判断key不存在,直接返回缓存未命中,避免无效的数据库查询。如果布隆过滤器判断key可能存在,再去查询缓存或数据库进行进一步的验证。
入口校验:
在应用程序的入口处进行参数校验,对于非法的请求直接拦截并返回错误信息,避免无效请求进入后端数据库。
可以校验请求的参数是否符合规范,例如检查请求的key是否为空或长度是否合法,对于非法的请求直接拒绝。
实际案例:
在一个在线商品查询的系统中,用户可以通过关键字搜索商品信息。攻击者利用该功能,通过查询大量不存在的商品关键字,导致大量无效的查询请求直接访问后端数据库,造成数据库超负荷。
为了解决这个问题,系统采取了以下措施:
不存在的key维护:对于经常被查询但实际不存在的商品关键字,系统将其作为特殊的缓存对象存储在Redis中,并设置了较短的过期时间,确保缓存中的无效数据会被及时清理。
布隆过滤器:将商品关键字放入布隆过滤器中,对于查询请求,先通过布隆过滤器判断关键字是否可能存在,如果可能不存在,则直接返回缓存未命中,避免无效的数据库查询。
入口校验:在接收查询请求时,先进行参数校验,对于非法的商品关键字请求,直接拦截并返回错误信息,避免无效请求进入后端数据库。
通过以上措施,系统成功解决了缓存穿透问题,保证了数据库的稳定性和性能。同时,系统在后续的设计中,对于其他可能出现缓存穿透的关键数据,也采取了类似的策略进行处理,提高了系统的安全性和可靠性。