最近在作项目的时候,由于部署了 MYSQL主从复制 因此在这里记录下整个过程。这里一共会分两篇博客来写:mysql
一、Mysql主从复制原理 二、docker部署Mysql主从复制实战
这篇只写MYSQL主从复制原理。ios
概念
主从复制是用来创建一个和 主数据库彻底同样的数据库环境称为从数据库;主数据库通常是准实时的业务数据库。sql
咱们来思考若是在企业网站中,后端MYSQL数据库只有一台时候,会有如下问题docker
一、单点故障服务不可用 二、没法处理大量的并发数据请求 三、数据丢失
因此经过主从复制后,它的优势就很明显数据库
一、若是主节点出现故障,那么咱们就直接将服务切到从节点,来保证服务立马可用。 二、若是并发请求特别大的时候,咱们可用进行读写分离操做,让主库负责写,从库负责读。 三、若是主库数据丢失,但从库还保存一份,减小数据丢失的风险。
这里先放一张图,这张图很好的诠释的主从复制的原理segmentfault
上面主要分红了三步,下面会详细说明。后端
(1) Master的更新事件(update、insert、delete)会按照顺序写入bin-log
中。当Slave链接到Master的后,Master机器会为Slave开启缓存
binlog dump
线程,该线程会去读取bin-log日志服务器
(2) Slave链接到Master后,Slave库有一个I/O线程
经过请求binlog dump thread读取bin-log日志,而后写入从库的relay log
日志中。网络
(3) Slave还有一个 SQL线程
,实时监控 relay-log日志内容是否有更新,解析文件中的SQL语句,在Slave数据库中去执行。
总结
(1) 既然是要把事件记录到bin-log日志,那么对于Master就必须开启bin-log功能。
(2) 整个Mysql主从复制一共开启了3个线程。Master开启 IO线程,Slave开启 IO线程 和 SQL线程。
(3) 这点也很重要那就是Master和Slave交互的时候,记住这里是Slave去请求Master,而不是Master主动推给Slave
。Slave经过IO线程
链接Master后发起请求,Master服务器收到Slave IO线程发来的日志请求信息,io线程去将bin-log内容返回给slave IO线程。
(1)异步复制
MySQL主从同步 默认是异步复制的。就是上面三步中,只有第一步是同步的(也就是Mater写入bin log日志),就是主库写入binlog日志后便可成功返回客户端,无须等待binlog
日志传递给从库的过程。Master 不关心 Slave 的数据有没有写入成功。所以若是Master和Slave之间有网络延迟,就会形成暂时的数据不一致的现象;若是Master出故障,而数据
尚未复制过去,则会形成数据丢失;但也有好处,效率较其余两种复制方式最高。
(2)同步复制
对于同步复制而言,Master主机将事件发送给Slave主机后会触发一个等待,直到全部Slave节点
(若是有多个Slave)返回数据复制成功的信息给Master。这种复制方式最安
全,可是同时,效率也是最差的。
(3)半同步复制
对于半同步复制而言,Master主机将事件发送给Slave主机后会触发一个等待,直到其中一个Slave节点
(若是有多个Slave)返回数据复制成功的信息给Master。由此加强了
数据的一致性,可是由于Master主机的确认开销,会损耗一部分的性能;另外,半同步复制除了不须要等待全部Slave主机确认事件的接收外,半同步数据复制并不要求那些事件
彻底地执行,所以,仍有可能看到在Slave主机上数据复制延迟的发生,若是由于网络延迟等缘由形成Slave迟迟没有返回复制成功的信息,超过了Master设置的超时时长,半同步
复制就降级为异步复制方式,然后继续数据复制。
上面也说了,Mysql默认采用的异步操做,由于它的效率明显是最高的。由于只要写入bin log后事物就结束返回成功了。但因为从库从主库异步拷贝日志 以及
串行执行 SQL 的特色,因此从库的数据必定会比主库慢一些,是有延时的。因此常常出现,刚写入主库的数据多是读不到的,要过几十毫秒,甚至几百毫秒才能
读取到。这就是主从同步延时问题。
经过监控 show slave status
命令输出的Seconds_Behind_Master参数的值来判断:
mysql> show slave status\G; // 状态一 Seconds_Behind_Master: NULL // 状态二 Seconds_Behind_Master: 0 // 状态三 Seconds_Behind_Master: 79
Seconds_Behind_Master=0: 表示主从复制良好;
Seconds_Behind_Master=NULL: 表示io_thread或是sql_thread有任何一个发生故障;
Seconds_Behind_Master=79: 数字越大表示从库延迟越严重。
这里整理了影响主从复制延迟大体有如下几个缘由:
1)主节点若是执行一个很大的事务,那么就会对主从延迟产生较大的影响
2)网络延迟,日志较大,slave数量过多
3)主上多线程写入,从节点只有单线程同步
4)机器性能问题,从节点是否使用了“烂机器”
5)锁冲突问题也可能致使从机的SQL线程执行慢
这个没有说去彻底解决,要想解决那么就只能采用同步复制策略。不过,通常不建议使用这种同步模式。显而易见,若是写操做必须等待更新同步完成,确定会
极大地影响性能,除非你不在意性能。
1)大事务:将大事务分为小事务,分批更新数据
2)减小Slave的数量,不要超过5个,减小单次事务的大小
3)MySQL 5.7以后,可使用多线程复制,使用MGR复制架构
4)在磁盘、raid卡、调度策略有问题的状况下可能会出现单个IO延迟很高的状况,可用iostat命令查看DB数据盘的IO状况,再进一步判断
5)针对锁问题能够经过抓去processlist以及查看information_schema下面和锁以及事务相关的表来查看
总结
主机与从机之间的物理延迟是没法避免的,既然没法避免就能够考虑尝试经过缓存等方式,下降新修改数据被当即读取的几率。
别人骂我胖,我会生气,由于我内心认可了我胖。别人说我矮,我就会以为可笑,由于我内心知道我不可能矮。这就是咱们为何会对别人的攻击生气。 攻我盾者,乃我心里之矛(32)