数据库和缓存一致性个别分为两类,最终一致性和强一致性。

最终一致性

名词解释:db更新后通过一段时间后要求能拜访到更新后的数据,是最终一致性。
实用场景:对于实时性要求不是很高的业务。

计划一:

读取:先从缓存读取,读取不到则读取db,而后写入缓存。

写入/更新/删除:先写db,再写入/更新/删除缓存。

可能遇到的问题:T0时刻申请A读取的时候缓存为空,从db读取数据,T1时刻申请B更新了DB和缓存,T2时刻更新了缓存,T3时刻申请A将老数据写入缓存,此时缓存数据为脏数据。

计划二

读取:先从缓存读取,读取不到则读取db,而后写入缓存。

写入/更新/删除:先写入/更新/删除缓存,再更新db。

可能遇到的问题:T0时刻申请A读取的时候缓存为空,从db读取数据,T1时刻申请B删除了缓存,T2时刻申请A将老数据写入缓存,T3时刻申请B更新了缓存,此时缓存数据为脏数据。

对于计划一二,既然先更新缓存和数据库都不行,那是否给更新db和缓存的整体操作中加上锁呢,确实能够,然而这样读取也须要加锁,会影响性能,除非是一致性要求很高的场景,不然不倡议这样应用。

计划三:

读取:从缓存读取,读取不到则返回空。
写入/更新/删除:更新db再更新缓存,仍然会有不同申请造成的并发问题,除非把更新db和缓存的整个操作加锁,不过会有性能问题,而且若更新db胜利,更新缓存失败,会有脏数据。

计划四:

读取:从缓存读取,读取不到则返回空。

写入/更新/删除:先更新db,异步音讯更新缓存,音讯里加上数据更新工夫作为版本号,消费者加锁生产音讯,缓存数据也存储工夫戳,依据工夫戳判断是否须要进行更新,若缓存为空则间接写入。

可能遇到的问题:
1.若先更新再删除,消费者先生产到了删除申请,再生产到更新申请,则缓存为脏数据。
2.工夫戳精度不够示意版本号。
3.更新db胜利,发送音讯失败。

解决方案:
1.加上isDel字段,删除操作视为更新操作,只是将isDel字段置为true。待缓存主动过期删除。
2.须要依据业务场景选取字段,或者在db加上版本号。
3.发送音讯失败记录音讯到本地音讯表,定时工作轮询重发。

强一致性:

名词解释:对于关系型数据库,要求更新过的数据能被后续的拜访都能看到,是强一致性。
实用场景:对于实时性要求比拟高的业务。

计划一:

读取:先从缓存读取,读取不到则读取db,而后写入缓存。
写入/更新/删除:先写入/更新/db,再删除缓存。
可能遇到的问题:

1.如图,查问操作在db更新后查问的还是老数据。


2.和最终一致性的计划一一样,查问操作查问数据时缓存不存在,从db写入老缓存缓存,导致缓存存在脏数据。

计划二:

新增/批改/删除: 将更新db和删除缓存整体操作加锁lock1。
查问:查问时先判断锁lock1是否存在,若锁存在则读取db并返回数据,锁不存在间接查问缓存,若缓存存在则间接返回后果,缓存不存在同样加锁lock1,执行查问db和更新缓存操作,这样能够保障强一致性。