一文讲清,MySQL主从架构

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

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

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

一文讲清,MySQL主从架构_第1张图片

图1 MySQL主从复制架构

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

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

一文讲清,MySQL主从架构_第2张图片

图2 MySQL读写分离

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

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

一文讲清,MySQL主从架构_第3张图片

图3 MySQL主从复制一主多从

MySQL主从复制的工作原理

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

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

一文讲清,MySQL主从架构_第4张图片

图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库里去读,这样就肯定不会出现主从不一致的问题了。

你可能感兴趣的:(java,数据库,分布式,redis,mysql)