Redis——关于数据库与缓存数据一致性
用「读 + 写」请求的并发的场景来分析。
假如某个用户数据在缓存中不存在,请求 A 读取数据时从数据库中查询到年龄为 20,在未写入缓存中时另一个请求 B 更新数据。它更新数据库中的年龄为 21,并且清空缓存。这时请求 A 把从数据库中读到的年龄为 20 的数据写入到缓存中。
即:请求A——缓存未命中;读取数据库中的值为20;将20回写缓存
请求B——更新数据库为21;删除缓存
采用 Cache Aside 策略,即写策略先更新数据库,再删除缓存中的数据。
虽然从理论上分析也会出现数据不一致情况(该用户年龄在缓存中是 20(旧值),在数据库中是 21(新值)),但概率不高。
因为缓存的写入通常快于数据库的写入,实际上很难出现请求B已更新了数据库并删除了缓存,请求A才更新完缓存的情况。
而请求A早于请求B删除缓存之前更新了缓存,那么接下来的请求会因缓存不命中重新向数据中获取数据,所以不会出现这种不一致的情况。
如果业务对缓存命中率有很高的要求,我们可以采用 更新数据库 + 更新缓存 的方案,因为更新缓存并不会出现缓存未命中的情况。
在两个更新请求并发执行的时候,会出现数据不一致的问题,因为更新数据库和更新缓存这两个操作是独立的,而我们又没有对操作做任何并发控制,那么当两个线程并发更新它们的话,就会因为写入顺序的不同造成数据的不一致。
解决数据不一致的两种做法:
- 在更新缓存前先加个分布式锁,保证同一时间只运行一个请求更新缓存,就会不会产生并发问题了,当然引入了锁后,对于写入的性能就会带来影响。
- 在更新完缓存时,给缓存加上较短的过期时间,这样即时出现缓存不一致的情况,缓存的数据也会很快过期,对业务还是能接受的。

浙公网安备 33010602011771号