专栏首页腾讯云技术沙龙李岩:CynosDB for MySQL高可用系统介绍
原创

李岩:CynosDB for MySQL高可用系统介绍

3月16日在北京举行的腾讯云自研数据库CynosDB交流会圆满落下帷幕。现将技术团队分享的内容整理如下。

任何系统都需要高可用,CynosDB也不例外,下面主要从研发的角度来看CynosDB的高可用系统方案是如何一步一步设计的。主要内容包括:首先是说下CynosDB高可用系统设计的思路,然后是CynosDB是如何快速恢复的,以及高可用系统的整体架构,最后是针对高可用系统中经典的“脑裂”问题是在CynosDB是如何解决的。

对于高可用来说,其实是一个老生常谈的问题,为什么要高可用,大家都熟悉了,这里简单提一下。首先用户要求所使用的服务是7×24小时的;其次我们知道服务所运行的环境是不可靠的,这种不可靠有来自软件的bug、硬件的损坏,还有来自自然环境的不可抗因素;最后数据是很重要的,数据丢失或者数据库服务的不可用带来的结果是,小到DBA被开除,大到导致一个公司的破产,所以无论在任何情况下,都要保证数据服务的可用性,这是我们做数据高可用的最重要的原因。

CynosDB的高可用系统是如何设计的呢?从开发角度来说我要设计一个高可用系统,首先我要看一下业内是怎么做的,业界的方案有两种,一种是基于一致性协议,这个是近两年比较热门的一个话题,就是Paxos和Raft。这种方案基本思想是,使用可证明的一致性算法,各节点通过心跳来探测整个集群的可用性,出现心跳超时就剔除超时节点,重新发起选主。这个方案中,最典型的就是MySQL官方的5.7版本的MGR架构。它的优点是,有可证明的理论基础,整个数据都强一致的。但是有一定的问题,首先它存在特定的版本中,MySQL官方5.7.17版本才有这个特性,5.6版本就无法使用,所以如果想在低版本中使用,需要修改MySQL代码嵌入一致性算法,业界有些产品是这么做的。这就导致对MySQL存在一定的侵入性,后续版本升级都需要打这个patch,从而带来升级上的不方便。还有就是,这种架构必须要求是三个节点或者更多的节点,对于云上的用户来说可能考虑更多的是成本问题,有时候可能需要的只是双节点架构或者基础版单节点,所以,在需要适配多种MySQL主从架构的情况下基于一致性协议的方案就不合适了。

第二种是基于外围系统的方案,这种方案的基本思路是,外围会有一个服务系统,不断地去探测MySQL集群各个节点的状态,出现问题的时候,会做一个切换或者恢复,这种方案中一个典型代表就是比较流行的MHA组件。它的优点是,首先不管MySQL集群有多个个节点,都是适用的,对这个外围系统来说,都是做探测;然后,由于是通过外围服务来做,不需要修改MySQL内部代码,不存在侵入性;再者,不管MySQL什么版本,只要能支持MySQL访问协议,都可以探测状态,所以这种方案对版本是透明的。但是它也有自己的问题,需要实现一套外围系统,这就增加了运维成本,还有就是整个外围系统本身的高可用性需要保证。

以上是业界比较流行的两种高可用设计方案。我们设计CynosDB的高可用系统的时候,是采用基于外围系统这个方案,当然外围系统本身的高可用性我们也是有考虑的。

具体我们是怎么设计的呢?我们在设计的时候,其实是将设计一个高可用系统划分成了三个子问题:第一个是如何探测故障,就是说当有故障发生的时候我要如何发现;第二个是如何决策,即当我知道有故障发生时,我该怎么做,是原地拉起还是立即切换,是恢复主从状态还是用冷备数据重建这个节点;第三个问题是如何恢复,即我知道怎么做之后,具体的恢复操作是怎么样的。后面是针对这三个问题来介绍怎么设计CynosDB的高可用系统。

