黄东旭解析 TiDB 的核心优势
827
2023-05-05
数据库高可用方案PK:选择***还是MySQL?
关于***和MySQL的高可用方案,其实一直想要总结了,今天分为几个系列简单说说。通过这样的对比,会对两种数据库架构设计上的细节差异有一个基本的认识。
高可用方案概览
***有一套很成熟的高可用解决方案MAA。用我在OOW上的ppt来看,这个方案自9i开始,到今年已经有16个年头了。
当然,MAA方案虽好,成本还是有的、复杂度还是有的,所以放眼国内的使用情况,RAC不一定是100%有,电信、证券、寿险、银行如果用,基本都是全套方案,有些相对保守,RAC也有使用active-passive模式的,互联网行业如果用,清一色都是单实例和DG结合。
而MySQL因为开源的特点,官方和社区里推出了很更多的解决方案,高可用情况大体如下,仅供参考(数据引用自Percona)。
因为时间的原因,MGR刚推出不久,还在观察期。MGR固然不错,MySQL Cluster方案也有PXC、Galera等方案,个人还是更倾向于MHA。
基本情况说完了,接下来分为几个部分来解读。
*** RAC和MySQL MHA
先拿RAC和MHA来做一个基本的对比。
***的解决方案在阿里快速发展时期支撑起了核心业务的需求。大概是这样的架构体系,看起来很庞大。里面的RAC算是一个贵族,用昂贵的商业存储,网络带宽要求极高,前端大量的小机业务还有不菲的license费用。非常典型的IOE的经典架构。
如果要考虑异地容灾,那么资源配置要double,预算翻番。
MySQL的架构方案相对来说更加平民化,普通的PC就可以,但数量级要高,做业务拆分、水平拆分就能够横向扩展出非常多的节点,很多大互联网公司的MySQL集群规模都是几百几百的规模,上千都不稀奇。如此之多的服务资源,发生故障的概率还是有的,保证业务服务的可持续性访问是技术方案的关键。如果按照MHA的架构,基本上就是MHA Manager节点来负责整个集群的状态,好比一个居委会大妈,对住户的大大小小的事情都了如指掌包打听。
当然上面的架构图过于笼统,在MHA的高版本里面还使用了binlogServer,我们从一些细节入手。比如先来说说网络的事情。
***对于网络的要求还是很严格的,一般都是要2块物理网卡,每台服务器需要至少3个IP:Public IP、private IP、VIP,除了共享存储,至少需要2个计算节点。
private IP是节点间互信的,Public IP和VIP在一个网段,简单来说,VIP是对外的,是public IP所在网络的漂移IP,在10g里面都是通过VIP来做负载均衡的,11g开始有了scan-IP,原来的VIP还是保留,所以***里面的网络配置要求还是很高的。抛开共享存储,搭建的核心就是网络配置了,网络通则通。
当然网络层面不只是这些,我们还有必要了解下TAF(Transparent Application Failover)。TAF是***中对应用透明的故障转移,在RAC环境中使用尤其广泛。在RAC中Load Balance这块确实做了很大的改进,从10g版本开始的多个VIP地址的Load Balance,到11g版本中的SCAN,做了很大的简化。
而在Failover的实现中,还是有一定的使用限定,比如11g中默认的SCAN-IP的实现其实默认没有Failover的选项,如果两个节点中的其中一个节点挂了,那么原有的连接中继续查询就会提示session已经断开,需要重新连接。客户端TAF主要会讨论Failover Method和Failover Type的一些简单内容。
(1)Failover Method
Failover Method的主要思路就是换取故障转移时间,或者换取资源来实现。
可以这样来理解,假设我们存在两个节点,如果某个session连接到了节点2,然而节点2突然挂了,为了更快处理Failover这种情况,Failover Method有preconnect和basic两种。
preconnect这种预连接方式还是会占用较多的资源使用,在各个节点上会预先占用一部分额外的资源,在切换时会相对更加平滑,速度更快。basic这种方式,则在发生Failover时,再去切换对应的资源,中间会有一些卡顿,但是对于资源的消耗相对来说要小很多。
简单来说,basic方式会在故障发生时才去判断,而preconnect则是未雨绸缪;从实际的应用来说,basic这种方式更加通用,也是默认的故障转移方式。
(2)Failover Type
Failover Type实现更加丰富而且灵活,非常强大。这时控制粒度可以针对用户SQL的执行情况进行控制,有select和session两种;通过一个小例子说明一下。
比如,我们有个很大的查询在节点2上进行,结果节点2突然宕机了,对于正在执行的查询,比如说有10 000条数据,结果刚好故障发生的时候查出了8 000条,那么剩下的2 000该怎么处理。
第一种方式就是使用select;即会完成故障切换,继续把剩下的2 000条记录返回,当然中间会有一些上下文环境的切换,对于用户是透明的。
第二种方式是session;即直接断开连接,要求重新查询。
在10g版本中借助于VIP的配置达到Load Balance+Failover的配置如下:
racdb=(DESCRIPTION =(ADDRESS= (PROTOCOL= TCP)(HOST=192.168.3.101)(PORT= 1521))(ADDRESS= (PROTOCOL= TCP)(HOST=192.168.3.201)(PORT= 1521))(LOAD_BALANCE = yes)(FAILOVER = ON)(CONNECT_DATA =(SERVER= DEDICATED)(SERVICE_NAME = racdb)(FAILOVER_MODE =(TYPE= SELECT)(METHOD= BASIC)(RETRIES = 30)(DELAY = 5))))
如果11g的SCAN-IP也想进一步扩展Failover,同样也需要设置failover_mode和对应的类型。
RACDB =(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = rac-scan)(PORT = 1521))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = RACDB)))
从这个角度来看,***的方案真是精细。
再来看看MySQL的方案。
分布式的方案,让MySQL看起来像一把瑞士军刀,对于网络层面的要求,几乎可以说MySQL没有什么要求,申请一主一从的架构,那么就只需要4个IP即可(主、从、VIP、MHA_Manager(考虑一个manager节点)),一主两从是5个。
这一点上,MySQL原生并不支持所谓的负载均衡(这里说的不是读写分离),可以通过前端的业务来分流,比如使用中间件proxy,或者持续的拆分,达到一定的粒度后,通过架构设计的方式来满足需求。因为基于逻辑的复制,很容易扩展,一主多从都是很常见的,代价也不高,延迟不能说没有,只是很低,能够适应绝大部分的互联网业务需求。
而说到触发MHA切换的条件,从网络层面来看,如下的红点都是潜在的隐患,有的是网络的中断,有的是网络的延迟,发生故障时,保数据还是保性能稳定,都可以基于自己的需求来定制。从这一点上来说,丢失数据的概率是有的。绝对不是强一致性的无损复制。
把上面的图放大,其实会有更多的细节,比如ssh的连接检测和数据库的心跳检测(insert_ping),在整个方案里面要考虑的场景就很多了。对于网络的切换,目前MHA做的主要是保证数据复制关系,如果要深入使用,还是要做更多的定制,比如结合Proxy的方案,使用ZooKeeper的状态检测,使用keepalive或者VIP的网络层面的切换等。
整体来看两种方案,RAC是集中共享,除了存储层面的共享外,网络层面的组播其实也会提高节点间通信的成本,所以RAC对于网络的需求很大,如果存在延迟是很危险的,发生了脑裂就很尴尬了。MySQL MHA的方案是分布式的。支持大批量的环境,节点间通信的成本相对来说要低很多。但是从数据架构的角度来说,因为是复制的数据分布方式,所以对于存储尽管不是共享存储,对于存储的成本还是高于RAC(不是说存储的价格,是存储的数据量大小)。
*** Data Guard和MySQL灾备
然后我们来继续说说灾备的部分。我就拿***的DG和MySQL的方案对比。
在灾备的概念中,*** DBA习惯叫做主备,即为Primary、Standby,而MySQL更喜欢叫做主从,即为Master、Slave,无论怎么叫,说得都是同一个意思。
首先在***中,数据是基于物理复制(此处说的都是physical standby),所以对于数据库的状态和角色就很好定位,从库正常状况下是无法读写的。所以在***中角色转换的概念就很清晰,failover和switchover,failover就是故障转义,switchover就是主备切换。在MySQL中failover的概念很好理解,但是switchover相比来说,就会淡化很多。
***因为是基于物理复制,所以一直以来备库要么就是恢复状态(recover),要么就是只读不应用状态(read_only),直到11g这个问题才解决,就是大名鼎鼎的ADG(read only with apply)。而在MySQL里面这都不是事儿,备库可以灵活的开关read_only的参数,当然一般是不希望备库写入的,读绝对不是问题,而且还可以扩展着读,做读写分离。
对于***的备库的理解,我认为除了ADG之外,最有亮点的就是闪回数据库了,可能很多*** DBA都对于闪回数据库敬而远之,技术的更新很多,好端端的特性放着不用太可惜了,比如搭建DG,分分钟DG Broker搞定,使用手工方式不见得有多高效。
闪回的概念在MySQL里面也有,目前来说,可以根据binlog抽取的数据做到DML的闪回,和***里面的闪回差距还很大。***里面的闪回五花八门,零零总总算下,差不多就有这些。
当然常用、实用的不见得这么多,MySQL的DML还算是原生态,可以根据binlog抽取来恢复,或根据第三方工具辅助,但DDL就是难上加难了,目前MariaDB的DDL闪回就是一个突破,从我的理解来说,应该能够实现一部分的闪回功能,具体的效果我后面测试一下。
所以说闪回是个大宝藏,到底有多好呢,***的备库方案有了快照数据库,就是物理备库可以临时写入,带来的优点就是主库的碎片,在备库是完全一样的。所以在SQL审核方面有着得天独厚的优势,我在线上的很多DDL审核中都做过测试和实际应用,效果很赞,而且11g中的闪回可以在线开在线关,所以一般10g里面我建议要慎重使用,11g有条件下备库端还是推荐的,满足需求就行。当然闪回数据库不是万金油,有个别场景是不支持的,在此就不展开了。
对于灾备来说,数据库的切换是未雨绸缪的事情,那么到底备库切换的检查是否OK呢,***里面有了DG Broker这么一个神器,还在新版本中做了很多不错的选项,比如新版本中有了validate的选项,可以检测主备切换的条件是否满足。下面是DG Broker的命令中多出来的validate命令,效果还是不错的。
此外,从高可用的角度来说,如果在备库存在连接,做switchover时,会话会持续保持,当然会有短暂的卡顿。这也就是特色的会话保持特性。
Preserving Active Data Guard Application Connections
当然在MySQL里面就不可理解了,切换别说会话保持,卡顿的影响都微乎其微。因为***基于物理复制的方式,物理一致性使得复制扩展性很难,当然也不是说完全不能实现,比如cascade standby,可以级联复制,到了12c改进一版,就是Far Sync,号称是零数据丢失,对于跨区域的数据中心来说,会把延迟降到最低。
如果从技术架构的角度来看,部署的分布图类似下面的形式,中间有远距离的数据传输,可以通过中间的节点来转换,中间这个节点很特别,是不存数据的,只是保持一个内存结构,同步数据。
还有就是延迟,我测试过DG的延迟,和MySQL在基本相似的压力情况下,***基本上控制在0.1秒左右,MySQL的复制就会有一些延迟的放大。
所以总体看下来,***的方案是一种很专业的解决方案,工具全,架构相对复杂,数据同步是强一致性。所以在涉及交易的业务中对它更加偏爱。
再来看看MySQL方向的改进。我们不比单机性能和延迟了,因为这个确实是有差距,而且硬拼也没有太大的意义,我们从整体架构角度来考虑,这些又是***难以实现的地方。
首先说下主从复制,MySQL是典型的逻辑复制,主库端可以承载大批量的并发,但是性能瓶颈很明显,主库的并发最后落到文件上还是串行的,抛开日志传输进程的开销,最大的瓶颈就在于SQL_Thread的应用延迟。就好比中午大家出去吃饭,前台可以并发点很多的菜品,但后台的厨师就好比是SQL_Thread,他得一道菜一道菜做啊。怎么能做得更快呢?比如你叫了5分盖饭,他可以一次性炒出来,这样就能够大大提高效率,所以前台的小姑娘也会建议你和其他人点一样的菜,原因就一个字——快。这用在并行复制上就是类似的道理。MySQL 5.6没法做到细粒度的并行复制,只能在库级别,而在MySQL 5.7中可以做到表级别更细粒度的,这个改进就很明显了。
所以延迟的问题能够解决,后续的扩展就容易多了,MySQL的扩展甚至可以做到指数级的扩展方式,如果允许一些低延时,大量的读请求就可以逐步分解。所以一主多从的架构方式也是见怪不怪。
值得一提的是MHA的一主多从架构中,如果多个从库存在延迟,在切换的时候MHA会补齐差异的日志,这是MHA的一大亮点。
而MySQL的级联复制就更纯粹了,和***相比的最大优势就是一个数据库可以既是主库也可以同时是从库,起到承上启下的作用。
这种扩展方式简直是酸爽,在一些跨数据中心的场景,允许一定延迟的情况下还是有用武之地。比如你需要从北美读数据,可以从北美推送数据库到香港或者新加坡,再推送到北京。有了这种方式就很容易扩展。当然在实时交易中还是存在一些瓶颈和缺陷。
展望和后续补充
如果抛开具体的数据库,整体来说数据量和业务量到达一定程度都会碰到一系列的问题。这些都是痛点也是难点,常见的问题如下:
单台服务器无法承载已有的压力数据库单表容量越来越大大量的读写需求无法平衡资源如果扩容,应用改动较大资源的负载没法拆分,或者不易拆分
这时就需要扩展,就需要匹配的解决方案,比如中间件的方案,有的解决了一些通用的问题,有些侧重于某一方面。比如需要考虑sharding来分片,读写分离来做分担读写压力,前端海量访问可以通过大量的水平扩展来分担。
从这个角度来说,MySQL是以架构和规模取胜,通过业务拆分和架构拆分能够实现线性扩展。而***的扩展性虽然没有那么好,但从架构和业务层面来说也能做,这个后续有机会再细细说一说,可以拟一篇分布式方面的文章。
小结
简单总结一下,高可用的方案选择很多,各家有各家的需求,能定制的定制,能开源的开源。大道至简,只要满足了需求,系统稳定不背锅,那就是最好的方案。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。