Redis缓存更新方案:
先更新数据库,再更新缓存
策略:
并发请求A、B。
A请求先更新数据库的值为1,然后在更新缓存前,请求B将数据库的值更新为2,紧接着也把缓存更新为2,然后A请求更新缓存为1。于是出现数据库缓存不一致,数据库为2,缓存为1
问题:存在并发更新同一条数据时,可能会出现数据库缓存不一致现象
先更新缓存,再更新数据库
策略:
并发请求A、B。
A请求先将缓存数据更新为1,然后在更新数据库前,B请求将数据库的值更新为2,紧接着将数据库更新为2,此时A请求将数据库的数据更新为1。于是出现了数据库缓存数据不一致
问题:存在并发更新同一条数据时,可能会出现数据库缓存不一致现象
先删除缓存,再删除数据库(Cache Aside 旁路更新策略①)
策略:
并发请求A、B。
请求A要将数据库值更新为21,所以请求A会删除缓存,此时请求B要读取该值,它查询缓存后没有命中,会从数据库中读取原值20,并写入到缓存中,然后请求A继续更改数据值为21。此时依然会出现数据库缓存不一致的现象
问题:
不更新缓存,而是删除缓存,然后后读取数据时,发现缓存中没有数据,在从数据库中读取数据更新到缓存中。分为【读策略】和【写策略】
写策略步骤:更新数据库数据,删除缓存中的数据
读策略步骤:如果读取的数据命中缓存,则直接返回数据;如果没有命中则从数据库中读取数据,然后更新缓存并返回
先更新数据库,再删除缓存(Cache Aside 旁路更新策略①)
策略:
并发请求A、B。
请求A查询某个值(假设缓存中不存在),此时请求A从数据中查询到值为20,在未写入缓存时请求B更新该值,先将数据库更新为21,并删除缓存。这是请求A把从数据库中读取到的数据20写入缓存。最终还是可能出现数据库缓存不一致的现象。
概率较低,缓存速度理论上不会出现该问题,但若删除缓存失败会导致缓存不一致。
问题:
不更新缓存,而是删除缓存,然后后读取数据时,发现缓存中没有数据,在从数据库中读取数据更新到缓存中。分为【读策略】和【写策略】
写策略步骤:更新数据库数据,删除缓存中的数据
读策略步骤:如果读取的数据命中缓存,则直接返回数据;如果没有命中则从数据库中读取数据,然后更新缓存并返回
问题解决方案:
原因:
两步操作,没有并发控制,因此遇到并发场景时,由于执行顺序不同导致数据不一致
方案:
分布式锁
同一时间同一数据只由一个请求操作更新缓存
过期时间
数据不一致 兜底方案
保证数据库与缓存两个操作均成功
- 重试(如@Retryable)
- 订阅MySQL binlong,异步操作缓存(Canal,MQ)
注解:
①Cache Aside 旁路更新策略(不保证数据一致性)
释义:更新数据时,不更新缓存,而是删除缓存中的数据,在读取数据时,发现缓存中没有,再从数据库中读取数据,更新到缓存中。