首先,我们来看第一个问题:如何故障探测。目前大致有三种方式,第一种方式是基于内部心跳,MGR架构中leader和follower会保持心跳,心跳超时就发起故障投票,这种方式要求系统至少有三个节点。第二种方式是基于外部Server,比如MHA使用MHA Manager来不断探测master节点的存活,发现异常时开始切换。但是外部Server的探测是通过网络来访问MySQL节点的,这会带来几个问题:第一个就是故障发现不够及时,如果网络出现波动,可能一次探测并不能说明MySQL已经故障了,需要多次探测,这就导致故障发现不够及时;第二由于Server是非同机部署的,那MySQL机器本身的状态,比如机器高负载、机器假死,这种导致MySQL无法访问的故障类型也是感知不到的;第三点它容易导致脑裂,如果网络出现隔离,Server无法访问MySQL,认为MySQL故障了,就去切换,很容易出现“脑裂”的问题。第三种方式是基于本地Agent,就是MySQL本地会部署一个探测Agent,通过Agent去检测MySQL的一些状态。这种方式下,由于Agent与MySQL同机部署,与MySQL之间的通信不通过网络,一次探测就能发现MySQL是否正常,所以及时性没问题;另外,Agent可以探测机器本身的负载状态,当然,这种方式在某些场景下也会导致脑裂,但是针对这个问题是有解决方案的。针对这几种故障探测方式,我们选择的是基于本地Agent做探测故障。在探测的时候,我们不仅要探测MySQL进程的状态,比如进程是否存活或者正在做恢复,或者已经挂掉;还要探测MySQL内部的状态,比如在主从架构下,还会探测Slave节点的IO线程和SQL线程状态,主从差距的大小,如果发现有问题,会做一个自动修复;更进一步,我们还会探测机器的负载状态,出现高负载或者磁盘坏块之类的问题,也能及时发现,做出决策。目前我们的故障探测主要考虑了这三种情况。对于每种故障的RTO,目前是:针对进程故障,我们可以原地拉起,这个时间在5s内,如果无法拉起,需要做切换,我们的系统可以在10s内完成切换,针对于机器故障的情况,目前设置的超时时间是20秒,再加一个切换时间,可以保证在30秒内能够恢复。

现在,我们来看第二个问题,发现故障之后,我该做什么?我们知道,MySQL是分主从的,对于不同角色的节点来说,会有不同的做法。首先,对于Master节点,在发生故障的时候,我们一般会做自动切换,比如MHA,但是在有些方案中,会选择自动剔除故障的Master节点,比如MGR;在做完切换后,一般会做对旧Master节点做自动降级,把旧的Master节点角色降为Slave,这样在旧节点恢复后,它就不会认为自己还是Master,从而规避一些不必要的麻烦问题。对于Slave节点,如果进程挂掉,我们在拉起进程后,只需要重建主从关系就可以了,但是如果主从关系无法重建,或者机器故障重建不了,就可能需要通过冷备数据或者Master数据来重建这个节点。我们将这几个操作抽象为三种决策,对于Master节点,我们是决策是自动切换(switch),对于Slave节点是重新加入拓扑(rejoin)和重新构建从节点(rebuild)。

最后一个问题就是怎么做恢复了,对于Master节点,在主从架构下,恢复时第一个要考虑的问题是如何选主,根据前面提到的业界两种高可用方案,我们把选主抽象为分布式选主和集中式选主。分布式选主是指集群内所有可用节点同时参与选主,比如Raft/Paxos多数派投票选主;集中式选主是根据Agent上报的状态信息,以及一定的策略来进行选主,比如数据最新优先或者权值优先。我们采用的选主方法是,在满足多数派情况下的多策略选主。比如,策略1:可以指定节点优先,这种策略主要使用场景是手动发起切换;策略2:最大权值优先,其应用场景是多个从节点设备配置不一致,在故障发生时,期望优先切换到配置高的从节点,这个策略在MGR中有用到;策略3:数据最新优先,这个策略一般都是要保证的。

