首页 > 数据库 >数据库缓存数据一致性保证

数据库缓存数据一致性保证

时间:2023-02-14 11:36:44浏览次数:53  
标签:缓存 数据库 db 更新 缓存数据 一致性 数据

一、背景

在本文正式开始之前,需要先取得以下两点的共识:

a) 缓存必须要有过期时间

b) 保证数据库跟缓存的最终一致性即可,不必追求强一致性。

数据一致性指的是:

a) 缓存中存有数据,缓存的数据值 = 数据库中的值;

b) 缓存中没有该数据,数据库中的值 = 最新值

数据库跟缓存,毕竟是两套系统,如果要保证强一致性,势必要引入 2PC 或 Paxos 等分布式一致性协议,或者分布式锁等等,这个在实现上是有难度的,而且一定会对性能有影响。

在使用缓存时,通常有以下几种缓存使用策略用于提升系统性能:

1、读:

1)先读缓存,hit -> 返回数据
2)miss -> 从db中取出数据,放入缓存,同时返回数据

缺点:

由于数据仅在缓存未命中后才加载到缓存中,因此初次调用的数据请求响应时间会增加一些开销,因为需要额外的缓存填充和数据库查询耗时。

2、写(insert):

先写db后写缓存,db返回成功时,再写缓存。原因:
如果先写缓存,后写db,写db失败时,会导致只有缓存有数据,db无数据。数据库都不存在的数据,缓存存一份已经没意义了可视为脏数据。

3、写(update):
先更新db后删除缓存,为什么是删而不是更新缓存?
更新缓存在高并发下有可能出现脏数据:比如两个线程a,b先后到来,

1)a先更新db成功,在更新缓存时网卡了

2)b后更新db成功,并成功更新缓存

3)此时a才开始更新缓存,覆盖了b的数据

3.1、先更新db还是先删缓存?

1)如果先删缓存再更新db:假如删缓存成功了,更新db失败了,那么db中还是旧的值,缓存中无数据还会从db中拿到旧的值写到缓存里,pass此方案

2)如果先更新db再删缓存:如果删缓存失败了,可以使用重试机制,mq中异步重试

3.2、先更新db后删缓存也会存在一些问题:

1)更新db成功,删缓存失败,在重试的过程中有读取请求进来,读到的还是旧数据

2)在高并发下有可能出现脏数据,比如缓存过期时间到了,已经失效,此时两个线程读请求a,写请求b先后到来

a、读请求a发现缓存没数据,从db中读取数据,写缓存时网卡了

b、写请求b顺利的更新db删除缓存

c、此时读请求a恢复了,完成写缓存,把旧的值写入了缓存,此时缓存和db的数据已经不一致了

不过这个情况很难出现,因为数据库读操作是远快于写操作的(正是因为如此,才做读写分离),所以步骤b比步骤a更快不太可能出现,同时还要配合缓存刚好失效。

 

参考:https://mp.weixin.qq.com/s/r8VeAKkjMeResc4kKEovHw

 

标签:缓存,数据库,db,更新,缓存数据,一致性,数据
From: https://www.cnblogs.com/MarkLeeBYR/p/17118995.html

相关文章