数据库和缓存一致性问题

前言

缓存一致性是指业务在引入分布式缓存系统后,业务对数据的更新除了要更新存储以外还需要同时更新缓存,对两个系统进行数据更新就要先解决分布式系统中的隔离性和原子性难题。目前大多数业务在引入分布式缓存后都是通过牺牲小概率的一致性来保障业务性能,因为要在业务层严格保障数据的一致性,代价非常高,业务引入分布式缓存主要是为了解决性能问题,所以在性能和一致性面前,通常选择牺牲小概率的一致性来保障业务性能。为了减轻数据库压力,高效读,引入缓存。方便的同时也带来数据库和缓存之间数据的一致性问题。

1. 缓存的使用

1.1 缓存获取

引入缓存层后,读数据就变得不是那么简单直接了,APP 需要先去缓存读取数据,如果缓存 MISS(数据没有被缓存),则需要从存储中读取数据,并将数据更新到缓存系统中,整个流程和代码如下所示:

缓存更新

1.2 业务层缓存更新

是先操作缓存还是先操作数据库。是通过删除缓存的方式然后读取时更新还是更新缓存的方式。如何保证原子性,一致性,隔离性。

这里我们面临的问题本质上是一个数据库的分布式事务的问题,需要处理数据可靠性的挑战,并发更新带来的隔离性挑战,和数据更新原子性的挑战。

数据可靠性

如果要保证数据的可靠性(保证数据库内数据一定正确),在业务逻辑成功之前,必须保障有一份数据落地,我们有以下两个选择:

  • 先更新成功存储,再更新缓存;
  • 先更新成功缓存,再跟新存储,如果存储更新失败,删除缓存;

操作隔离性

一条数据的更新涉及到存储和缓存两套系统,如果多个线程同时操作一条数据,并且没有方案保证多个操作之间的有序执行,就可能会发生更新顺序错乱导致数据不一致的问题。

更新原子性

引入缓存后,我们需要保证缓存和存储要么同时更新成功,要么同时更新失败,否则部分更新成功就会导致缓存和存储数据不一致的问题。

方案如下进行比较:

1.2.1 更新缓存 更新数据库

1.2.2 删除缓存 更新数据库

前面两种都是先操作缓存再操作数据库的。不推荐先操作缓存,因为先操作缓存如果缓存更新

1.2.3 更新数据库 更新缓存

1.2.4 更新数据库 删除缓存

更新数据库 然后删除缓存 等待下次读的时候miss进行更新缓存,也是推荐方案。

为何通过删除缓存的方式而不是更新缓存的方式?积极更新策略,缓存数据实时性更高,但是在缓存侧带来了更多的更新操作,这会提高更新冲突导致脏数据概率。

比如:

总结

References

posted @ 2020-10-31 23:44  胖大星-  阅读(309)  评论(0编辑  收藏  举报