为了说明我们选主的过程,这里给出一个示例图。我们会把一个MySQL集群抽象为一个节点集,比如说一主两备架构下,有三个节点A、B、C,A是Master,B和C是Slave,在A节点故障时,我们得到一个异常集A和正常集B、C,这里正常集节点数需要满足多数派,如果不满足不能发起切换;在正常集中挑选候选集,这时就用到刚才提到的策略,首先如果指定了某个节点,该节点就为候选集节点,如果没有指定就去比较权值,权值大的为候选集节点,如果权值都相同,则都为候选集节点,图中我们假设B、C权值相同;然后,我们会在正常集节点中找数据最新的节点,假设B节点数据最新,然后其他节点去跟最新节点同步数据,得到一个同步集B、C,同步集也需要满足多数派;同步集中数据回放完成的节点跟候选集中的节点做一个交集,从交集中选择一个做目标节点。选择好节点后,下面要做的事情就是恢复了。针对恢复,一个很重要的问题是,如何能够尽可能快的恢复?

下面针对CynosDB的基础版,说明一下我们是如何做快速恢复的。首先我们看下CynosDB的实例架构,大致是这样,上下分为计算层和存储层,计算层每个实例机器是由一组Mysqld进程和一个与存储层交互的的Client组成;存储层是一个分布式的存储系统,我们叫TXStore。熟悉MySQL恢复过程的小伙伴都知道,恢复的原理其实是获取一致性位点的过程,只要拿到这个位点,MySQL就会知道恢复到哪个位置,然后根据保存的Redo和Undo去做事务提交或者事务回滚。对于CynosDB来说,这个一致性位点我们称为卷持久化序列号,简称VDL。下面说下在CynosDB中如何快速获取VDL。

这里先说下迷你事务(mtr)的概念,MySQL中的每个事务在InnoDB引擎层会有很多个mtr,每个mtr在Redo中有很多个log组成。这里假设我们上次的一致性VDL是3(L-VDL=3), 现在正在写入3个mtr:mtr1、mtr2、mtr3,其中mtr1有三个log组成L1~L3,mtr2有两个log组成L4和L5,mtr3有L6和L7组成。具体VDL的恢复原理是:首先,client通过广播L-VDL的方式获取存储层所有tablet的已完成的最大持久化点(CPL),这里假设从三个tablet获取到的CPL是4、7、5;然后,我们使用二叉堆对获取到的所有CPL排序,得到系列3、4、5、7,由于6还没有持久化,所以获取的最大连续CPL=5,同时L5是mtr2最后一个log,所以我们得到新的VDL=5。

具体是怎么恢复的?我们来看一个示例,在做恢复的时候,client会去做广播,获取每一个tablet的CPL点。对于每一个tablet,我们作为二叉堆上的一个节点,根据每个节点最头部的日志号(LSN)构建一个最小二叉堆。恢复的时候,我们从二叉堆中获取第一个最小的LSN=1, 从堆顶节点拿到1之后,节点剩下一个5,此时最小堆会有一个调整的过程,调整后变成图②,这样5被调整到最下面;然后继续从堆顶节点得到一个2,然后拿到3,以此继续,最后我们会得到这样一个从1~11的CPL序列。由于LSN=8的日志还没有持久化,所以会把8及其以后日志都truncate掉,这样就得到一个1~7的连续CPL序列。此时,如果7是一个mtr最后的一个日志,则得到的最终VDL=7。但是如果7是mtr中间的日志,比如,假设1~3属于mt1,4~5属于mtr2, 6~8属于mtr3, 则此时会进一步truncate掉日志6和7,得到最后的VDL=5。这样我们最终得到返回给计算层,计算层去做进一步的恢复。这就是CynosDB中VDL快速恢复的基本过程,我们通过并发广播和二叉堆排序来保证恢复的性能。

