深入理解MySQL原理之四--如何实现高可用

一、前言

     对于一些组件产品,高可用的要求可能没有那么强烈,但对于数据库产品,高可用尤为重要。一旦数据丢失或者损坏,无法修复,轻则中断业务服务,重则导致整个公司的覆灭。实现高可用的本质就是冗余,高可用一般考察两个指标:

  • 两次故障点间正常运行时间(MTBF),这个指标主要在于要防止故障发生,越大越好。
  • 故障恢复时间(MTTR),这个指标主要在于故障发生后,业务恢复的时间(并不一定是指故障恢复),越小越好。

    高可用的实现,涉及到设计,研发,监控,运维等环节的相互配合,是一个复杂的工程。我们将从复制原理,集群方案,备份几个方面了解下高可用的实现。本章主要内容有:

1、MySQL的高可用需要实现哪些方面内容?

2、MySQL的复制原理,复制模式和拓扑有哪些?

3、数据库集群如何确保高可用,高可用的方案有哪些?

4、为什么需要备份,备份有哪些方案?

二、复制

复制是实现高可用的基础,我们先了解下MySQL原生复制的原理。

1、复制原理

对于主从复制,主库记录二进制日志(binlog),从库获取该日志文件,并进行重放。具体步骤如下:

1、主库每次准备提交事务前,先记录二进制日志,完成后,主库通知存储引擎提交事务。

2、从库启动一个I/O工作线程,负责和主库保持连接,一旦有新的事件产生,主库就通知从库,该线程被唤醒,从库接受日志并写入到中继日志(Relay log)。

3、从库的SQL线程读取中继日志并进行回放,最终完成从库的同步。

可以看到,从库通过I/O线程和 SQL 线程实现了日志文件的读取和写入。接下来,我们看binlog主要记录了什么?

基于语句的复制

      MySQL5.0之前的版本仅只会基于语句的复制,主库会记录变更的SQL语句,备库会重放这些SQL语句,这种方式的好处是显而易见的,比如"update test set col_1=0",仅需要一行字符即可,二进制日志文件小。但是也有很多弊端,比如会导致数据的不一致,"insert into test (createtime) values (now())",由于复制的延迟,那么createtime在主从库上值是不一致的。

基于行的复制

       MySQL5.1开始支持基于行的复制,将实际的更变数据记录在二进制日志中,这种模式的优缺点刚好和基于语句复制的相反,比如"update test set col_1=0",需要将所有的变更行记录到二进制文件中,如果行数很多(几百万行),导致二进制文件特别大;而对于"insert into test (createtime) values (now())",则不会像基于语句复制那样,导致不一致。

      基于语句复制,以及基于行的复制的优缺点比较明显,又相互补充,无所谓谁优谁劣,需要按照具体的场景确定。默认情况下,MySQL采用的基于语句的复制。

2、复制的模式

    MySQL复制模式分为异步复制,同步复制,以及半同步复制。

1、异步复制

     主库写入binlog并发送给从库,不会等待从库的反馈,就提交事务。这种模式下,由于不保证从库能正确同步到binlog,写入效率高,但是主库宕机后,可能存在有部分数据没有及时同步到从库,存在主从数据不一致的风险。

2、同步复制

     主库写入binlog,发送到从库,所有从库接受到新的binlog,写入到Relay log并执行,然后返回响应到主库,主库确认完毕后,再提交事务。该模式能确保主从数据的实时强一致性,但是对于性能影响较大,如果某个从库的性能较差,会拖累主库的写入效率。

3、半同步复制

      主库写入binlog,并发送到从库,某个从库接受到binlog并flush到Relay log就返回响应(不需要执行SQL thread),主库接受到响应后,无需等待所有的从库的返回,即可提交事务。这种模式优势比较明显,该模式综合了上面两种的优点,即能确保至少一个从库同步了所有数据,又兼顾写入的效率,优势比较明显。

3、复制拓扑

接下来,我们重点介绍几种常用的复制拓扑:

1、一主多从(星型架构)

大部分场景采用的都是这种模式,如图所示:

   所有的从库仅同步主库的日志文件,从库之间没有关联。该模式部署简单,适合于写少读多的场景,多个从库可以分担读的压力。这些从库可以扮演不同的角色,比如

  • 一台从库作为待备用库,除了复制没有其他的数据传输。
  • 一台从库可以作为灾备,可以启用延时备份。
  • 一台从库可以作为开发,培训或者测试使用服务器。

