一、缓存
1.缓存穿透
概述:
缓存穿透是指在使用缓存系统时,大量请求查询不存在于缓存中的数据。当请求到达缓存系统时,系统发现需要查询的数据不存在于缓存中,于是将请求转发到后端数据库进行查询,然后将查询结果返回给用户,并将查询结果存入缓存中。然而,如果大量请求查询的数据都不存在于缓存中,就会导致大量的请求都转发到后端数据库,增加了数据库的负载,降低了系统性能。这种情况被称为缓存穿透。
解决方法:
1.把不存在的数据null存到缓存,缺点是比较容易给缓存造成压力
2.布隆过滤器,用位图来把存在的数据在数组里面改为1,缺点是存在误判
2.击穿
概述:
缓存击穿是指一个存在于缓存中的热点数据,在某个时刻失效的情况下,同时有大量的请求访问这个数据。当缓存中的数据失效后,新的请求访问这个数据,发现缓存中没有了这个数据,于是会将请求转发到后端数据库进行查询。这时由于大量请求同时访问数据库,导致数据库负载增加,甚至可能出现数据库宕机的情况,从而导致系统性能下降。
与缓存穿透不同,缓存击穿是指已经存在于缓存中的数据失效导致的大量请求转发到后端数据库。为了避免缓存击穿,可以使用互斥锁或者分布式锁来保证在缓存失效时只有一个请求能够访问数据库,其他请求等待该请求的操作完成后再从缓存中获取数据,或者可以使用热点数据预加载策略,在热点数据失效之前提前刷新缓存数据。
方法:
1.互斥锁,一个线程在获取数据时发现数据过期,会添加互斥锁,在锁释放之前其它线程只能等待线程一获取到数据并存入缓存释放锁之后拿到数据,保证数据强一致性,性能差
2.逻辑过期,和互斥锁很像,只不过其他线程拿不到锁不会等待,会直接返回旧数据,线程一也一样,拿到锁之后会新开一个线程去获取数据存入缓存,原来线程也会返回旧数据,保证高可用,性能好
3.雪崩
缓存雪崩是指在某个时间段内,缓存中的大部分数据同时失效或者由于某种原因导致无法访问,使得所有的请求都直接访问后端数据库。这种情况下,后端数据库会承受巨大的压力,容易导致数据库性能下降甚至崩溃,从而导致系统不可用。
造成缓存雪崩的原因可能有多种,如缓存服务器宕机、缓存设置了相同的失效时间、缓存节点故障等。当大量的请求无法从缓存中获取数据时,都会直接访问后端数据库,导致数据库负载激增。
为了避免缓存雪崩,可以采取以下措施:
- 设置不同的缓存失效时间,避免大量数据在同一时间失效。
- 使用分布式缓存,将数据分散在不同的缓存节点中,降低单点故障风险。
- 实时监控缓存系统的状态,及时发现和修复故障。
- 使用熔断机制,当缓存失效时,限制对数据库的访问,避免数据库负载过大。