MySQL和缓存如何解决一致性_高并发下缓存和数据库一致性问题

一、问题描述

正常的缓存步骤是:

1、查询缓存数据是否存在

2、不存在即查询数据库

3、将数据添加到缓存同时返回结果,

4、下一次访问发现缓存存在即直接返回缓存数据。

那么当更新数据库数据的时候,该如果更新缓存呢,至少要考虑尽量短时间的一致性,这个看业务需求,比如用户信息缓存时间越短越好,比如排行榜可能是一天更新一次,本文纯技术讨论,就是尽量缩短非一致性的时间以此来学习思路。

二、当更新数据库时候,缓存应该如何更新

1.1、更新缓存VS淘汰缓存

更新缓存很直接,但是涉及到本次更新的数据结果需要一堆数据运算,复杂度就增加了。而淘汰缓存仅仅会增加一次cache

miss,代价可以忽略,所以建议淘汰缓存

1.2、先淘汰后写数据库vs先写数据库后淘汰

先写后淘汰,如果淘汰失败,cache里一直是脏数据

先淘汰后写,下次请求的时候缓存就会miss

hit一次,这个代价是可以忽略的,(如果淘汰失败return false)

综合比较统,推荐先淘汰缓存再写数据库,下次请求直接从数据库取然后再写在缓存里。(当然这里可能会大并发一起击穿(通过下面1.3的方式可以解决),还有在淘汰缓存再写数据库的这一瞬间,再来一个读取请求,这个读取比上一个请求的写先完成,那么就会出现脏数据。网上有人说

修改数据库的连接池方法,就是对于同一个ID的数据请求,比如query(id),edit(id)都使用同一个连接对象,这样来保证先来的先完成,貌似还是挺复杂的,关于后来的读取请求先与先来的写请求完成,只能通过这样的串行方式执行

关于脏数据,如果需要强一致性

1、可以通过数据库无论是读或写操作都是通过一个请求db

connection连接完成(目的是串行),这样就需要修改连接池

2、可以采用更新缓存而不是淘汰缓存,前提是更新的代价比较低

3、可以先更新数据库再淘汰缓存,不过一般情况,淘汰缓存失败的可能性很小,可以以缓存处理100%不失败为前期。

4、双淘汰发,即:淘汰缓存-更新数据库-淘汰缓存,可以尽量减少脏数据的留存时间

5、以上实现起来,要么极短时间的不一致要么一致性代价比较高,实际项目我会这样处理,更新数据库的地方和读取的地方上同样key的分布式锁,这样就能保证,先操作(或读或写)数据的先获得结果,实际中这样的强一致需求比较少,参考思路即可。

当然数据既然都缓存起来了,绝大部分都不要求强一致性,为了尽可能的缩短一致性的时间,可以如下处理:

6、异步消息总线esb更新法,即:修改数据库往消息总线里发送一个消息,在接收端去处理这个消息更新缓存,缺点是有代码入侵

7、异步binlog扫描更新法,增量的去扫描binlog中的修改记录,符合条件的更新缓存,相比消息总线法没有代码入侵

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值