缓存击穿是指在高并发系统中,缓存中不存在但存储层中存在的数据,在某一时刻被大量请求同时查询,导致大量请求落到存储层上,引起数据库压力过大或者宕机的现象。
通常情况下,当一个请求需要查询一个存在于存储层但不在缓存中的数据时,缓存无法命中,会向存储层发起查询请求,这个查询请求可能会因为某些原因(比如过多的请求、热点数据)导致存储层宕机,从而引起缓存击穿。
缓存击穿示意图如下:
-
多个请求同时查询一个不存在于缓存中但存在于存储层中的数据,由于缓存中没有相应的数据,多个请求都会落到存储层进行查询。
-
查询请求发生堆积,存储层负载过高,出现宕机等问题,导致系统响应变慢甚至瘫痪。
-
将热点数据预先加载到缓存中,在第一次查询时就将数据加载到缓存中,避免了对存储层的大量查询请求,从而保证系统响应速度和稳定性。
避免缓存击穿常见的方法包括:
-
加锁:当多个请求同时访问一个不存在于缓存中但存在于存储层中的数据时,可以通过加锁机制,确保只有一个线程去查询存储层,并将查询结果写入缓存中。其他线程在等待同步响应的同时使用缓存数据。
-
数据预热:将一些热门数据预先加载到缓存中,避免由于访问量暴增导致的缓存击穿问题。比如,在系统启动前,可以将热点数据进行加载,或者在非高峰期对热点数据进行周期性更新。
-
使用布隆过滤器(Bloom Filter):布隆过滤器可以快速判断某个键是否可能存在于缓存中,从而避免大量无效的查询操作。如果布隆过滤器判断该键不存在于缓存中,则直接返回缓存未命中。
-
设置热点数据永不过期:将热点数据设置成永不过期,避免数据失效和缓存击穿问题的发生。但需要注意,这种做法可能会带来一定的数据一致性问题。
总之,针对不同的场景和需求,可以采用不同的方法来避免缓存击穿问题。