本文内容是直播的文字稿,直播视频回放地址https://tech.antfin.com/community/live/773
OceanBase的高可用可以做到自动故障切换和不丢一点数据,即使是异地多机房部署也是如此。这是OceanBase的特性之一。OceanBase的高可用机制是数据库内核能力不可分割的一部分,且是常态运行不存在需要的时候才发现失效了。
高可用方案要点
通常对高可用的要求就是数据库如果出问题了要能够自动切换,并且切换后不丢数据。
能自动切换,服务恢复时间才有可能最短,衡量指标就是RTO。切换后服务恢复时,数据丢失多少,衡量指标就是RPO。分析一个高可用方案就从这两点入手。
数据库不丢数据的关键——事务日志
数据库事务要满足ACID特性,其中D就是持久化,其关键点就是事务日志的设计。事务日志必须先于数据修改前生成并落盘,即常说的Write-Ahead Logging(WAL)。数据修改通常不会立即落盘。事务日志除了能用于本机数据库宕机恢复外,还可以用于构建冗余副本(即备库)并保持主备同步。
然而不同数据库在实现上面方案的细节上又不完全相同,导致实际效果并不完全一样,需要懂这个原理才能区分。比如说MySQL自身有两套事务日志,即InnoDB的Redo日志和Server的Binlog日志。前者格式是记录数据块的变化,后者格式是记录修改数据的SQL。前者记录未提交事务的日志(因为InnoDB有UNDO),而后者只记录已提交的事务日志。所以MySQL实例宕机恢复时都有可能没办法保证两套事务日志完全一致,更不用说依赖Binlog做主从同步。如果MySQL是依赖Binlog做主从同步并且Binlog有可能不立即落盘,那么这个同步方案就不能绝对保证不丢数据。
ORACLE的主备同步是传输事务日志(记录物理块的变化),并且REDO都是及时落盘。所以ORACLE的宕机恢复,主备切换只要顺利的话都是可以不丢数据。不过如果REDO日志有缺失的话就不能保证了。
所以需要一种机制保证事务日志的可靠性。仅仅在本机落盘成功并不算可靠,因为可能会因为硬件问题导致无法获取盘上的事务日志。最可靠的方式是本机事务在提交的时候把事务日志在备库主机上也落盘成功,这种方案叫强同步。ORACLE的最大保护模式的备库就是强同步。它有个弊端就是备库必须可用,否则主库也会拒绝提供服务。所以ORACLE会建议至少配置两个最大保护模式的备库。这样只要有一个备库接收到主库的事务日志并落盘成功主库的事务即可返回。MySQL仿照ORACLE提供了一个半同步的技术,但是它在备库都不可用的时候会降级为异步同步而不是像ORACLE那样让主库拒绝服务。ORACLE认为在最大保护模式下数据一致性最重要,宁可不要可用性。而MySQL则把可用性放在数据一致性前面。所以业务核心重要数据通常放在ORACLE比MySQL上更可靠。即使ORACLE也提供最大可用和最大性能同步模式,也不会改变这点。
OceanBase的事务也遵循日志先行原理,事务日志简称CLog。OceanBase没有UNDO设计,CLog落盘只包含要提交事务的日志,在事务提交环节CLog先落盘,OceanBase的数据修改不落盘(内存富余的情况下会在很长一段时间内都不会落盘)。OceanBase的数据冗余至少是三副本,角色上划分为1个主副本2个备副本。事务提交时,主副本的CLog除了自己落盘外还会同时发往其他两个备副本。跟ORACLE的最大保护机制不一样的时候,OceanBase认为三个副本只要有一半以上成员将CLog落盘成功时这个事务就是可以提交的。所以有个极端案例就是主副本事务在提交时落盘失败,两个备副本却落盘成功。此后主备切换时这个事务会被恢复出来并提交。这个情形在MySQL的主从同步上也可能存在,MySQL很大概率会因为这个出现主从不一致,修复过程也比较麻烦。这个场景在OceanBase下首先会发生主备切换,老的主副本后来是备副本,在硬件问题解决后会自动从新的备副本或者主副本那里同步缺失的日志。最终第三个成员也要把事务日志落盘。
自动切换方案分析
高可用通常都要求自动切换,否则对运维没有太大的价值。传统主备两副本架构下,当主备之间的网络中断时对于是否切换可能会存在误判,导致备库也可能被激活为主库,出现双主和数据不一致。所以传统的双机房容灾方案里负责做高可用切换的产品一定会在第三机房有个监测点,负责检测两机房可用性,以准确判断是哪个机房不可用。
即使是用了一主多备的同步方案,在老主故障时选择新主时,依然要借助外部工具产品来判断和实施切换。这个高可用产品自身的可用性就会显得至关重要。
OceanBase的三副本在主副本故障时会自动从剩下2个备副本里选择出一个新主,并保证这个新主一定是有全部最新的事务日志。在没有故障的时候,OceanBase使用Paxos协议同步主副本的事务日志到备副本时就时刻在保证每笔事务的日志都在三副本的多数成员里有落盘。所以当切换(选主)时,它一定能选出新的主且还不丢事务日志。实际实现时,还会有些策略减少这个选举投票的时间以提高选举效率。不过OceanBase的三副本如果多数成员都不可用,则无法选出新主,也不能恢复服务。
OceanBase的切换(选主)跟传统数据库不同,是以分区为粒度的。每个节点上可能有上千上万个分区,只有其中角色是主副本的分区在该节点出现故障时才需要重新选举。并且是并行选举(当然并行度相对于要选举的分区数来说还是太小,所以总体上也有个串行的特征)。所以,换个角度来说OceanBase里并没有主库或者备库的说法。每个节点上可能既有部分数据的主副本,也有其他数据的备副本。默认只有主副本提供读写服务。
还有个特别的是OceanBase的选举机制是一直都在运行的。每个新主只能维持一个租约时间默认是10s。租约快到期前要继续选举。只不过在没有故障的时候重新选举(有主选举),会优先考虑老主当选。所以应用通常感知不到这个。
客户端路由切换
平常谈论高可用方案时重点都是数据库的主备切换,很少提及客户端需要做什么。站业务角度应用最好是什么都不要做。这个要求是合理的。如果这个能实现那必然是其他环节有做过。比如说数据库主备切换了,IP可能变了,应用怎么连接到新主上。
传统的解决方案有VIP技术、DNS技术或者借助负载均衡设备(F5或LVS)做转发。现在常用的方案都是在中间件环节对应用到数据库的连接做一次转发。类似代理一样,实现的好的话应用只需要跟代理建立连接,后端数据库主备发生切换时,代理会自动维护到新主库的连接。这样对业务而言可以做到会话保持(连接不断)。不过会话的事务状态不一定能保持。如果事务未提交的时候发生主备切换,该事务通常还是会失败回滚掉。需要应用有重试逻辑。
OceanBase里的OBProxy是分区的反向代理。应用只需要连接OBProxy,OBProxy会根据SQL特点将请求转发到相应的节点。OBProxy会将访问过的分区的位置信息缓存起来。如果后端分区发生主备切换,OBProxy会在第一次转发时获取到OBServer的反馈(如不命中)然后重新拉取分区位置信息并更新自己的缓存信息。
除了OBProxy可以路由外,OBServer节点也是可以路由SQL请求的。这种情况不会少见。因为OBProxy在转发SQL的时候,会考虑将一个事务里相关SQL都转发到同一个节点上。这不可避免的导致有些SQL可能就被发往非Leader副本所在节点,那么就需要被二次转发一下。这也是远程SQL和分布式SQL执行计划产生的原因。详细情况可以查看《从ORACLE/MySQL到OceanBase:数据访问代理》。
OceanBase的高可用方案案例分析
OceanBase宕机切换分析
下面就以一个具体的OceanBase节点宕机事件为例详细分析来加深大家对OceanBase高可用的理解。
接着上图。假设OBServer01 节点发生宕机。此时只有t1(p0)的访问会受影响,t3(p1)、t4(p1)都是备副本,不会有访问。
OceanBase会在t1(p0)租约到期(10s)前发起新的选举,老主连任失败表示不可用,那就走无主选举流程。当t1(p0)在OBServer02上的副本变为主副本后,OBProxy在访问这个分区的时候也能感知到这一变化自动维护一个到新节点的连接。对于业务而言,应用连接不会中断。不过前面说了,此前业务事务如果没有提交会出现报错回滚。
此后对于这些分区(t1(p0),t3(p1),t4(p1) 就只有两个副本在运行了。这个是一个危险的状态,OceanBase不会容忍这个状态长期存在。它会等待节点OBServer01恢复,如果超过一段时间(默认是2小时)还没还有恢复,OceanBase会将该节点状态下线,并自动找到同一个Zone的其他节点OBServer04,在上面补齐这三个分区的副本数。
OceanBase只读副本
在传统数据库里有个读写分离的方案,其中会有个只读备库。在主库故障期间,只读备库还能提供纯读服务,以将业务故障影响降低到最小。在OceanBase里,在SQL上使用Hint也可以访问备副本。不过更推荐的方案是在三副本之外增加一个只读副本。只读副本会在一个单独的Zone里(只读Zone)。
只读副本的特点是不能写,只提供弱一致性读(可以在应用会话级别设置,数据可能有延时)。并且只读副本不参与CLog可靠性投票。所以只读副本也可以部署在异地机房不影响业务读写性能。OceanBase只读副本还有个特殊的能力就是假如主副本和备副本都不可用的情况下,只读副本还可以单独提供纯读服务,以将业务故障的影响降到最低。
OceanBase在线不停服机房异地搬迁
OceanBase的高可用特性还可以用于机房在线搬迁。在线搬迁指业务对数据库访问不会出现中断,也不需要申请停机维护时间。整个搬迁过程由OceanBase自己保障数据强一致,OceanBase的高可用能力也不会受损。所以不用担心数据库机房搬迁会有 不可用 或者丢数据的风险。
OceanBase在线搬迁技术的奥秘是利用了OceanBase可以在线增加只读副本,以及只读副本和备副本可以在线进行角色切换。整个搬迁过程会先从三副本扩容到六副本,然后逐个转换备副本和只读副本的角色,当备副本都转到异地的时候,业务的写性能会下降,所以这个环节会放在业务低峰期做但业务不需要停。这个时间点也不会持续很久,迅速的就可以进入下一个阶段。最后OceanBase集群再从六副本缩容到三副本。
OceanBase的容灾/多活方案
OceanBase的特性决定了它非常适合做机房异地容灾和多活方案。不同客户实际机房特点、业务要求可能不完全一样,OceanBase都可以提供针对性的解决方案。由于OceanBase机房容灾方案相关的文章已经很多。这里就简单提一下。
在OceanBase的资源管理了,会有Zone概念。这个是容灾单位的一个逻辑单位。它可以是一个数据中心,或者是一个机房包间,或者是一个机柜等。具体是什么取决于客户实际机房情况和部署设计。
OceanBase的Region是城市。当同城有2个机房的时候,其中一个主副本不可用时,同一个Region的另外一个Zone里的备副本会优先当选为新主。这是一个本地化策略。
- 同城/两地三中心三副本
如果不能接受单副本故障时性能下降则升级到下面五副本方案。
- 两地三中心五副本
如果不能接受单机房故障时性能下降则升级到下面五副本方案。或者可以降级到三副本。
- 三地三中心五副本
OceanBase高可用测试建议
- 数据库部署建议
OceanBase集群最少三副本,1-1-1架构。建议用2-2-2架构,测试更全面一些。
只读副本的功能可选。OBProxy可以安装在OBServer节点上或者应用服务器上。
- 应用建议
如果有现成的应用,应用需要捕获数据库异常,需要自动重试逻辑。
如果没有应用,可以用sysbench模拟。sysbench有个问题如果数据库报错(如主键冲突)就会退出。所以需要忽略一些数据库错误号。如:
模拟数据库宕机可以直接kill -9杀掉observer进程,拔机器网线或者断掉机器电源。
- 监控建议
OceanBase有自己的运维平台(OCP),它需要额外三台机器资源部署(因为自身还有个元数据库OB)。
如果没有OCP的话,可以使用OceanBase自身的脚本dooba。通常在/home/admin/oceanbase/bin/下。它可以观察各个节点的请求信息。如果有请求表示上面有主副本被访问。
下图就是运行sysbench读写测试时,三个OBServer节点都有读写请求。
杀掉 节点78的observer进程后,可以看到读写压力都转移到其他两个节点上。
总结
OceanBase的多副本(奇数)设计,以及使用Paxos协议同步事务日志,是OceanBase高可用能做到自动切换(RTO约20s)和不丢数据(RPO=0)的关键。OceanBase在这个设计上还衍生出很多特性:如负载均衡和异地多活等。
我计划的有关OceanBase实践入门的三次直播就全部结束。大家也可以到恩墨的墨天轮平台查看前期直播回放:https://cs.enmotech.com/course/17
相关PPT下载地址:
- OB直播间01_手把手教你搭建高可用的OceanBase数据库集群
https://gw.alipayobjects.com/os/basement_prod/9dc401e4-eed9-4800-8916-4f1b1e7166f9.pptx
- OB直播间02_OceanBase负载均衡和弹性伸缩实践原理
https://gw.alipayobjects.com/os/basement_prod/722a25b4-4702-40cc-b4dc-ff864261bb77.pptx
- OB直播间03_OceanBase高可用原理和演示
https://gw.alipayobjects.com/os/basement_prod/ed53e8dc-1d16-4a83-9b1e-1931361b48cc.pptx
- 从ORACLE_MySQL到OceanBase入门
https://gw.alipayobjects.com/os/basement_prod/3ea2b4a3-1ca5-46ca-bf94-d99b42be361b.pptx
推荐阅读
- OceanBase数据库实践入门——手动搭建OceanBase集群
- 揭秘OceanBase的弹性伸缩和负载均衡原理
- 如何基于OceanBase构建应用和数据库的异地多活
- 从ORACLE/MySQL到OceanBase:数据访问代理
- OceanBase资料大汇总(20190720)
更多分享敬请关注公众号:obpilot,对OB有兴趣还可以发送消息“加好友”进一步沟通。