双重判定锁解决缓存击穿

出现原因

热点数据过期导致大量的请求会同时查询后端数据库。

对于一个之前从未被请求过的数据,当它第一次被请求时,缓存中没有这个数据,从而导致请求穿透到后端存储。

解决方案

设置热点数据永不过期:

对于一些热点数据,可以将其设置永不过期

但是这些数据将长期占据缓存空间,可能导致缓存资源无法被有效利用。如果后台数据库中的数据发生变化,而缓存中的数据未能及时更新,就会导致数据不一致的问题。

使用互斥锁:

在获取数据时,使用分布式锁(如 Redis 的分布式锁)来控制同时只有一个请求可以去后端获取数据,其他请求需要等待锁释放。这样可以防止多个请求同时穿透到后端存储,有效地避免了缓存击穿问题。

但还有一个问题就是,假如 有1w 的请求读取一个缓存,只有一个线程会执行逻辑请求数据库并放入缓存。剩下的请求全部在等待获取分布式锁。但即使剩下的请求获取到了锁,还是会继续请求数据库。

这会对数据库造成无用的性能浪费,因为这 100w 的请求,只有第一次是有效的。

而且还会造成用户响应时间变长,接口吞吐量下降。

因此我们可以做双重判断

获取分布式锁后,在查询数据库之前,再次检查一下缓存中是否存在数据。如果缓存中存在数据,说明之前已经有线程将数据库中的数据加载到缓存中了,不需要继续从数据库中读取,直接返回缓存中的数据;如果不存在,才继续执行查询数据库的操作。

这样不仅减少数据库访问压力,还降低用户响应时间


双重判定锁解决缓存击穿
https://xichicheng.github.io/2024/11/20/双重判定锁解决缓存击穿/
作者
陈兮迟
发布于
2024年11月20日
许可协议