1. 缓存穿透
当一个数据在数据库与缓存中都不存在,此时有大量的请求来访问该数据,会导致所有的请求都直接到达数据库,造成数据库系统崩溃。
解决方案
(1). 从数据库中未找到数据,就返回null,存储到缓存中,并对key设置较短的过期时间。
(2). 布隆过滤器【推荐】
它能非常快的判断出一个元素是否存在于海量数据的集合中。
布隆过滤器的实现请查看该博客:点击
2. 缓存击穿
大量的并发请求访问一个热点key,恰巧热点key过期了,后面的请求直接到达数据库,造成数据库系统崩溃。
解决方案:
(1). 加互斥锁
(1). 热点key永不过期。
永不过期有俩种含义:
- 物理上永不过期:针对热点key不设置过期时间。
- 逻辑上永不过期:将key的过期时间添加到value中,每次获取key都判断是否过期,若过期,就启动一个异步线程更新key的value值。
3. 缓存雪崩
同一时间有大量的key过期,后面的请求都直接到达数据库,造成数据库系统短时间内承受了大量的请求而崩溃。它与击穿不同的是,击穿由于一个热点key过期导致的,雪崩由于一批key过期导致的。
解决方案:
(1). 加互斥锁
(2). 热点key永不过期
(3). key的过期时间均匀分配(预防同一时间有大量key过期)。
(4). 加二级缓存(使用memacached作为二级缓存,需要考虑一级、二级缓存的数据同步问题)。
4. 缓存预热
当系统上线时,提前将热点数据加入缓存,避免上线后有大量的请求过来,直接到达数据库,造成数据库崩溃。
解决方案:
(1). 数据量小时,写个页面,手动添加数据到缓存中。
(2). 数据量大时,系统启动时,加载数据到缓存中。
(2). 数据量非常大时,启动定时器添加数据到缓存中。