一、Redis
redis作为内存数据存储,我们在网站开发过程中经常用到,极大的提升了程序的访问速度,极大的降低了数据库服务器的压力。一般网站使用没什么问题,在遇到到大流量大并发的时候会出现一些问题。下面讲解常见的三种极端情况及解决办法。
二、缓存雪崩
缓存雪崩是指在某一个时间段,缓存集中过期失效。所有原本应该访问缓存的请求都去查询数据库了,而对数据库CPU和内存造成巨大压力,严重的会造成数据库宕机。从而形成一系列连锁反应,造成整个系统崩溃。
1、原因
大量key同时过期。
2、解决办法
需要防止缓存集中失效,可以采取“过期时间+随机数”的方法,尽量让缓存失效的时间均匀分布,最次也得随机分布,尤其是一些访问大的接口。
同时需要保护好数据库,可以采用“加锁或者队列”的方法,防止大量线程对数据库的一次性进行读写,避免缓存失效时对数据库造成的巨大冲击,但吞吐量就降低了。
三、缓存穿透
缓存穿透指查询一个一定不存在的数据。由于缓存不命中,并且出于容错考虑,如果从数据库查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,缓存失去意义。
1、原因
主要是源于黑客攻击,查询数据库中不存在的数据。
2、解决办法
将空对象记录在缓存中,如果数据库返回信息为null,也可以将这个空对象设置到缓存里边去。下次再请求的时候,就可以从缓存里边获取。
注意:将空对象设置一个较短的过期时间(因为没有意义,存着就是为了防止黑客高频null攻击)
使用布隆过滤器可以有效避免。具体使用方法见附件1。
四、缓存击穿
缓存击穿是指热点key在某个特殊的场景时间内恰好失效了,于是大量并发请求导致数据库压力过大或宕机。
1、原因
热点key过期。
2、解决办法
对于热点key,我们应该将过期时间调长或者永不过期。待热度下降之后再设置成正常过期时间。
附件1:布隆过滤器
1、什么是布隆过滤器
布隆过滤器就是一个很大的位图bitmap。
private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size,0.01);
2、布隆过滤器使用到的技术
(1)hash算法
一般都是哈希取余运算,将数据库中查出来的数据都塞到这个bitmap里,并设置对应的bit字段为1,代表有数据。
(2)容器大小
容器大小是指bitmap的初始容量大小,其内部维护一个全为0的bit数组。
(3)误判率
误判率越低,要求精确度越高,导致数组越大,所占空间越大。误判率越高则数组越小,所占的空间也越小。
(4)作用
用于快速判读某个元素是否存在于集合中,类似于Java中HashSet的功能。
3、布隆过滤器原理
布隆过滤器的关键就在于hash算法和容器大小(容器大小和误判率有关)