这种模式的缺点在于对主库的性能影响,一旦从库达到一定数量,从库对于主库的负载以及网络带宽都会带来严重的影响。

2、一主多从(级联架构)

针对星型架构中主库性能问题,考虑将复制的任务让一部分从库承担。如图所示:

      第一级的从库集群就分担了之前主库的复制工作,这类从库需要开启log-slave-update,产生新的binlog文件。理论上,这种模式可以无限的级联下去,但实际上,会导致架构的不稳定,以及延迟增大(特别对于最底层的从库),一般建议不超过三层。

      笔者在做异地多活方案时,采用的就是这种方案,备机房的主库作为主机房的从库,通过级联的模式再复制到备机房的其他从库上。

3、主主模式

两个主库互为主从,相互复制。如下图所示:

       这种模式,可以实现数据的双写,但是最大的问题就是如何解决数据冲突,比如对于自增长的主键索引,需要设置步长(调整auto_increment_offset和auto_increment_increment)。另外通过设置不同的serverid,确保复制到对库的数据不会再复制回来,否则造成循环复制。

使用主主模式进行双写的场景不多(一般对于日志库等对于数据冲突要求不高的),更多的是用来做热备,如下图所示。

     在日常情况下,一个从库标记为readonly,不写入流量,避免双写。当需要切换时,仅需要将该库从可读提升为可写即可,速度很快(后面我们会介绍主从模式下切换的流程)。高可用集群架构解决方案MMM就是采用类似的机制。

     笔者在做异地多活方案时,流量切换系统双机房部署就是采用的这种模式,因为该系统无法切自身流量(该方案中,readonly是由应用层控制是否可写)。

    还有其他的复制拓扑,比如环形复制,带有备库的主主复制等,这些实际应用中比较少,所以这里不一一介绍。

三、高可用集群方案

     开篇我们介绍了高可用的本质是冗余,高可用设计一般采用集群模式,底层采用数据库复制机制实现数据同步。MySQL的高可用集群的方案很多,从产品的维度可以分为三类:

  • MySQL原生配套产品,包括MySQL Replication,MySQL Fabirc,MySQL Cluster,MGR(MySQL Group Replication)
  • 第三方产品,包括MMM(Master Replication Manager for MySQL),MHA(Master High Availability),Galera Cluster
  • 存储硬件高可用产品,包括SAN(共享存储),DRBD。

下面我们对几种常用的方案做个介绍,并比较下优缺点。

1、MySQL Replication

    MySQL复制就是前面所说的主从复制,原有的方案仅做到了节点冗余,但是在主库故障发生时,需要手工提升从库为主,需要完成以下步骤:

(1)选择从库,如果存在多个从库,需要通过show slave status指令输出,选择其中Master_Log_File/read_Master_Log_Pos的值最新的那个。

(2)在新主库上执行stop slave,执行change master to master_host='',再执行reset slave,提升为主,并与老主库断开。

(3)执行show master status记录新主库的二进制日志坐标

(4)对于其他的从库,执行change master to 语句,使用之前通过show master status获得的二进制日志坐标,来指向新的主库。

        一顿操作猛如虎,一看时间250,人工操作是无法满足降低MTTR指标要求的,且存在误操作的风险。一般采用keepalived或者lvs+keepalived架构实现自动切换,我们重点介绍下lvs+keepalived+双主架构。

     App通过VIP连接到LVS,LVS采用主备模式,并通过keepalived实现LVS集群高可用,两台MySQL作为后端负载服务,采用主主复制模式,一旦某个数据库宕机,可以快速剔除该故障机器,负载到其他主库上。

    这种方式部署简单,故障后能自动切换到其他库,但是一般采用的是LVS的DR模式,两个库需要再同一个局域网内,无法跨汇聚实现高可用。另外故障恢复后,数据的不一致也需要手工处理。

2、MGR(MySQL Group Replication)

     MySQL Group Replication(MGR)是MySQL官方在5.7.17版本引进的一个数据库高可用与高扩展的解 决方案,MySQL组复制是一个MySQL Server插件。由多个节点组成一个组(group),组内通过复制实现数据的同步,其高可用架构如下:

 从架构图可以看到,无需借助其他的组件,就可以实现集群管理。

