前面聊到,修改数据时,缓存和数据库,不管先操作哪个,都会有潜在的数据不一致问题。怎么解决呢?

前文阅读:《先操作缓冲,还是先操作数据库?》

问题分析

如图:1和2并发请求,1要将用户的余额从200修改为100,2读取用户余额。

cache数据库_cache-cache夏津有嘛_4,(填空)一个n路组相联映像的cache中,共有m块数据

假设先操作缓存,后操作数据库,由于无法保证时序,可能出现:

(1)写请求淘汰了缓存

(2)写请求操作了数据库,将用户余额改为100

(3)主从同步没有完成,读请求读了缓存(cache miss)

(4)读请求读了从库(读了一个旧数据:余额200)

(5)读请求set缓存:用户余额200

(6)数据库主从同步完成

最终,数据库中的用户余额为100,而缓存的用户余额为200,数据库和缓存的数据不一致。

如果改为先操作数据库,问题依然存在。因为无法保证读写请求的时序,可能出现:

(1)写请求操作了数据库,将用户余额改为100

(2)写请求淘汰了缓存

(3)主从同步没有完成,读请求读了缓存(cache miss)

(4)读请求读了从库(读了一个旧数据:余额200)

(5)读请求set缓存:用户余额200

(6)数据库主从同步完成

最终,数据库和缓存的数据不一致。

可见,和先操作谁无关。问题的根本原因在于:数据库的主从不一致。当主库上发生写操作之后cache数据库,在从库同步数据的时间间隔内cache数据库,读请求可能导致有旧数据入缓存。

cache-cache夏津有嘛_cache数据库_4,(填空)一个n路组相联映像的cache中,共有m块数据

优化方案

方案一:设置缓存过期时间

很多业务是允许一段时间内数据不一致的,比如:朋友圈文章的点赞数。新的点赞数,不及时看到也没问题。这时,只需要设置一个缓存过期时间,比如10分钟。那么10分钟之后,再发起读请求,会cache miss,这时重新从数据库加载数据到缓存,两边的数据就一致了。

付出的代价是每隔一段时间,都会cache miss一次,哪怕这期间数据没有发生修改。

如果业务能够接受,推荐用这个最简单的方案,别把系统架构搞得太复杂。

方案二:订阅binlog,删“脏”数据

4,(填空)一个n路组相联映像的cache中,共有m块数据_cache数据库_cache-cache夏津有嘛

如图,在并发读写导致缓存中读入了脏数据之后:

(6)主从同步

(7)通过工具订阅从库的binlog,从而能够准确的知道,从库数据同步完成的时间

订阅工具可以是DTS,cannal等,也可以自己订阅和分析binlog

(8)从库执行完同步,向缓存再次发起删除,淘汰这段时间内可能写入缓存的“脏”数据,此后两边数据一致。

思路比结论重要,希望能对你有所启发。

关注【老张聊架构】,前迅雷大数据CTO,带您成为百万年薪架构师!

———END———
限 时 特 惠:本站每日持续更新海量各大内部创业教程,一年会员只需128元,全站资源免费下载点击查看详情
站 长 微 信:jiumai99

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注