图解 MySQL 面试题 —— 容灾篇
容灾热身
容灾有几种方式?
从冷热来说,分为冷备和热备。从距离来说,分为同城和异地。
一般而言,大的维度划分就是两者的正交:同城冷备,异地冷备,同城热备,异地热备。
MySQL如果挂了怎么办呢?
MySQL可以主从模式部署,如果主挂了,可以将从升级为主。当然,为了节约资源,如果业务允许,在平时运行正常的时候,也可以将部分读请求分流到从节点。
那主从模式按部署方式又分为哪几种?
常见的主从模式有几种,具体的模式也得看实际的业务需要。根据实际的情况,选择合适的一种架构模式。
1.一主一从模式:一个大佬带一个小弟,大佬挂了小弟上位。
2.一主多从模式:一个大佬带一群小弟,只要不全挂,就还能翻盘。
3.级联主从模式:一个大佬培养了一个亲信骨干,其它小弟都由亲信骨干培养。
嗯,比喻得不错,那主节点和从节点怎么保证一致呢?
两种方式,一种是双写两个db,还有就是主从复制。前者需要耗费大量成本去保证双写的最终一致性。所以更常见的是主从复制。
那主从复制,Master做了哪些工作?
当主节点上进行写操作时,会按照时间先后顺序写入到binlog中。主从复制就是基于binlog进行的,具体流程有两部分。
首先,当从节点连接到主节点时,主节点会创建一个叫做dump的线程,有多少个从节点,就会创建多少个dump线程;
然后,当主节点的binlog发生变化的时候,dump线程就会通知从节点,并将相应的binlog内容发送给从节点。
主从复制,Slave又做了哪些工作呢?
当开启主从同步的时候,从节点会创建两个线程用来完成数据同步工作:
I/O线程连接到主节点,主节点上的dump线程会将binlog的内容发送给I/O线程。它接收到内容后,再将其写入到本地的relay log。
SQL线程读取I/O线程写入的relay log,并且根据relay log的内容对从数据库做对应的操作。
数据复制
主从复制有几种模式?
主要有三种模式:异步模式、半同步模式、全同步模式。
异步模式:这种模式下,主节点不关心dump线程同步情况,直接返回成功给客户。
半同步模式下,主节点只需要接收到其中一台从节点的返回信息,就会给用户返回成功,否则需要等待直到超时回滚。
这样做性能比异步模式会差一些,但可靠性会高一些,保证了binlog至少传输到了一个从节点上,不过没有保证从节点立刻将此事务更新到存储中。
全同步模式是指主节点和从节点全部执行并提交了,才会向客户端返回成功。
注意,是提交,而不只是从节点写入到relay log,这样主从是强一致性的,但性能损耗非常大,必须在网络良好的情况下使用。
那全同步模式下,性能会不会很差,有优化空间吗?
全同步主要性能损耗在于同步等待返回,业界有一个方案叫MAR,即异步多线程强同步复制,只有当备机数据完全同步后,才由主机给予应用事务应答,保障数据不丢失,同时还用多线程思路保证了性能。
MAR可以说是半同步和全同步的折中,经常被称为强同步。腾讯的明星产品TDSQL,就是使用的MAR做同步。
详细说一下强同步细节吧。
Master上事务写到binlog就算结束,将会话保存到session中。接着执行下一轮循环去处理其它请求,这样就避免让线程阻塞等待应答了。
然后负责主备同步的dump线程会将binlog立即发送给slave,slave的IO线程收到binlog并写入到relay log之后,再给主机一个应答。
在Master,会有一组线程来处理应答,收到应答之后找到对应的会话,还可以批量执行commit,并且给客户端应答。
MySQL一般会使用哪种模式的复制呢?
根据业务需求,如果要求实时性高的话,可以搞同城容灾,同城可以选择全同步模式。
如果要求进一步降低风险的话,异地容灾也得搞起来,异地通常会采取异步模式。
业界容灾方案
同城容灾和异地容灾的区别是什么?
同城容灾是在相近区域建立两个数据中心 : 一个负责日常生产运行 ; 一个负责在灾难发生后的重建。同城之间的同步速度比较快,可以支持全同步模式。
异地容灾主备中心之间的距离较远, 因此一般采用异步同步,灾难情况下会有少量的数据丢失。异地灾难备份可以有效防范地震、水灾等各类风险。
由于同城灾难备份和异地灾难备份各有所长,为达到最理想的防灾效果,数据中心应考虑采用同城和异地各建立一个灾难备份中心。
你有了解过两地三中心吗?
两地三中心即同城双中心➕一个异地中心。同城双中心由于距离近,数据可以完全同步。异地灾备中心因为距离远,会有一定程度的数据延迟。
同城双中心具有投资成本低、建设速度快、运维管理相对简单、可靠性更高等优点。
异地灾备中心则具有抗风险能力强的作用,当同城中心因为自然灾害等原因而发生故障时,异地灾备中心可以用备份数据进行业务恢复。
那灾难发生时MySQL该怎么切换呢?
如果是同城强同步的节点,直接切换主从即可。如果是跨城市,这种主要是灾难之后的止损,灾难地的数据不一定能恢复。
平时事故时间较短,不一定要切到异地冷备。如果时间预期比较长,比如光纤断了要等几小时以上的,就需要考虑切到异地冷备,此时会丢失一部分数据,等到恢复之后,再做数据迁移。
MySQL异地双活怎么做?
前面说的异地冷备其实也是异地双活的一种。异地双活是说两个不同城地域,同时进行服务,并且互相容灾。
既然能相互容灾,那么两地数据都需要是完整的,至少是最终完整,所以有个同步的过程。
那你能说说异地双活的适用场景吗?
异地双活非常困难,主要涉及到跨城的网络存在较大延迟。要做异地双活,需要对业务场景进行考虑。
如果要完全数据同步,那么两端需要相互同步数据,一般需要数据冲突较少,并且要接受一定的查询延时。
还有一种场景,如果增量数据不受存量影响,比如任务表,那么也可以不双向同步数据,如果一地挂了,可以将用户的新任务调度到异地,等恢复之后,再迁移回来,缺点就是损失一些记录。
MySQL是后台开发中非常重要的领域,容灾更是面试环节的高频考点。
一方面是日常故障怎么做到快速恢复,另一方面,如果真的发生了大型事故 (比如2015年8月,天津爆炸导致腾讯机房受损),怎么把影响降低到最小,这些都是我们需要考虑的问题,若是连冷备兜底都没有,那么这个项目基本可以说拜拜了。
当然,在面试中,要是问到容灾,你能对答如流,甚至拔高,绝对是一个加分项!