前言
从理论上来说,给缓存设置过期时间,是保证最终一致性的解决方案。这种方案下,我们可以对存入缓存的数据设置过期时间,所有的写操作以数据库为准,对缓存操作只是尽最大努力即可。也就是说如果数据库写成功,缓存更新失败,那么只要到达过期时间,则后面的读请求自然会从数据库中读取新值然后更新缓存。
因此,接下来讨论的思路不依赖于给缓存设置过期时间这个方案。
先更新数据库,再更新缓存
一、线程安全问题
假设同时有请求A和请求B进行更新操作,那么会出现如下情景
- 线程A更新了数据库
- 线程B更新了数据库
- 线程B更新了缓存
- 线程A更新了缓存
正确结果应为缓存A数据,但是因为网络原因或者其他原因,导致缓存了B数据,出现脏数据问题。
二、使用场景问题
- 若写请求较多,读请求较少,导致缓存数据被频繁更新,浪费性能。
- 若缓存数据由数据库数据计算得来,则每次写库都要耗费CPU性能做计算更新缓存,浪费性能。
综上,先更新数据库,再更新缓存不适用于作为redis缓存一致性解决方案。
先删缓存,再更新数据库
一、问题
假设同时有请求A进行更新操作和请求B进行读取操作,那么会出现如下情景