当前位置:首页 > 公众号精选 > 架构师社区
[导读]MySQL在生成环境中,如果是单机版的部署方式,就会有很大的可用性问题,MySQL提供了一套主从复制的架构,以提高其可用性。MySQL主从复制架构,就是部署两台机器,一台机器上部署的MySQL是master节点,另一台机器上部署的MySQL是slave节点。我们平时可以向mast...

MySQL在生成环境中,如果是单机版的部署方式,就会有很大的可用性问题,MySQL提供了一套主从复制的架构,以提高其可用性。


MySQL主从复制架构,就是部署两台机器,一台机器上部署的MySQL是master节点,另一台机器上部署的MySQL是slave节点。


我们平时可以向master节点读写数据,master节点会把写入的数据自动复制到slave节点去,让slave节点与master节点有一份一样的数据。


图1 MySQL主从复制架构


MySQL的主从复制架构,有一个大名鼎鼎的作用,就是读写分离。


读写分离就是,你的Java业务系统可以向master节点写入数据,但是从slave节点读取数据,读和写分别在不同的机器上。


图2 MySQL读写分离


读写分离的作用是显而易见的,假设MySQL单机每秒抗4000读写请求,1500的写请求 2500的读请求,压力已经到极限了,此时你可以利用读写分离架构,让2500的读请求分流到到slave节点,就会大大降低master节点的压力。


如果随着业务发展,读请求越来越多,一个salve节点也快扛不住读请求了,你可以再部署几个从节点,MySQL主从架构是支持一主多从的。让多个从节点分摊读请求。

图3 MySQL主从复制一主多从



MySQL主从复制的工作原理


MySQL在执行增删改的时候,会记录binlog日志,从库上会起一个IO线程,这个线程会跟master节点建立一个TCP连接,请求master节点传送binlog日志给自己,这个时候master上有一个IO dump线程,会负责通过这个TCP连接,把binlog日志传输给slave的IO线程。


然后,slave节点的IO线程会把读取到的binlog日志写入到自己本地的relay日志文件里去,然后从库上另外一个线程会读取relay里的日志,进行日志重做,把所有在master上执行的增删改操作在slave上也执行一遍。


图3 MySQL主从复制原理


简单来说,你只要给master挂上一个slave节点,slave节点的IO线程就会跟master节点建立网络连接,然后请求master节点传输binlog日志,master节点的IO dump线程就负责传输binlog日志给从节点,从节点收到日志后就可以回放增删改操作恢复数据了。


canal就是把自己伪装成slave,利用同样的同步机制,把master节点binlog同步过去的。


通常master节点复制数据到slave节点,有几种方式。


(1)异步复制


master把日志写入binlog,就提交事务返回了,它不管slave有没有收到日志。


如果此时数据还没同步到salve,master宕机了,数据是不是就丢了?


因此你可以采用半同步的复制方式。


(2)半同步复制方式


半同步就是说,你master写入数据,日志进入binlog之后,会确保 binlog日志复制到slave了,再告诉客户端说本次写入事务成本了。


这样就算master宕机了,你写入binlog的数据也到了slave,数据也不会丢失。


一般生产环境中,会采用半同步复制的方式。


主从复制延迟问题如何解决?


master是多线程并发写入的,所以主库写入数据的速度可能是很快的,但是slave是单个线程缓慢拉取数据的,所以必定会导致slave节点数据比master节点慢。


这导致的问题也很明显,你向master节点写入一条数据,立马去slave节点读取,可能就读不到。


怎么解决?


MySQL 5.7就已经支持并行复制了,可以在slave节点里设置slave_parallel_workers>0,就是开启多个线程去同步binlog,然后把slave_parallel_type设置为LOGICAL_CLOCK,就好了。


即使是这样,也还是有可能主从不一致。


如果你要求主从数据强一致,那么你只能强制从master库里去读,这样就肯定不会出现主从不一致的问题了。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
关闭
关闭