MGR分为单主模式和多主模式。

  • 单主模式下,只有一个节点可以读写,其他节点提供只读服务。当主节点故障后,根据MySQL Server版本,成员权重(group_replication_member_weight),以及server_uuid选举新的主节点。
  • 多主模式下,组内所有的节点的都可读写,组复制中通过Group Replication Protocol协议及Paxos协议,形成的整体高可用 解决方案。readwrite(rw)的操作只有在组内验证后才可以commit,Read-only (RO)事务是不需要验证可以立即执 行,当一个事务在一个节点上提交之前,会在组内自动进行原子性的广播,告知其他节点变更了什么内 容/执行了什么事务,然后为该事务建立一个全局的排序,最终,这意味着所有的服务器都以相同的顺 序接收相同的事务集。因此,所有服务器都按照相同的顺序应用相同的变更集,因此它们在组中保持一 致。

这个集群方案的优点是MySQL自带的,不需要集成其他的组件,但是节点的个数是有限制的,目前在9个。

3、MHA(Master HA)

     MHA(Master HA)是一款开源的 MySQL 的高可用程序,它为 MySQL 主从复制架构提供了 automating master failover 功能。MHA 在监控到 master 节点故障时,会提升其中拥有最新数据的 slave 节点成为新的master 节点,在此期间,MHA 会通过于其它从节点获取额外信息来避免一致性方面的问题。MHA 还提供了 master 节点的在线切换功能,即按需切换 master/slave 节点。架构如下:

MHA服务有两种角色,MHA Manager(管理节点)和MHA Node(数据节点)

MHA Manager

     通常单独部署在一台独立机器上管理多个 master/slave 集群(组),每个 master/slave 集群称作一个application,用来管理统筹整个集群。

MHA Node

     运行在每台MySQL服务器上,接受管理节点的指令,用来收集从节点服务器上所生成的 bin-log,当需要切换时,会选择一个最新binlog的从库提升为主库。

manager与node间使用ssh实现无密码互联。当主库出现宕机后,MHA能完成自动切换工作,并最大程度保证slave间的数据一致性。我们看下步骤:

1、尝试保存宕机的主库的二进制事件,尽管很多情况下无法办到,比如机器或者磁盘故障。

2、识别拥有最新更新的slave节点;

3、应用差异的中继日志(relay log) 到其他 slave ;

4、应用从 master 保存的二进制日志事件(binlog events);
5、 提升一个 slave 为新 master ;

6、使用其他的 slave 连接新的 master 进行复制。

     MHA的一个复制组一般要求包含一主两从,所有的节点开启二进制日志和中继日志,主从间采用半同步,确保至少有一个slave保持最新数据。

MHA集群可以进行故障的检测和自动转移,并最大化实现数据的一致性,但是负载均衡,读写分离需要自行实现。

4、Galera Cluster

    Galera Cluster是由Codership开发的MySQL多主集群,这些主节点互为其它节点的从节点。如图所示,一个三节点的galera集群,三个MySQL节点是对等的,互为主从,节点的复制并不是采用原生的主从复制,而是通过Galera复制插件实现的多主同步复制。对于写操作,当数据写入某一节点后,集群会将其同步到其他节点,对于读操作,每个节点的读取的数据是一致的。

Galera集群架构包含四个组件,分别为数据库管理系统(DBMS),wsrep api,Galera复制插件,组通信插件

  • 数据库管理系统(DBMS),在单个节点上运行的数据库服务器。Galera群集可以使用MySQL、Mariadb或Percona xtradb。
  • wsrep api:Galera与数据库服务器的接口,为上层提供了丰富的状态信息和回调函数。wsrep api由wsrep hooks、dlopen函数两部分组成。wsrep hooks钩子程序用于与数据库服务器引擎集成。dlopen函数使Galera插件中的复制程序对wsrep hooks可用。
  • Galera复制插件:实现写集复制功能的核心模块,通过全局事务唯一Id(GTID),确保事务和数据的强一致性。
  • 组通信插件:Galera集群的组通信系统(Group Communication System,GCS),如GComm。

    Galera集群实现多主多活架构,对于任意一个节点都可以进行都写,在某个故障的情况下,无需切换,其他节点就能接管,不影响业务;扩展性好,增加一个节点,通过快照和增量复制,拉取最新数据,确保数据的最终一致性。