说完恢复之后,我们来看一下CynosDB高可用系统的整体架构。主要有两个模块,Agent和Scheduler。Agent与Mysqld同机部署,不断地去采集Mysqld状态,上报状态数据给Scheduler;Scheduler根据任务调度策略和切换策略,发起HA任务;不同的HA任务完成不同的恢复工作,比如switch主要做多策略下的多数派选主及主从切换,rejoin负责修复主从状态,rebuild在rejoin失败的情况下对从节点进行重建。对于Agent,是无状态的,在故障时,我们抛弃了crontab,使用supervisor来秒级拉起;对于Scheduler,我们通过ZK保证它的高可用,同时保证同一时间只有一个Scheduler正常服务。

介绍完CynosDB的高可用系统后,现在我们来看下针对高可用系统设计中的经典“脑裂问题”,在CynosDB中是如何解决? 首先我们以CynosDB基础版为例,描述一下“脑裂问题”。假设我有一个CynosDB的基础版实例,高可用系统中的Agent在不断的采集实例状态上报Scheduler,突然在某个时刻,实例机器与Scheduler机器发生了网络隔离,由于Agent与Scheduler之间通信超时,Scheduler此时认为机器故障了(实际上并没有),发起主节点的切换操作,假如切换到另一台机器后,网络又恢复了,这样对于应用来说,存在两个同时可写的实例,于是就产生了“脑裂”。

CynosDB是如何解决这个“脑裂”问题的呢?我们在每个实例最开始创建的时候,会在存储层记录下每一个实例的实例版本号,也就是记录在TXStore这块,如果出现网络隔离的发生切换的时候,高可用系统会通知TXStore把实例版本号加1,这样旧节点上写下来的IO请求使用的是旧版本号,版本号落后于新版本号,会返回IO失败,这样MySQL内核发现IO失败原因是版本号过低,就会自动退出。以此达到规避“脑裂”的目的。

以上就是本次介绍的全部内容,这里对本次内容做一个总结。首先从三个问题的角度介绍了如何一步一步设计CynosDB的高可用系统的,然后介绍了CynosDB中VDL的快速恢复原理,接着是整个CynosDB高可用系统的整体架构介绍,最后阐述了CynosDB是如何解决经典“脑裂”问题的。

Q:我们因为业务需要要部署不同地区的系统,要不同地域之间实施数据的一致性,用CynosDB的话,有比较成熟的方案吗?我们系统现在主要是用腾讯云的北京和广州,咱们这边有没有好的方案。

A:CynosDB在计算层是一主多从的架构,在存储层可以保证数据的多个副本分布在多个可用区,数据的一致性在存储层来保证。所以CynosDB可以满足跨AZ数据一致性的需求。

Q:意思是不同的地域往一个地区写吗?现在我们好像需要多写。

A:多写这种架构,除了spanner,还没有能搞定的存储系统,多主架构我们也在开发中,可以关注一下后续CynosDB的进展。

Q:还有是我们的数据量,数据量每天在一个表里面是三千万左右,我们现在的开发也很简单,每天一个表,现在的存储已经比较吃力了,所以说如果用CynosDB之后,里面数据会在存储层自动分层还是会有什么好的优化?

A:对于存储,CynosDB其实解决了用户一个最大的痛点,单机存储量的上限, CynosDB一个实例可以做到上百TB,存储量基本没问题。你刚才说的每个表,可能有三千万行的数据,对于这个,分库分表还需要业务去做,CynosDB不会自动分库分表,每个表中具体数据量多少比较合适,这个是MySQL自己本身的限制,一般情况建议最多千万级的,上亿的话对整个查询性能都有影响了。

Q:比如我们现在还是一种架构直接迁移到CynosDB上,性能会有提升吗?

A:架构整个迁移不会有任何问题的,迁移会带来性能上很大的提升,以及不用考虑存储上限的问题,这些都能解决。

Q:我们的业务跟之前类似,是跨地区的,如果这种情况下写入的时候会有延迟是吧。

