高性能缓存实践-缓存穿透
目标
缓存穿透
缓存穿透:大量的客户端请求,参数都是无效的,导致直接穿过缓存,直接查询数据库。需要将这些无效的请求参数,过滤,不直接查询数据库,减少数据库的压力。提供正常请求的响应率。
解决方法:
- 定义校验规则,对恶意数据进行过滤,直接阻断,防止请求到数据库层。
- 缓存空值,将无效的参数结果缓存起来,下次有相同的参数,可以直接返回空值。为了避免占用过多的内存,可以设置较短的时间间隔。
- 布隆过滤器,根据算法,可以判断查询数据是否一定不存在或者存在。
缓存空值
对于非法参数请求,通过前端后端的参数校验,直接阻断请求。
使用spring boot cache 默认是缓存null结果的。
布隆过滤器
思路:将可能的查询参数,也就是缓存的key,都存储在布隆过滤器中,在请求达到后,先判断该请求参数,是否在布隆过滤器中,不存在,直接响应。不再查询数据库。
问题
解决缓存穿透有什么方式?优缺点是什么?
-
缓存空值
缓存空结果,超时时间应该设置的比一般缓存短。
缺点:如果是恶意用户,一直请求无效切不重复的参数,每个空值对应的key,也只出现一次,缓存穿透依然存在。
-
布隆过滤器
将存在的key,都存储在布隆过滤器
优点:能存储海量数据,并且消耗的资源少(内存,磁盘),鉴别key是否存在的效率非常高。
缺点:
1,代码复杂度增大,
2,需要将所有的缓存的key都存放到布隆过滤器中。
3,布隆过滤器不支持删值操作。
随着数据的增加,误判率随之增加;无法做到删除数据;只能判断数据是否一定不存在,而无法判断数据是否一定存在。
为什么使用布隆过滤器存储缓存的key?
基于布隆过滤器的算法,能在海量数据中判断某个数据是否存在,判断效率非常高,占用的存储空间很小。
Redis 布隆过滤器使用了redis 的那种数据结构?
参考:大白话布隆过滤器
一看就懂系列之 详解redis的bitmap在亿级项目中的应用
bitmap