双重判定锁解决缓存击穿
出现原因
热点数据过期导致大量的请求会同时查询后端数据库。
对于一个之前从未被请求过的数据,当它第一次被请求时,缓存中没有这个数据,从而导致请求穿透到后端存储。
解决方案
设置热点数据永不过期:
对于一些热点数据,可以将其设置永不过期
但是这些数据将长期占据缓存空间,可能导致缓存资源无法被有效利用。如果后台数据库中的数据发生变化,而缓存中的数据未能及时更新,就会导致数据不一致的问题。
使用互斥锁:
在获取数据时,使用分布式锁(如 Redis 的分布式锁)来控制同时只有一个请求可以去后端获取数据,其他请求需要等待锁释放。这样可以防止多个请求同时穿透到后端存储,有效地避免了缓存击穿问题。
但还有一个问题就是,假如 有1w 的请求读取一个缓存,只有一个线程会执行逻辑请求数据库并放入缓存。剩下的请求全部在等待获取分布式锁。但即使剩下的请求获取到了锁,还是会继续请求数据库。
这会对数据库造成无用的性能浪费,因为这 100w 的请求,只有第一次是有效的。
而且还会造成用户响应时间变长,接口吞吐量下降。
因此我们可以做双重判断
获取分布式锁后,在查询数据库之前,再次检查一下缓存中是否存在数据。如果缓存中存在数据,说明之前已经有线程将数据库中的数据加载到缓存中了,不需要继续从数据库中读取,直接返回缓存中的数据;如果不存在,才继续执行查询数据库的操作。
这样不仅减少数据库访问压力,还降低用户响应时间
双重判定锁解决缓存击穿
https://xichicheng.github.io/2024/11/20/双重判定锁解决缓存击穿/