A:是多个地区写同一个Master吗?

Q:对,仅单数的情况,对性能的损耗和延迟,相对传统的MySQL来说,数据库对于一个连接数和处理的性能方面,有什么更好的提高吗?

A:连接数方面跟传统MySQL保持一致,性能方面,CynosDB由于在计算层和存储层都做了很多优化,比如锁拆分和减少IO,所以会带来性能上很大的提升。

Q:这个大并发是对于磁盘还是?

A:不是基于磁盘,因为CynosDB不会在本地有保存数据文件,所有的数据都存在底层,这个大并发下的性能提升主要是通过在计算层砍掉了很多不必要的IO、锁拆分以及线程池等手段来保证的。

Q:因为之前我们使用腾讯的MySQL,它对于IOPS是针对磁盘以及存储的。

A:CynosDB主要是网络IO。

Q:也就是用新数据库会避免这个问题是吗?

A:对,首先本地磁盘IO少了很多,在不开启binlog的情况下,基本都是网络IO,其次,存储层的IO包括写日志的顺序IO和apply时的随机IO,随机IO是异步的。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 王甲坤:如何设计和实现高可用的MySQL

    下面开始我们今天的主要内容,今天主要是通过什么、为什么、怎么做,这条思路跟大家呈现MySQL的高可用。

    云加社区技术沙龙
  • 邹建平:智能化大数据平台打造实践

    12月15日,由腾讯云主办的首届“腾讯云+社区开发者大会”在北京举行。本届大会以“新趋势•新技术•新应用”为主题,汇聚了超40位技术专家,共同探索人工智能、大数...

    云加社区技术沙龙
  • 张善友:基于Kubernetes 构建.NET Core 技术中台

    5月25日,云+社区技术沙龙-互联网架构成功举办。本期沙龙特邀请腾讯的技术专家分享关于技术架构、落地实践案例、无服务器云函数架构、海量存储系统架构等话题,从技术...

    云加社区技术沙龙
  • 江苏省初中信息技术八年级 -张叔叔一文读懂

    今天张叔叔给大家讲讲江苏省八年级信息技术教材内容,之前的七年级教材讲解收到了热烈欢迎,在此感谢所有的读者们,也希望大家积极转载,为社会主义建设添砖加瓦!

    张叔叔讲互联网
  • ASP.NET + SqlSever 大数据解决方案 PK HADOOP

    ASP.NET + SqlSever 大数据解决方案 PK HADOOP 半个月前看到博客园有人说.NET不行那篇文章,我只想说你们有时间去抱怨不如多写些实在的...

    逸鹏
  • 深度学习word2vec笔记(算法篇)

    一. CBOW加层次的网络结构与使用说明 Word2vec总共有两种类型,每种类型有两个策略,总共4种。这里先说最常用的一种。这种的网络结构如下图。 ? 其中第...

    机器学习AI算法工程
  • MongoDB事务模型分析

    在了解写操作的事务性之前,需要先了解mongo层的每一个table,是如何与wiredtiger层的table(btree)对应的。mongo层一个最简单的ta...

    MongoDB中文社区
  • [LeetCode] Symmetric Tree

    1、题目名称 Symmetric Tree https://leetcode.com/problems/symmetric-tree/ 2、题目内容 Give...

    程序员小王
  • 树的遍历 Traverse a Tree

    值得注意的是,当删除树中的节点时,删除过程将按照后序遍历的顺序进行。也就是说,当你删除一个节点时,你将首先删除它的左节点和它的右边的节点,然后再删除节点本身。

    爱写bug
  • 第19问:MGR 架构,如果一个节点网络不稳,消息缓存会被撑满么?

    1. MySQL 版本为 8.0.21(随 8.0 的小版本升级,MGR 参数和行为变更频繁,需要特别注意版本号)。

    爱可生开源社区

扫码关注云+社区

领取腾讯云代金券