关于Oracle和MySQL的高可用方案,一直想总结一下。今天我就分几个系列来简单说一下。通过这样的对比,你会对两种数据库架构在设计上的细节差异有一个基本的了解。高可用解决方案概述Oracle有一个非常成熟的高可用解决方案MAA。从我在OOW上的ppt来看,这个程序从9i开始已经有16年了。当然,虽然MAA解决方案很好,但仍然存在成本和复杂性。所以从国内的使用情况来看,RAC不一定100%可用。如果用在电信、证券、人寿保险、银行等领域,基本上是一套完整的解决方案。相对保守,RAC也采用主动-被动模式。如果互联网行业用的话,都是单实例和DG的结合。由于开源的特点,MySQL在官方和社区推出了更多的解决方案。高可用的大致情况如下,仅供参考(数据引用自Percona)。由于时间关系,MGR刚刚上线,还在观察中。MGR当然好,MySQLCluster方案也有PXC、Galera等方案。就个人而言,我更喜欢MHA。基本情况说完了,接下来分几个部分来解读。OracleRAC和MySQLMHA先拿RAC和MHA做一个基本的比较。Oracle的解决方案支撑了阿里高速发展时期的核心业务需求。大概这样的架构体系看起来很大。里面的RAC算是贵族了。它使用昂贵的商业存储,需要极高的网络带宽,前端有大量小型计算机服务,还有昂贵的许可费用。非常典型的IOE经典架构。如果要考虑异地容灾,资源配置一定要加倍,预算也要加倍。MySQL的架构方案相对更加平民化。普通PC还好,只是数量级更高。业务拆分和横向拆分可以横向扩展很多节点。很多大型互联网公司的MySQL集群规模都是几百上千的规模并不少见。服务资源那么多,还是有失败的可能。确保对业务服务的可持续访问是技术解决方案的关键。按照MHA的架构,MHAManager节点基本上负责整个集群的状态,就像居委会的阿姨一样,对居民的大小事了如指掌。当然,上面的架构图太笼统了。在MHA的高版本中,还使用了binlogServer。让我们从一些细节开始。比如先说网络。Oracle对网络的要求还是很严格的。一般需要两块物理网卡。每台服务器至少需要三个IP:公网IP、私网IP、VIP。除了共享存储,至少还需要两个计算节点。私有IP是节点之间的相互信任。公网IP和VIP在同一网段。简单的说,VIP是外部的,是公网IP所在网络的浮动IP。在10g中,VIP用于负载均衡。从11g开始有了scan-IP,原来的VIP还是保留的,所以Oracle里面的网络配置要求还是很高的。除了共享存储,构建的核心是网络配置,网络是通用的。scan-IP还可以继续扩展,最多支持3个scan-ip,如下图所示:当然网络层面不仅仅局限于这些,我们还需要了解TAF(TransparentApplicationFailover)。TAF是Oracle中的应用程序透明故障转移,在RAC环境中使用尤其广泛。RAC中的LoadBalance确实有了很大的提升。从10g版本开始的多个VIP地址的LoadBalance,到11g版本的SCAN,都做了很大的简化。在Failover的实现中,还是有一定的使用限制的。比如11g中SCAN-IP的默认实现其实默认是没有Failover这个选项的。如果两个节点中的一个挂掉了,原来的连接会继续查询会提示会话已经断开,需要重新连接。ClientTAF主要讨论了FailoverMethod和FailoverType的一些简单内容。(1)FailoverMethodFailoverMethod的主要思想是通过换取failover时间,或者换取资源来实现。可以这样理解,假设我们有两个节点,如果一个session连接到节点2,但是节点2突然挂了,为了更快的处理Failover的情况,FailoverMethod有两种:preconnect和basic.preconnect这种预连接方式还是比较占用资源的,在每个节点上都会预占一些额外的资源,切换会相对更顺畅和快速。在基本方法中,当发生Failover时,切换相应的资源。中间会有一些滞后,但是资源消耗相对要小很多。简单来说,basic方法只会在出现故障时才进行判断,而preconnect则是为了未雨绸缪;从实际应用来看,basic方式更为通用,也是默认的failover方式。(2)FailoverTypeFailoverType的实现更丰富、更灵活,也非常强大。此时可以根据用户SQL的执行情况来控制控制粒度,有两种:select和session;让我用一个小例子来说明。例如,我们在节点2上执行了一个大查询,结果节点2突然宕机了。比如正在执行的query,有10000条数据,结果发现刚出故障的时候检测到了8000条数据。那么剩下的2000怎么办呢。第一种方式是使用select;即完成故障转移,继续返回剩余的2000条记录。当然,中间还会有一些上下文切换,对用户是透明的。第二种方式是session;即直接断开连接,要求重新查询。在10g版本中,借助VIP配置的LoadBalance+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))))如果11gSCAN-IP还想进一步扩展Failover,还需要设置failover_mode和对应的type。RACDB=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=rac-scan)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=RACDB)))从这个角度来看,Oracle的解决方案真的美好的。我们来看看MySQL的解决方案。分布式解决方案使MySQL看起来像一把瑞士军刀。可以说MySQL对网络层面没有要求。如果申请主从架构,只需要4个IP(master,slave),VIP,MHA_Manager(考虑是manager节点)),一主两从是5个。此时MySQL原生不支持所谓负载均衡(这里不是读写分离),可以通过前端业务进行分流,比如使用中间件代理,或者不断拆分。达到一定粒度后,通过Architecture设计的方式来满足需求。因为基于逻辑的复制容易扩展,一主多从很普遍,成本也不高。延迟不能说不存在,但是很低,可以满足大部分互联网业务的需求。说到触发MHA切换的条件,从网络层面来看,以下红点是潜在的隐患,有的是网络中断,有的是网络延迟,当出现故障时,能否保证数据或性能稳定性可以根据您自己的需要定制。从这个角度来看,有丢失数据的可能。绝对不是强一致性无损复制。把上图放大,其实会有更多的细节,比如ssh连接检测,数据库心跳检测(insert_ping)。整个方案需要考虑的场景很多。对于网络切换,MHA目前主要做的是保证数据的复制关系。如果想深入使用,还是需要做更多的定制,比如结合Proxy方案,使用ZooKeeper状态检测,使用keepalive或者VIP网络级切换等。两种方案整体来看,RAC是集中共享。除了存储层面的共享,网络层面的组播实际上会增加节点间通信的成本。因此,RAC对网络的需求很大。如果有延误,那是非常危险的,脑裂很尴尬。MySQLMHA解决方案是分布式的。支持大容量环境,节点间通信的成本相对要低很多。但是从数据架构来看,由于采用了复制的数据分布方式,即使存储不是共享存储,存储的成本仍然高于RAC(不是存储的价格,而是存储的数据量).OracleDataGuard和MySQL容灾那我们继续说容灾部分。我将比较Oracle的DG和MySQL的解决方案。在容灾概念中,OracleDBA习惯称其为primary和standby,即Primary和Standby,而MySQL更喜欢称其为master和slave,即Master和Slave。不管怎么称呼,意思都是一样的。首先,在Oracle中,数据是基于物理复制的(这里说的是物理备),所以很容易定位到数据库的状态和角色,而从库在正常情况下是不能读写的。所以Oracle中角色切换的概念很明确,failover和switchover,failover就是failover,switchover就是主备切换。MySQL中failover的概念很好理解,但是相对于switchover来说,会淡化很多。因为Oracle是基于物理复制的,备库一直要么处于恢复状态(recover),要么处于只读非应用状态(read_only)。这个问题直到11g才解决,也就是大名鼎鼎的ADG(readonlywithapply)。在MySQL中,这不是问题。备库可以灵活切换read_only参数。当然,一般不会想到备库会写。阅读肯定不是问题,阅读也可以扩展到读写分离。关于Oracle的standbydatabase的理解,我觉得除了ADG,最大的亮点就是flashbackdatabase。可能很多OracleDBA对闪回数据库敬而远之。技术更新很多,把好的功能搁置一旁有点可惜,比如搭建一个DG,DGBroker分分钟搞定,人工方式不一定高效。闪回的概念在MySQL中也有。目前可以根据binlog提取的数据实现DML闪回,与Oracle中的闪回还有很大的差距。oracle里面有各种各样的闪退,几乎都有。当然,没有那么多常用的和实用的。MySQL的DML还是原生态的。可以根据binlog抽取恢复,也可以借助第三方工具辅助,但是DDL就更难了。目前MariaDB的DDL闪回是一个突破口,以我的理解,应该可以实现部分闪退功能,具体效果待会再测试。那么闪回是一件大宝,到底有多好呢?Oracle的备库方案有快照库,也就是说可以临时写物理备库。好处是主库的分片在备库中是完全一样的。.因此,它在SQL审计方面具有得天独厚的优势。本人在网上多次DDL审计中做过测试和实际应用,效果非常好。另外,11g中的闪回是可以在线开启和关闭的,所以一般来说,我建议在10g中谨慎使用,11g的条件备库还是比较推荐的,只要满足要求即可。当然闪回数据库也不是万能的,有些场景是不支持的,这里就不展开了。对于容灾来说,数据库切换是一个提前规划的事情,那么备库切换的检查是否OK呢?Oracle有DGBroker这样的神器,在新版本中做了很多不错的选项,比如新版本有validate这个选项,可以检查是否满足主备倒换的条件。下面是DGBroker命令中附加的validate命令,效果还是不错的。另外,从高可用的角度来说,如果备库有连接,切换时会话会继续保持,当然也会有短暂的卡顿。这是典型的会话持久性功能。当然,PreservingActiveDataGuardApplicationConnections在MySQL中是不可理解的。切换的影响很小,更不用说会话保留了。因为Oracle基于物理复制,物理一致性使得复制的可扩展性变得困难。当然,并不是说不能实现。例如,级联备用可以级联。12c的改进版本是FarSync,号称零数据丢失,对于跨区域数据中心,延迟将被最小化。从技术架构上看,部署的分布图类似下面的形式。中间有远距离数据传输,可以通过中间节点进行转换。中间节点很特别。它不存储数据,只是维护一个内存结构,用来同步数据。还有延迟。我测试了DG的延迟。在与MySQL基本相似的压力情况下,Oracle基本控制在0.1秒左右,MySQL的复制会有一定的延迟放大。所以总体来说,Oracle的方案是一个非常专业的方案,工具齐全,架构相对复杂,数据同步的一致性强。因此在涉及交易的业务中更受欢迎。下面来看看MySQL的改进方向。单机性能和延迟我们不比较,因为确实有差距,硬拼意义不大。我们从整体架构的角度去考虑,这些都是Oracle难以做到的地方。首先说说主从复制。MySQL是典型的逻辑复制。主库可以承载较大的并发量,但性能瓶颈明显。主库的并发最终落到文件上时还是串行的,不管日志传输过程如何。开销上,最大的瓶颈是SQL_Thread的应用延迟。就像中午大家出去吃饭,前台可以并发点很多菜,但是后台的厨师就像SQL_Thread一样,他一次只能做一个菜。如何让它变得更快?比如你点了5分的盖饭,他可以一次炒,可以大大提高效率,所以前台小姑娘也会建议你点和别人一样的菜,原因是一个字——快。这类似于并行复制的使用。MySQL5.6无法实现细粒度的并行复制,只能在数据库层面实现,但是在MySQL5.7中,可以在表层面实现更细粒度的并行复制,这种提升是显而易见的。因此,延迟的问题就可以解决,后续的扩展也会容易很多。MySQL的扩容甚至可以实现指数级扩容。如果允许一些低延迟,可以逐步分解大量的读请求。因此,一主多从的架构也就不足为奇了。值得一提的是,在MHA的一主多从架构中,如果多个从库出现延迟,MHA会在切换时填充差异日志,这是MHA的一大亮点。MySQL的级联复制更加纯粹。与Oracle相比,最大的优势在于一个数据库可以同时是主库和从库,起到了承前启后的作用。这种扩容方式简直酸酸的,在一些跨数据中心的场景下允许一定延迟的情况下还是有用的。比如你需要读取北美的数据,你可以把北美的数据库推送到香港或者新加坡,再推送到北京。这样很容易扩展。当然,实时交易还存在一些瓶颈和缺陷。展望及后续补充如果抛开具体的数据库不谈,整体来说,当数据量和业务量达到一定程度时,会遇到一系列的问题。这些都是痛点和难点。常见问题如下:单台服务器无法承受现有压力。单个数据库表的容量越来越大。大量的读写需求无法平衡资源。如果不好拆分,或者不好拆分,那么就需要扩展,需要配套的解决方案,比如中间件解决方案,有的解决一些通用的问题,有的专注于某个方面。比如分片需要考虑分片,读写分离分担读写压力,海量前端访问可以通过大量横向扩展分担。从这个角度看,MySQL以架构和规模取胜,可以通过业务拆分和架构拆分实现线性扩展。虽然Oracle的扩展性不是那么好,但是从架构和业务的角度也可以做到。这个后续有机会再详细讲,分布式方面可以写一篇文章。总结简单概括一下,有很多高可用性解决方案可供选择,每个公司都有自己的需求。定制可以定制,开源可以开源。从大道到简单,只要满足需求,系统稳定不被怪,就是最好的方案。
