开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天,点击查看活动详情
MySQL读写分离详解
前言
什么是读写分离,读写分离就是对数据库的查询操作、插入和更新操作分别对应到不同的数据库节点上,这样可以提高数据库的写性能和读性能。例如,我们有一台数据库master,还有一台数据库slave,我们所有的查询操作全部对slave数据库进行操作,全部的插入、更新操作对master数据库进行操作,master数据库和slave数据库之间会进行主从同步。master主要负责写入数据,slave主要负责读取数据。
读写分离主库和从库读取数据不一致?
原因
在实际应用中,master数据库和slave数据库进行主从同步就一定会耗费时间,在这段时间里面,主库的数据和从库的数据就会不一致,如果此时读取从库的数据库,数据就是不准确的。
解决
- 在操作主库之后强制将读数据的请求转发到主库进行处理。
我们经常使用的Sharding-JDBC数据库中间件就是这种方式,将读数据的请求全部使用主库进行操作,但是这种方式会增加主库的压力。
- 增加延迟
我们可以在需要立即读取数据的操作前增加延迟,例如我们需要在付款之后立即更新当前账户的余额,我们可以在付款成功之后,弹出付款成功的页面,在页面上我们点击返回或者关闭才返回到我们的账户,此时才可以查看到我们的账户余额,此时数据库的主从同步基本也会完成,或者增加请求延迟,不过这种方式会降低用户的体验感。
- 客户端保存
客户端保存相应的列表数据或者缓存数据,例如修改后的文章,需要设置缓存的时间,预估主库之间同步的时间,该方法对客户端的逻辑处理要求较高,并且客户端不能保存大量的数据。
- 缓存标记
在写请求发起后,在缓存中设置标记,并且设置失效时间,失效时间就是预估的主库之间同步的时间,在发起读请求是,先判断标记是否存在,标记存在,直接走主库,标记不存在,走从库。与缓存之间需要频繁交互,会影响性能。
- 本地缓存标记
在写请求发起之后,本地设置一个标记,下次的读请求带上这个标记,后端判断,有这个标记,走主库,没有这个标记,走从库。这个方案会导致其他用户暂时会看不到这个新的数据,但是时间比较短,在数据库主库和从库同步之后,其他用户再刷新就能看到这个数据了,对于自己修改或者新增加的数据,其他用户过几秒钟看到,是没有任何影响的。
常用的读写分离的数据库中间件
sharding-jdbc、MyCat、MySQL Router