毫无疑问,多主情况下,确保数据的强一致性,是需要牺牲性能作为代价的。

5、基于DRBD复制

      DRBD(Distributed Replicated Block Device)即分布式复制块设备,这是linux内核板块实现的块级别的同步复制技术。通过各主机之间的网络,复制对方磁盘的内容。当客户将数据写入本地磁盘时,还会将数据发送到网络中另一台主机的磁盘上,这样的本地主机(主节点)与远程主机(备节点)的数据即可以保持同步,可以认为是网络版的RAID。

基于DRBD复制的MySQL集群部署如下:

该集群方案采用主从模式,通过keepalived实现主从切换,通过DRBD实现数据的复制,保证数据强一致性,同时对于io性能影响较大。

四、备份

       很多对数据库运维不大熟悉的同学认为有了集群的高可用,数据有了多副本,再做备份就多此一举了。其实备份和复制是两个事,表面看都是冗余,但是方法和目的是不一样的。严格意义上,备份不算高可用的范畴,它只是保证数据完整性和可靠性,不确保整个系统的可用性。

先看下备份能解决哪些具体问题。

1、生产环境上,一不小心误执行了"drop table"指令或者恶意"删库跑路",等发现时,已为时晚矣。此时,只能采用前一天备份的数据,以及当天的二进制日志文件,恢复这张表的数据。

2、我们要新搭建一个集群,先用备份的数据初始化,再搭建复制关系追加,加快创建速度。

备份是确保数据安全的最后一道关,作为对数据可靠性要求较高的公司,是必须建立的机制。

1、备份哪些数据

(1)数据库中的数据,包括行数据和表定义,这个是最基本的要求。

(2)日志文件,包括二进制日志以及Innodb事务日志

(3)配置文件,包括复制配置,服务器配置。

(4)代码,包括存储过程,存储函数,触发器

2、备份的方案

备份的方案可以分为逻辑备份,物理备份。

(1)逻辑备份

逻辑备份主要分为两种,SQL导出以及符号分隔符文件备份。

SQL导出

     采用mysqldump或者mydumper工具,将表结构,表数据以SQL格式导出,这种方式比较简单,但是对于行数据较大的情况下,生产的文件会比较大,且恢复执行的时间也比较长。一般用于数据量较小的库备份,或者测试环境数据临时备份。

符号分隔符

     采用select into  outfile 以符号分割文件格式创建数据的逻辑备份,符号分割文件包含以ASCII展示的原始数据,没有SQL,注释和列名,文件更加紧凑,比如导出CVS格式。恢复时,采用LOAD DATA INFILE进行加载。

   该方案在备份和恢复的时候,速度比SQL模式更快,文件也要小,但是总体上也是适合数据量小的库备份。

(2)物理备份

    物理备份是指对物理文件的备份,又分为冷备份和热备份,冷备份是需要停止MySQL服务,将data下相关的文件拷贝出来进行备份,这种方案对业务有影响,一般不会在生产环境使用。

     热备份是指在MySQL服务开启的情况下就可以执行备份操作,这里介绍xtrabackup备份和lvm快照两种方案。

xtrabackup备份

        Percona-xtrabackup是 Percona公司开发的一个用于MySQL数据库物理热备的备份工具,xtrabackup只能备份innoDB和xtraDB两种数据引擎的表,而不能备份MyISAM数据表。

       其工作原理是,在后台线程不断追踪InnoDB日志文件尾部,然后复制InnoDB数据文件,依靠检测机制确保复制的数据是一致的,当所有的数据文件被复制完成,日志复制就结束了。这样就得到了不在同一时间点的数据副本和开始备份以后的事务日志。完成上面的步骤之后,就可以使用InnoDB崩溃恢复代码执行事务日志(redo log),以达到数据的一致性。整个过程可以分为:

  • 备份阶段,追踪事务日志和复制数据文件(物理备份)
  • 准备阶段,重放事务日志,使所有的数据处于同一个时间点,达到一致性状态。

