为帮助开发者更好地了解和学习分布式数据库技术,2020年3月,腾讯云数据库、云加社区联合腾讯TEG数据库工作组特推出为期3个月的国产数据库专题线上技术沙龙《你想了解的国产数据库秘密,都在这!》,邀请数十位鹅厂资深数据库专家每周二和周四晚上在线深入解读TDSQL、TBase、CynosDB三款鹅厂自研数据库的核心架构、技术实现原理和最佳实践等。三月为TDSQL专题月,本文将带来直播回顾第三篇《破解分布式数据库的高可用难题:TDSQL高可用方案实现》。点击下图观看直播回放及领取PPT:
以下是分享全文:
大家好,今天我分享的主题是TDSQL多地多中心高可用方案。TDSQL是腾讯推出的金融级分布式数据库。在可用性和数据一致性方面,基于自主研发的强同步复制协议,在保证数据的跨IDC双副本的同时,具备较高的性能。在强同步复制的基础上,TDSQL又实现了一套自动化容灾切换方案,保证切换前后数据零丢失,为业务提供7×24小时连续高可用服务。
事实上,不光是数据库,任何对可用性有较高要求的系统都需要具备高可用的部署架构。这里面会涉及到一些专业术语如:异地、多活、双活、选举等,今天的分享中都会讲到,除此之外还包括我们耳熟能详的两地三中心、两地四中心、同城双活等概念。值得一提的是,今天这次分享不光是对数据库,对任何高可用系统的部署架构都具有参考借鉴的意义。
本次分享我们会介绍TDSQL的几种典型部署架构,以及各种架构的优缺点。因为在实际生产实践中,会有各种各样的资源条件限制,比如同城有一个机房和有两个机房的容灾效果就完全不一样。再比如虽然有两个机房,但是这两个机房的规格相差比较大,有的机房可能网络链路比较好,而有的机房可能网络链路比较差,等等…所以,如何在有限的资源条件下搭建一套性价比高或者说效能比高TDSQL,是我们这次分享要探讨的主要内容。
在正式切入正题前,我们先回顾一下上一次分享有关TDSQL的核心特性以及整体架构。
好,接下来我们先看一下TDSQL核心特性。
我们今天的重点聚焦在“金融级高可用”上。TDSQL如何做到99.999%以上的可用性呢?所谓五个九的高可用意味着的是,全年不可用时间不可超过5分钟。我们知道,故障是一种无法避免的现象,同时故障也是分级的,从软件故障,操作系统故障,再到机器重启、机架掉电这是一个灾难级别从低到高的过程,对于金融级数据库需要考虑和应对更高级别的故障场景,如:整个机房掉电甚至机房所在的城市发生地震、爆炸等自然灾害。如果发生这类故障,我们的系统首先能否保证数据不丢,其次在保证数据不丢的前提下需要多久恢复服务,这都是金融级高可用数据库需要考虑的问题。
TDSQL数据库一致性:强同步机制是最核心的保障
首先,我们回顾一下TDSQL的关键特性—强同步机制,它是TDSQL保证数据不会丢、不会错的关键,并且相比于MySQL的半同步复制,TDSQL强同步复制的性能更是接近于异步。
那么这个高性能强同步是如何工作的呢?强同步复制要求任何一笔应答业务成功的请求,除了在主机落盘成功以外,还需在至少一个备机落盘成功。所以我们看到,一个请求到了主机之后,立刻发送发给备机,当两台备机中的一台应答成功之后主机才能应答业务成功。也就是说任何成功应答给前端业务的请求一定会有两个副本,一份在主节点上,另外一份在备节点上。所以,强同步是数据多副本的关键性保障。TDSQL通过引入了线程池模型与灵活的调度机制,将工作线程异步化,实现了对强同步的性能大幅提升,改造后其吞吐量接近于异步。
TDSQL核心架构
看完强同步,我们接下来再回顾一下TDSQL的核心架构。负载均衡是业务的入口,业务请求经过负载均衡到达SQL引擎模块,SQL引擎再将SQL转发到后端数据节点。图中的上半部分是集群的管理调度模块,作为集群的总控制器承担着资源管理、故障调度等工作。所以,TDSQL整体分为:计算层、数据存储层,以及集群管理节点。集群管理节点我们之前强调过,一个集群部署一套就行,一般是3个、5个、7个这样的奇数个部署。为什么是奇数呢?因为当发生灾难的时候,奇数个能够形成选举,话句话说,比如3个节点部署在3个机房,其中有1个机房故障的话,而另外两个机房可以互通并且都连不上第三个机房,就可以对第三个机房故障达成共识将其踢除。我们可以把三个机房的管理模块理解为集群的三颗大脑,这组大脑坏掉一个后,如果剩余的大脑能够在数量上达到初始数量的一半就可以继续提供服务反之则不行。
高可用集群的部署实践
以上是对TDSQL一些核心特性的回顾,接下来我们看一下各个模块在机型上的选择。对于计算与存储相分离的分布式架构数据库,我们该如何选择机器?我们知道,要想让一个IT系统发挥出最大的价值,就是要尽可能地榨干机器的资源,让这些资源物有所值效能比高。如果这个机器CPU跑得很满,但是IO没有什么负载,或者说内存配128个G但实际上只用了2个G。这种就属于效能比非常低的部署,无法发挥出机器以及系统的整体性能。
首先是LVS模块,首先作为接入层它不是一个TDSQL的内部组件,TDSQL的SQL引擎兼容不同的负载均衡,比如软件负载LVS、硬件负载L5等。作为接入层的负载均衡一般都是CPU集型服务,因为它需要维护管理大量链接请求,相对较为耗CPU和内存。所以这里推荐的配置中CPU比较高,16vCPU,32G内存,一定是万兆网口。到了今天,网卡设备的成本已经非常低了,所以一般都给装配万兆网卡。而vCPU这里强调的是逻辑核16核就可以(可能实际物理核只有8个),因为我们大部分程序都是多线程的。
我们再看计算节点。如果集群规模较小,同时资源相对比较紧张,计算节点可以跟存储节点复用机器,因为存储节点的机型基本能够满足计算节点的需求,一个16vCPU,32G+内存,万兆网口。
说完了接入层和计算层,下面我们再看看数据存储层。存储节点负责数据存取,属于IO密集型服务,建议用PCI-E的SSD,并且需要独站物理机。对于数据库来说,我们推荐部署在真实的物理机上,相比虚拟机更为稳定。此外,有条件的建议再做一层Raid0,让数据节点的读写能力更为强劲。有些同学肯定会问,数据节点为什么不做一个Raid5、Raid10而直接做Raid0。因为TDSQL本身已经是一主多从的架构,甚至可以加更多从机,在磁盘阵列这里我们就没必要继续做冗余,无限冗余只会让效能比降低。作为数据节点,这里推荐的配置是32vCPU,64G内存。数据节点采用的Innodb引擎是一个优先使用缓存的引擎,也就是说大内存对性能的提升具有显著的作用。所以,这里推荐大内存,万兆网,PCI-E的SSD的机型。
接下来是管理节点:推荐配置是8核CPU、16G内存,万兆网口。管理节点任务比较轻,一个集群也只需要少量的管理节点。如果说没有物理机用虚拟机也可以,配置相对于前面的计算、存储节点明显可以低一些。
备份节点的话,硬盘越大越好,它主要负责存储冷数据,用普通的SATA盘就可以。
以上机器的型号不用太关注,是腾讯内部的一个编号,没有什么实际意义。这里简单做一个总结,计算节点依赖CPU和内存,对磁盘没有太多要求。存储节点虽然对CPU内存也要求较高,但它更强调IO的强劲(需要PCI-E的SSD)。
通过刚刚的介绍希望可以帮助大家进一步加深对TDSQL,尤其是这种计算存储相分离的数据库的认识。从机型配置的解读我们可以清楚的了解,怎样的机型搭配能够让系统的性能发挥最佳。
总结起来,如果机型正确搭配,业务也按照规范使用,那么就可以轻松发挥出数据库强劲的性能,即以较低的运营成本获取较高的业务支撑能力。海量的业务都是伴随着现金流,比如说广告、游戏、电商,一套低成本的系统如果在满负荷工作下轻松高效处理这类业务请求,带来的经济效应是比较可观的。
跨城跨机房级别容灾部署方案
第三部分,开始切入我们的正题,这一章我们将介绍比较典型的几种部署方案,那些耳熟能详的名词:同城三中心,两地三中心,异地多活,同城双活分别代表什么意义,或者说能带来什么样的效果呢。接下来就为大家一一将这些问题的答案揭开。
“同城三中心”架构
第一部分是同城三中心架构。同城三中心顾名思义:在一个城市有A、B、C三个机房,TDSQL仍采用“一主两备”结构,很显然我们需要将三个数据节点分别部署在三个机房,其中主节点在一个机房,两个备节点分别部署在另外两个机房。
每个IDC提供两台高可用的LV5做负载均衡系统。为什么每台IDC都要放一个LV5?因为每个IDC有自己的业务,对应都需要有一个独立的负载接入。从接入层看三个机房是一个相对平行的对等架构,三个机房都放了自身的业务,可能第一个机房支撑的是一个全国大区的业务,第二个机房是另外一个大区,对等就是这样的含义。这种架构比较简单,整体也比较清晰。
我们再看架构图,刚刚说了它是一个对称的结构。从上往下首先看业务,每个机房可能都部署有业务系统,每个机房的业务通过LVS负载接入访问到TDSQL的SQL引擎。由于在同一机房需要部署多个SQL引擎提供高可用服务,而对于业务来说更希望屏蔽后端多个SQL引擎的访问方式,所以这里引入一层LVS接入层,业务只需访问负载均衡的VIP即可。当请求到达SQL引擎后,根据路由信息将SQL发到master或者slave节点,最后返回业务数据。我们再看数据节点,一主两备分别部署在三个机房,任何一个机房故障,master节点都可以切换到另外两个机房中的一个。同城三中心架构下,从计算层到存储层都不存在单点,做到了高可用容灾。任意一个机房的故障都不会造成数据丢失,同时在TDSQL一致性切换机制的保证下,能够在30s内完成故障节点的切换。
这个图里面没有画出管理节点,我们刚刚也说了管理节点可以看做整个集群的大脑,负责判断当前的全局态势。三个机房很明显需要部署三颗大脑,之所以是“三”刚刚也讲过,当其中一个大脑出问题的时候,另外两个可以形成多数派,完成相互投票确认将故障大脑踢除。
“同城单中心”架构
“同城单中心”架构的场景有几种情况:
第一种场景是IDC资源比较紧张,只有一个数据中心。这种场景下做不到跨机房部署,只能按照跨机架方式部署,当主节点故障或者主节点所在的机架故障,能够自动切换。
第二种场景是业务追求极致的性能,甚至不能容忍跨IDC网络延迟。虽然现在的机房之间都是光纤网络,相隔50km的两个机房之间的网络延迟也只有不到1ms。但有些特殊的业务甚至无法忍受1毫秒的延迟。这种情况下我们只能将主备部署在同一机房。
第三类是作为异地灾备机房。作为灾备储存一般也没有实际业务访问,更多的可能是做备份归档,因此对它的资源投入比较有限。
第四种是作为测试环境,这个就不多说了。
“两地三中心”架构
接下来跟大家聊一聊这次分享的主角——“两地三中心”架构,它是银行常见的部署方式,更是监管要求的基本部署架构。这种架构通过同城两个数据中心加异地一个数据中心,在较低的成本下,提供较好的可用性和数据一致性。在节点异常、IDC异常都能做到自动切换,非常适合金融场景,是TDSQL重点推荐的部署方式。
“两地三中心”数据库实例的部署架构
部署方式方面,我们从上往下看,分别是同城两个机房和异地一个灾备机房。最上层是集群的大脑管理模块,分别跨三个机房部署。
管理模块的部署可以采用“2+2+1”也可以“1+1+1”的方式。我们知道,如果按照“2+2+1”的部署方式,当第一个机房故障时,还剩下“2+1”颗大脑,“2+1”比5的一半要多,剩下的“2+1”形成多数派将故障节点踢掉,同时继续提供服务。
继续往下看,我们看到数据节点采用的是“一主三备”的模式,并且是跨机房强同步,同机房异步。为什么同机房这里是异步,不能做强同步?如果同机房是强同步的话,由于它和主节点距离上要比另外两个跨机房的备节点近(IDC1、IDC2之间相隔了平均至少50公里),业务每次发送给主节点的请求都是这个同机房的强同步节点率先应答,最新的数据永远都只会落到同机房的备节点。而我们希望数据的两个副本应该位于相隔50km以上的不同机房,这样才能保证跨机房主备切换时数据能够保持一致。
可能有人会问,这个 IDC1 配置的异步节点和不放没有区别。这里解释一下为什么有了这个异步节点后更好呢。我们考虑一种情况,当备机房IDC2 发生了故障,备机房里面的两个节点全部宕机,IDC 1 这里的master节点就成单点了。此时,如果开启强同步,由于没有备机应答,主节点依然无办法提供服务;但如果关闭强同步继续提供服务,数据存在单点风险,如果这时主节点发生软件硬件故障,数据就再也无法找回。一个比较好的方案是:给IDC1增加了一个跨机架的异步节点,当IDC2挂掉之后,这个异步节点会提升为强同步。这样在只剩下一个机房的前提下,我们仍然能够保证一个跨机架的副本,降低主机的单点风险。
看完主城两个机房,我们再看看异地灾备机房。作为异地灾备机房,一般是和主节点相隔500公里以上,延迟在10ms以上的机房。在这样的网络条件下,灾备节点和主城之间只能采用异步复制的方式同步数据,因而异地灾备节点承担的更多是备份的职责,日常不会有太多正式业务访问。虽然表面上看有点花瓶,没有它却也万万不行。假如有一天发生了城市级别故障,灾备实例仍可以为我们挽回99%以上的数据。正是由于灾备节点和主节点的这种异步弱关系,才允许我们的灾备实例在备城是一个独立部署的单元。
异地灾备机房除了作为异步数据备份外,另外一个重要的职责是:当主城的一个机房故障,通过和主城另外一个正常的机房形成多数派,将故障机房踢掉进而完成主备切换。部署在异地的这个大脑,在大部分时间都不参与主城的事宜,只有在主城的一个机房发生故障时才介入。正常情况下,主城的模块访问主城的大脑,备城的模块访问备城的大脑,不会交叉访问导致延迟过高的问题。
“两中心”架构
聊完“三中心”,我们再来聊聊“两中心”架构。具体来说,同城只有两个机房,根据我们上一个PPT的经验,在两机房部署TDSQL需要按照同机房异步,跨机房强同步的方式部署。因而采用四节点的模式,分布式在2个IDC。
然而“两中心”架构有个需要权衡的地方是,只有部署在备机房而且故障的不是备中心,才能实现自动跨IDC容灾。但如果是备中心故障,事实上,在同机房异步,跨机房强同步的方式下,不管是部署在主机房还是备机房,假如发生故障,无法顺利完成多数派选举以及自动故障切换,要么强同步节点无法被提升形成多数派,要么多数派随机房故障而故障,需要人工介入。因而在高可用要求的场景下,一般更为推荐“两地三中心”等7*24小时高可用部署架构。
标准化高可用部署方案总结
最后我们总结一下今天的分享:
- 首先,对于跨城市容灾一般建议在异地搭建独立的集群模式,通过异步复制实现同步。主城和备成可以采用不同的部署方式,如主城一主三备,备城一主一备的方式灵活自由组合。
- 现网运营的最佳方案是同城三中心加一个异地灾备中心,其次是金融行业标准的两地三中心的架构。这两种架构都能轻松实现数据中心异常自动切换。
- 如果只有两个数据中心,做不到任意数据中心异常都能自动切换,需要一些权衡。
不光是对于数据库系统,任何做一种高可用系统都需要做基于部署架构方面的考量,这就是本次分享的全部,谢谢大家。
Q&A环节
Q:同城主备切换一次多长时间?
A:30秒以内。
Q:两地三中心的主城是不是设置成级联?
A:这个问题非常好,如果从主城的视角看,这显然是一个级联关系,数据先由主城的master同步到主城的slave,再通过主城的slave同步到备城的master,一层层向下传递数据。
Q:请教一下强同步会等SQL回放吗?
A:不会等,只要IO线程拉到数据即可。因为基于行格式的binlog是具备幂等写的,我们通过大量的案例证明它是可靠的。此外,增加了apply反而会使得平均时耗的上升和吞吐量的下降。最后,假如apply有问题,TDSQL的监控平台会立刻识别并告警,提醒DBA确认处理。
Q:备机只存binlog不回放,性能上跟得上主吗?
A:备机拉取binlog和回放binlog是两组不同的线程,分别叫IO线程和SQL线程,并且两组线程互不干扰。IO线程只负责到master上下载binlog,SQL线程只回放拉取到本地的binlog。上一个问题说的是强同步机制不等待回放,并不是说到备机的binlog不会被回放。
Q:同城三中心写存储节点都在IDC1,那么在IDC2的业务延迟是不是很大?
A:同城机房现在都是光纤传输,时耗基本都是做到1毫秒以下,完全没必要担心这种访问时耗。当然,如果机房设施比较陈旧,或者相隔距离间的网络链路极为不稳定,为了追求卓越性能可能需要牺牲一部分容灾能力。
Q:一主两备,SQL引擎做成故障切换有VIP方式吗?
A:当然有,多个SQL引擎绑定负载均衡设备,业务通过VIP方式访问TDSQL,当SQL引擎故障后负载均衡会自动将其踢掉。
Q:这样不是三个业务各自写一个库吗?
A:不是的,三个业务都写到主库。SQL引擎都会路由到主库,一主两备。TDSQL强调任何一个时刻只有一个主提供服务,备机只提供读服务不提供写服务。
Q:同城多副本,多SET对同城IDC之间网络要求有什么?
A:5毫秒以内的延迟。
Q:如果两个强同步主从可以设置其中一个返回?
A:TDSQL强同步默认机制就是等待一台强同步的备机应答。
Q:中间一个节点挂了,异地节点会不会自动连接到主节点?
A:当然会。
Q:强同步和半同步复制相比的优势是什么?
A:强同步跟半同步复制相比,最直观的理解可能有人会问,强同步不就是把半同步的超时时间改成无限吗?其实不是这样的,TDSQL强同步这里的关键不是在解决备机应答的问题,而是要解决这种增加了等待备机的机制之后,如何能保证高性能、高可靠性。换句话说,如果在原生半同步的基础上不改造性能,仅把超时时间改成无限大的时候,其实跑出来的性能和异步比甚至连异步的一半都达不到。这个在我们看来也是无法接受的。相当于为了数据的一致性牺牲了很大一部分性能。
TDSQL强同步复制的性能是在原生半同步的基础上做了大量的优化和改进,使得性能基本接近于异步,并且能实现数据零丢失——多副本,这是DSQL强同步的一个特点。上一期的直播我们介绍了,TDSQL如何实现高性能强同步的。比如经过一系列的线程异步化,并且引入了线程池模型,并增加一个线程调度的优化等。
Q:仲裁协议用的哪一个?
A:多数派选举。