1. 缓存穿透
问题描述:
缓存穿透是指在请求一个不存在的数据时,由于数据库和缓存层都没有这个数据,导致请求直接穿透到了数据库访问,当访问量过大时会导致数据库宕机问题。这样的情况通常发生在有人恶意攻击,用一个不存在的数据,如通常索引不为负值,去访问索引为负值的数据的请求会直接穿透到数据库去访问,当数据库资源被耗尽时,就出现问题了。
解决方案:
- 当接收到一个数据库和缓存层都不存在的数据时,可以在缓存层存入一个临时的数据,这样就可以解决缓存穿透导致数据库宕机的情况。
- 严格控制访问的内容格式,如必须用19位的id访问,而不是任意不存在的值都跑到数据库去访问
- 布隆过滤器:布隆过滤器会提供三个生成哈希值的函数,每次访问都会生成三个哈希值,并将其映射到一个固定长度的阵列中的点上,采用的方法是哈希值对阵列长度取模,在对应索引的位置将值设置成1,下次访问的时候会将访问值先通过哈希函数生成哈希值并取模,只要有一个对应索引的位置上值不为1,则说明一定没有该数据,直接被过滤,只有三个对应索引的值都为1才有可能在数据库中存在。不过布隆过滤器也存在误判的可能性,比如当布隆过滤器的阵列长度为2时,误判的概率会非常大,因为只有两个值能设置为1,这个条件非常容易被实现,解决这个方法的问题就是设置足够的长度去满足系统可接受的误差,阵列长度越长,误判概率越小。
2.缓存击穿
问题描述:
缓存击穿是指在缓存层中的热点数据忽然失效,所有访问同时去数据库请求导致数据库宕机的问题。
解决方案:
- 让缓存层中的热点数据永不过期。
- 使用锁,单体架构下使用同步锁,分布式架构下使用分布式锁。
- 缓存预热,采用提前写入缓存或定时更新缓存的办法来防止缓存击穿。
- 热点数据限流或降级查询,可以使用sentinel来实现,限流即当访问量过大时只接受一部分数据去访问,另外一部分被拒绝;降级查询即当短时间的访问量到达降级的要求时采用降级处理,如显示服务器繁忙。
3.缓存雪崩
问题描述:
缓存雪崩指大量的值在同一时间失效了,大量请求访问数据库导致数据库一瞬间宕机的情况。
解决方案
- 同缓存击穿一样可以使用锁来解决。
- 同缓存击穿一样缓存预热
- 可以在缓存层设置过期时间的时候加上一些随机数,让过期时间不一致,大大减小缓存层数据同时失效的可能。