今天分享主要包括三方面内容:一是常见的MySQL高可用架构;二是分布式数据库高可用实践;三是基于keepalive的MySQL高可用改造。第一部分会介绍业界一些经典的MySQL高可用解决方案,第二部分和第三部分分别介绍网易在分布式数据库和单节点MySQL上的高可用运维实践。
一、常见的MySQL高可用架构
MySQL高可用主要涉及两个方面,一是客户端如何切换,如何自动failover,二是多个MySQL节点之间如何做数据同步。业界MySQL高可用的解决方案有很多,总结起来有几类:从客户端自动切换的角度来看主要有两类:一类是基于HA同步软件的MySQL高可用,用户通过VIP访问数据库,然后第三方组件监控MySQL的状态,控制VIP的漂移。还有一类是基于API调用的MySQL高可用,把MySQL主从状态维护在客户端,应用程序可以通过API调用控制主从切换,进行数据同步。
MySQL多节点的数据同步方案也有多种,最常用的是基于binlog的数据同步,其次还有基于共享存储的数据同步,以及第三方自己实现的数据同步协议(如Galera)。
1、基于HA同步软件实现的高可用方案
如图所示,基于HA同步软件的MySQL高可用主要是通过VIP作为对外的访问入口,正常情况下VIP绑定在Master上,当Master出现故障后,可以将VIP切换漂移到Slave上。从而实现了一个故障failover的过程。这种基于VIP的高可用方案,最常用的数据同步方式是使用MySQL原生的binlog复制方式,当然,在成本允许的情况下,也可以选择利用SAN之类的共享存储解决方案。我们这边重点介绍的还是binlog复制或者其他软件层次的数据同步方式。
基于HA同步软件的高可用方式的主要特点包括:
结构简单、容易管理;
不支持多写、standby属于备机;
不保证数据一致性;
入侵性小,对用户透明。
2、MHA(Master High Availabitliy)
下面,我们来介绍几种典型的MySQL HA同步软件。在业界应用最为广泛,技术最为成熟的HA同步软件之一是MHA。MHA全称是Master High Availability,是一种一主多从的数据库高可用解决方案。他的特点是在保障高可用自切换的前提下,最大限度的保障主从数据的一致性。
我们先来看下MHA的架构图:
一次完整MHA故障切换流程如下:
保存故障的master节点的binlog日志;
Manager查找最新更新的slave节点;
应用差异的relay log日志到其他的slave;
在slave节点上应用从master保存的binlog日志;
提升一个slave为新的master;
使其他的slave连接新的master进行复制。
3、MMM(Master-Master Replication Manager for MySQL)
除了MHA以外,还有一个老牌的MySQL自动切换套件MMM。
与MHA相比,MMM是基于主主复制的故障切换。也就是不支持从多个slave中选择最新的一个,而是只能切换到特定的主主复制从节点。
4、基于API调用的MySQL高可用
刚才介绍的两种MySQL高可用解决方案,主要都是基于VIP切换的,优点是对应用程序没有入侵,但是缺点是不够灵活,而且系统的可靠性取决于HA软件本身的可靠性。如VIP通知产生问题,或者keepalive进程自己挂了,都可能导致切换出现问题。除了这种解决方案,还有一种是在客户端实现的MySQL高可用 – 基于API调用的MySQL高可用。也就是JDBC或者其他数据库驱动可以自主选择MySQL节点。这种实现方案可能使用的不是特别广泛,但是也有它自身的应用场景,它有如下特点:
架构较重,运维相对复杂
使用灵活,有一定开发成本
支持数据分片、分库分表、读写分离等高级特性
HA-JDBC 就是一种典型的基于API调用的MySQL高可用方案,它可以在应用程序中配置多个MySQL地址,由HA-JDBC实现选主/屏蔽故障节点以及多个应用程序之间的连接状态通知。HA-JDBC可以实现如下功能:
基本的failover
读写分离
节点状态通知
负载均衡
数据同步(先写主,然后同时写多个从节点,如果主写失败,则重新选主,如果从写失败,屏蔽从) 弱一致性。
刚才介绍的多是在客户端角度看到的MySQL高可用切换技术,下面再介绍几种MySQL数据同步的高可用解决方案,MySQL最经典的数据同步方案就是利用binlog进行数据同步,这种数据同步的优势是架构简单、易于管理,对主服务的性能影响相对较小。缺点是不能保障主从完全一致,而且只支持单写。下面介绍几种能保证主从完全一致,并且支持多节点写的方案。
5、Galera MySQL的高可用及特点
Galera架构如图所示:
客户端通过Galera Load Balancer访问数据库,提交的每个事务都会通过wsrep API 在所有服务器中执行,要不所有服务器都执行成功,要不就所有都回滚,保证所有服务的数据一致性,而且所有服务器同步实时更新。
wsrep API是一系列应用回调和复制调用库,来实现事务数据库同步写集(writeset)复制以及应用。其主要思想是在不出现冲突的背景下事务正常执行并持续到commit为止;当客户端发起commit命令时(此时仍然没有发生真正的commit),所有本事务内对数据库的改动与改动数据行的主键都会被放入一个写入集(writeset)中,该写入集随后会被复制到其他节点执行,在每个节点上使用主键进行冲突检测判断该写入集是否可以被应用,如果出现主键冲突,则其中一个事务会被回滚。
缺点及限制:由于同一个事务需要在集群的多台机器上执行,因此网络传输及并发执行会导致性能上有一定的消耗。所有机器上都存储着相同的数据,全冗余。若一台机器既作为主服务器,又作为备份服务器,出现乐观锁导致rollback的概率会增大,编写程序时要小心。不支持的SQL:LOCK / UNLOCK TABLES / GET_LOCK(), RELEASE_LOCK()…不支持XA Transaction。目前基于Galera Cluster的实现方案有三种:Galera Cluster for MySQL、Percona XtraDB Cluster、MariaDB Galera Cluster。
6、MySQL Group Replication
MySQL Group Replication是16年 MySQL 5.7官方推出的多节点数据同步解决方案,它也支持多节点写和强一致性。在架构上它与Galera相似,但是多节点事务一致性提交是基于paxos来实现的,性能更高。可以预见MySQL Group Replication,这类基于强一致性协议的MySQL数据同步方案,是MySQL高可用的下一个研究热点,目前腾讯、阿里均有类似的方案推出。
MySQL Group Replication中的Replication-group就是一组节点,每个节点都可以独立执行事务,读写事务会在group内的其它节点进行协调之后再commit。因此,当一个事务准备提交时,会自动在group内进行原子性的广播,告知其他节点变更了什么内容/执行了什么事务。基于Paxos协议使得事务在每一个节点上都保持着同样顺序执行,这意味着每一个节点都以同样的顺序,接收到了同样的事务日志,所以每一个节点以同样的顺序重演了这些事务日志,最终整个group保持了完全一致的状态。
MySQL Group Replication仅支持InnoDB表,并且每张表一定要有一个主键,用于做冲突检测;必须打开GTID特性,二进制日志格式必须设置为ROW。这是使用MGR的一些限制。
二、MySQL高可用在网易的实践
1、分布式数据库高可用实践
首先是分布式数据库方面的。由于OLTP的业务特性和业务量大的特点,分布式数据库在网易有广泛的应用,下面我们简单介绍下网易的分布式数据库架构以及重点介绍下其高可用解决方案。
DDB的组织架构如上图所示,DBN(MySQL)负责实际的数据存储与读写提供。管理服务器负责数据库表、用户权限、数据分布路由的维护以及DBN状态的监控与管理。除此之外DDB最核心的模块是被称之为DBI的数据库驱动,它是一个类jdbc驱动,一方面可以与管理服务器交互,获取分布式数据库的表结构与分布路由;另一方面可以解析用户发过来的SQL语句,转换成适用于分布式场景的sql直接发送给DBN节点,并且将DBN返回的结果进行聚合或者排序并最终返回给应用程序。正是由于DBN这一系列的改写与聚合动作,才能使得应用程序可以像访问一个简单的关系型数据库那样去访问DDB这样一个分布式数据库。
管理服务器的高可用主要是基于分离持久化信息到sysdb中实现的,也就是管理服务器本身是一个无状态的服务,可以部署多个,短暂的故障也不会影响DBI到DBN节点的正常数据读取。而sysdb本身是个MySQL节点,它的高可用可以用经典的MySQL高可用方案解决。
DBN的高可用也可以使用MySQL原生的高可用方式,比如基于VIP的高可用。但是使用分布式数据库做高可用的优势就是有一个管理服务器的角色维护数据路由,因此只要可以根据当前的节点的状态更新数据路由就可以做到一个自动的failover的过程。具体到DDB这个场景,我们引入了一个DDBSwitch高可用切换工具,这个工具可以监控DBN状态,维护DBN主从关系。当主DBN存在异常时,DDBSwitch工具会检测到节点异常,并且触发管理服务器更新DBN列表,管理服务器会通知所有客户端的DBI更新本地的DBN列表,切换缓存中的路由,从而完成了一次完整的切换。除了最基本的故障切换,DDBSwitch还可以通过逐步放开DBN连接池的方式控制新切入节点的流量,防止新上线的节点由于之前堆积的请求而瞬间被压垮。
目前网易杭州这边的项目,绝大多数的分布式数据库都是使用的DDB,因此有比较多的线上实践,事实也证明DDB这套高可用架构是稳定可靠的。目前像网易云的项目,比如视频云、云信后端依赖的数据库都是DDB,可以做到数据库相关模块故障异常在30s内自动恢复。在减少人工运维成本的前提下,提高系统整体可靠性。
除了分布式数据库,网易也有少量的单节点MySQL。出于成本和易用性的考虑,我们没有选择MHA方案,而是配合keepalive使用自定义的脚步进行故障自切换与尽可能的保障可靠性。首先keepalive本身是一个多进程的程序,可靠性和成熟度很高,不止可以做无状态的nginx的高可用代理,还能通过配合第三方的脚本来做类似MySQL这种有状态服务的高可用。
2、基于keepalive的MySQL高可用改造
网易的这套keepalive的MySQL高可用方案采用的也是经典的MySQL主主复制的架构,然后配合自研的切换脚本进行自定义故障判定以及升主的一致性检查功能。一次完整的故障切换包含如下几个步骤:首先利用Master上的keepalive定时调用故障检查check脚本,发现异常后进行3次重试,重试后MySQL依然无法正常服务则触发切换。切换不是采用keepalive传统的降低权值的方式进行的,而是直接stop keepalive来触发slave抢占VIP,升级为主。升级为主后slave keepalive会调用升主检查脚本,判定relay log应用完成后才放开写,关闭read only正式提供服务。
这套keepalive高可用解决方案有如下几个特点:
具备一致性检验功能(检查relay log是否应用完),配合杭研改进的semisync 功能,可以保障数据的强一致;
具备防网络抖动功能,不会再网络不稳定的情况下频繁切换;
原主恢复后不自动升级为master功能(MySQL复制延迟);
自定义故障判定规则,贴近业务的高可用;
简单易用,方便管理,可以人工介入。
- Keepalived 使用注意事项
现象:
keepalived主从切换后,网关/交换机上的arp表没有立刻更新VIP对应备用 LVS 的mac,或者arp包被交换机drop掉,导致备机无法被访问。
解决:
arping -I eth1 -c 5 -s VIP GATEWAY
garp_master_refresh 选项 (Release 1.2.10)
- Keepalived 不抢占的实现
Keepalived自带nopreempt参数实现不抢占功能,但当新主服务再挂掉后由于原主带nopreempt参数,即使原主优先级高仍无法完成切换。故现在通过自定义脚本实现类似功能(sudo /etc/init.d/keepalived stop),备机节点脚本只有当自身 MySQL可用且主机MySQL不可用时才触发切换。
Keepalive这套方案在网易内部主要用在一些负载比较小,但是对稳定性和可靠性要求比较高的数据库,比如openresty等云计算服务的元数据库,易信朋友圈数据库,也已经在线上稳定运行了3,4年的时间,可以做到秒级别的切换。
本文作者:佚名
来源:51CTO