全量备份完成后,记录下此时检查点的LSN(Log Sequence Number),在进行增量备份时,比较表空间中每个页的LSN是否大于上次备份时的LSN,如果是,则备份该页,同时记录当前检查点的LSN。

xtrabackup备份由于其开源性,热备份入侵小,自动备份检测,备份和恢复时间快等特点,使用案例较多,笔者所在公司就是采用该方案。

LVM快照备份

    文件快照是一种非常好的在线备份方法,可以瞬时创建用来备份的内容一致的镜像。MySQL主要采用逻辑卷管理(LVM)快照。

   LVM快照的原理,在快照的瞬间对原数据版本进行打标,此时不做任何物理的复制操作,仅是逻辑副本。当有数据块修改时,才将数据复制出来,称之为写时复制(copy-on-write)。所以快照具有以下几个特点:

1、速度快,仅打标,不做物理复制,瞬间完成。

2、快照并不等于备份,备份数据是快照数据(原数据块有修改)+原数据快(没有修改过)。这些数据实际还在本地磁盘,需要将备份数据进行拷贝,实现真正的物理备份。

备份仅是第一步,备份数据的校验,恢复也很大多的工作,这里就不探讨。

五、总结

按惯例,我们用文章开篇的问题作为本章的总结:

Q:MySQL的高可用需要实现哪些方面内容?

  • 高可用的本质是冗余,高可用的两个指标包含,两次故障点间正常运行时间(MTBF)和故障恢复时间(MTTR)。
  • 高可用是个综合工程,涉及到架构设计,研发,监控,运维等各个方面。在日常运行中,及时发现和处理相关问题,比如慢SQL导致CPU冲高卡死,磁盘达到阀值,集群复制异常导致数据不一致等等,将这些问题扼杀在萌芽阶段,防止进一步扩大,提升MTBF的指标。
  • 当一些故障不可避免发生,比如磁盘损坏,掉电等,通过高可用集群的故障转移,自动切换到备库上,及时恢复业务,降低MTTR指标。
  • 当故障机器恢复后,通过数据一致性比较,导出差异化数据,进行业务修单的方式进行补偿。

Q:MySQL的复制原理,复制模式和拓扑有哪些?

  • 复制模式,主库在提交事务前,记录binlog日志,并通知从库,从库通过I/O线程接受日志,并记录到中继日志,SQL线程读取中继日志进行回放,最终完成同步。
  • 复制模式,包括同步模式,异步模式,以及半同步模式,其中半同步模式兼顾性能和一致性特点。
  • 复制拓扑,包括主从星型架构,主从级联架构,主主架构,环形架构等,常用的是主从架构。

Q:数据库集群如何确保高可用,高可用的方案有哪些?

  • 高可用的本质是冗余,集群就是实现冗余的方法,可以是一个集群内的多个节点冗余,也包括多个集群冗余,确保数据实时一致性或者最终一致性。当故障发生后,集群通过负载均衡,主从切换等方式实现故障的自动转移。
  • 集群方案从产品上分:

1、MySQL原生配套产品,包括MySQL Replication,MySQL Fabirc,MySQL Cluster。

2、第三方产品,包括MMM(Master Replication Manager for MySQL),MHA(Master High Availability),Galera Cluster。

3、存储硬件高可用产品,包括SAN(共享存储),DRBD。

每种方案都有各自的应用场景以及优缺点,一般情况下常用的还是MySQL Replication方案。

Q:为什么需要备份,备份有哪些方案?

  • 集群在大部分场景下能确保高可用,但是在一些灾难场景下,比如误删表,恶意删库,地震等,备份是恢复数据的最后手段,可以说,备份是把守了数据安全的最后一道关。
  • 备份包括逻辑备份和物理备份,其中逻辑备份又包括SQL导出,符合分隔符两种,物理备份重点介绍了xtrabackup备份和lvm快照文件备份。

附:

深入理解MySQL原理之一--如何提升查询SQL的性能

深入理解MySQL原理之二--如何建立高效索引

深入理解MySQL原理之三--如何实现事务与分库分表

深入理解MySQL原理之四--如何实现高可用

深入理解MySQL原理之五--如何高效利用InnoDB存储引擎

深入理解MySQL原理之六--核心算法有哪些

深入理解MySQL原理之七--云原生时代将何去何从

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值