本文为 OceanBase 高级技术专家刘浩在第一届 OceanBase 开发者大会带来的分享。欢送拜访 OceanBase 官网获取更多信息:https://www.oceanbase.com/
3 月 25 日,第一届 OceanBase 开发者大会在北京举办,OceanBase 高级技术专家刘浩为大家带来了《RTO < 8s:OceanBase 极致高可用的探索之旅》的分享,为大家介绍了 OceanBase 在 RTO 畛域的摸索。
以下是演讲实录:
大家好,我明天分享的主题是《RTO<8s,OceanBase 极致高可用的探索之旅》,RTO(Recovery Time Objective)指的是“故障产生后业务的复原工夫”,这里的“复原工夫(30s→8s)”是 OceanBase 从 4.0 到 4.1 版本始终在致力的事件,它是很准确的数字, 明天我将分享咱们在客户的利用场景下看到了什么问题才决定将这个值准确到“8”,为什么之前 30 秒还不够?之后又做了哪些优化?解决了哪些挑战等一系列问题。
继续可用的价值是什么?
首先看一下继续可用的价值,这个置信用数据库的人都比拟有体感。
第一,要害的 IT 零碎宕机会造成微小的经济损失。 在 OceanBase 商业化过程中,有的客户如果宕机一个小时,损失的金额大略在几十万到百万美金,这是一个十分惊人的数字。
第二,在经济损失以外,还有很多隐性品牌方面的损失。 比方每一个互联网服务都会大量应用数据库,如果数据库呈现故障,故障工夫内就无奈为一部分用户提供服务,这会大大降低用户对该服务的信任度。
第三,对在 IT 零碎撑持下的社会运行的影响。 每一次故障都可能带来十分大的社会影响。举个 3 月份的例子,我本人早上会坐十号线,在刚刚过来的半个月外面,我经验了两次十号线的故障,而且每次故障继续的工夫长达一个小时,影响十分大。
▋ RPO
在谈到“继续可用”的时候总绕不开两个概念,RPO 和 RTO。
在故障产生的时候个别会有两个数字上的指标,第一个就是 RPO(Recovery Point Objective)。上图两头那条线是代表故障产生的工夫点,在故障产生工夫点之前会有一个短的线段,代表你应用这样的数据库业务会带来多少数据损失。
有两种次要的可能造成 RPO≠0 的起因:
第一,在应用相似于 MySQL 的数据库的时候,很多时候为了谋求性能,事务提交时不强制刷盘。 这样如果恰好产生宕机,就可能失落最初写入的一部分数据。
第二,当初数据库系统须要包容更多的故障,比方机房的故障、城市的故障。 在之前的数据库里有典型的主备架构,主备架构更罕用的是异步的形式。如果主库宕机时,备库无奈接管最新的数据,也会带来显著的 RPO 损失, 有的时候会在秒级,有的时候会更长,而每次 RPO 的损失都会要求业务对数据做弥补,这对业务会带来十分大的影响。
▋ RTO
另一方面,故障产生之后怎么去掂量业务复原工夫,这个就是明天会重点讲的 RTO 指标。咱们在之前的数据库里可能须要到小时级,无论是 NewSQL 还是 OceanBase,从 30 秒到 8 秒的工夫缩短,都给客户带来了更好的业务体验。
在谈到这几个值的时候咱们绕不开基础设施的变动。 OceanBase 在 1.0 研发之初,很多要害业务是跑在大机上的,在过来十年的倒退中,有非常明显的基础设施的变动和趋势:从大机到了一般的 PC 服务器以及明确的上云趋势,在整个 IT 资产老本降落的同时,也带来了服务可靠性的升高,这就要求咱们在数据库软件层面更好地解决问题,因为无论是硬件还是软件,故障随时都可能产生。
▋ 数据库容灾技术的演进
当初,OceanBase 的很多业务都要求 7×24 小时服务,随着古代社会的变迁,用户对咱们有更高的要求,从 99.99% 到 99.999%,全年故障工夫只能有几分钟,否则作为用户,可能就要通过网络进行投诉了。
这些事实诉求带来了数据库容灾根底的变动,从基于主备的主机架构(Oracle)到基于 Paxos 一致性协定的架构(OceanBase)变动。
▋ 客户对 RTO 的多样诉求
接下来我分享一下咱们看到的客户需要,这里有几个故事。
第一个故事是支付宝的故事。 回头看 OceanBase 我的项目立项的初心,是咱们在解决支付宝大体量业务的问题时,发现如果业务停机,会带来显著的客户负反馈,所以 OceanBase 十分大的初心之一就是要解决像支付宝这样外围金融业务的可用性难题,咱们要做到:遇到任何故障都不丢数据且用更短的工夫复原业务。
第二个故事是 OceanBase 商业化过程中,咱们在服务大型金融客户的故事。 咱们发现他之前的外围业务零碎是跑在大机和 DB2 下面的,客户有很明确的降本诉求,心愿迎接更好的分布式架构体系,以满足将来业务倒退。所以他须要在 PC 服务器下来跑 OceanBase 分布式数据库,然而他的业务零碎又很简单,像全局索引、分布式事务,跑在大机上没有问题,因为大机的可靠性很好,然而换到 PC 服务器的时候,可靠性会有降落。
但无论是面对他的客户,还是从整个国家的监管层面,架构变动带来可用性的降落都是没有方法承受的,所以咱们须要通过 OceanBase 的技术迭代去解决架构变动带来的可靠性降落问题。
第三个故事是咱们在服务云上客户时的案例。 某私有云客户最开始的时候只须要简简单单地把本人的业务跑在云上,但他自身的业务是做跨境电商,此时他须要把本人的业务跑在更多的云下面,比方 AWS、微软,但咱们发现很多云厂商的存储能力并没有这样的好,这就要求咱们在这样的介质下,能够给客户提供同样的服务连续性保障,即客户对 OceanBase 可靠性的诉求。
在这样业务需要的根底上,OceanBase 之前提出的 RPO=30 秒的指标是足够的,但当咱们须要在 4.0 版本上优化到 8 秒,就不仅仅是数字的变动,背地还有很多其余的货色。
从 30s 到 8s,一直谋求极致的 OceanBase
第一,咱们看到的 RTO<8s,除数字以外还须要有更多的场景反对。 不仅仅是常见的“过程挂掉”、“物理机或者 ECS 的重启”,还波及到更多如网络分区,或存储介质故障等场景,在云上也好,在本人的 PC 服务器也好,这些都是客户关怀的,咱们须要在这些不同的场景下都可能做到小于 8 秒的指标。
第二,咱们看到业务同学更多会从业务视角关注利用复原的工夫。 数据库的复原其实曾经很简单了,然而如果咱们思考到后面还有更多的组件如“应用服务器”、“负载平衡”,还有 OBProxy 等,咱们就要更好地满足业务视角关注的 RTO 工夫,此时,须要从业务复原和数据库复原两个视角去掂量整个指标的变动。
第三,很要害的方面,咱们要做到“零调参”。 无论你应用的是 OceanBase 的商业版还是社区版,都不须要调任何的参数就可能做到 RTO<8s,咱们不是为了做 POC 测试,而是立足于面对客户理论的生产场景,去解决用户应用数据库中遇到的挑战和问题。
第四,OceanBase 有一个很重要的概念即所有的节点对等。 外部每一个数据库的服务器都提供很多服务,不仅包含事务存储,还包含集群管控节点(RootService),所以咱们要做到其中任何一个节点的故障都可能提供这样的能力。
第五,咱们在现有外部的 PC 服务器部署根底之上,心愿在多云和跨云部署场景下也提供这样的能力。 这里有一个演示的例子(可移步官网看视频回放),是基于 OceanBase 社区版(与商业版齐全一样)在咱们内部测试机上跑的简略的 Sysbench 业务。右边曾经在把压力起起来,在左边会把提供读写服务的过程 kill 掉,由此大家会对整个 RTO 有个直观的印象。前排同学能够看到从第 30 秒开始降落,到第 34 秒时,整个服务能力就曾经完全恢复了。
在小于 8s 的工夫内产生了什么?
如下图拜访链路图所示,业务从应用服务器开始,通过负载平衡,再通过 OBProxy(保障业务申请找到正确的后端服务器节点),最初拜访到后端服务器节点。
接下来给大家简略介绍一下小于 8 秒的工夫内到底产生了什么?
在产生理论的故障时,外部会花短短几秒工夫做故障的检测,检测之后整个 OceanBase 外部会进行齐全主动的复原流程,在复原流程做完之后新的主节点就会对外提供服务,提供服务之后会波及到路由的刷新,他会有个路由的汇报和刷新机制。在几秒钟的申请之后,业务申请即可复原。
在这个全自动流程里,也会有一些挑战。第一,如何疾速精确地断定故障;第二,产生故障后,数据库如何疾速复原;第三,数据库复原后,如何帮忙业务疾速复原,接下来将围绕这三个板块做具体阐明。
▋ 如何疾速精确的断定故障
首先,咱们要大幅缩小故障复原单元。 这里的故障复原单元对应的是每一个 Paxos Group,OceanBase 1.0 到 3.x 版本里,Paxos Group 是 OceanBase 的一个业务分区,如果是在业务的表或者分区特地多的状况下,它的故障复原单元数量是十分惊人的,即在 50 万的分区下会有 50 万的故障复原单元,也就是说咱们须要在 30s 内复原 50 万个故障复原单元。
在这种场景下,咱们很难做到进一步优化。 但在 4.0 版本中,咱们做了十分大的架构调整,就是把故障复原单元变成单机的日志流,而不再与业务 schema 相干,也不与业务数据量相干。 比方像“1:1:1”这样的最典型的三正本集群,他实际上只有一个或者三个故障单元,这个量级的缩小会帮忙数据库在复原的时候做得更加稳固,这样能力保障故障复原工夫的进一步降落。
其次,咱们在新的架构根底上,发现在之前的设计里还有很多问题要解决。
一方面,在 4.0 版本中,咱们把最底层的最外围的局部之一即整个的选举和一致性协定做了从新设计和实现。在谈到选举的时候有一个十分重要的概念:OceanBase 要保障稳固的 RTO,所以选举流程要求基于稳固的算法去实现,无论在何种状况下,它都必须在某个特定的工夫内选出,而不是基于随机的算法。
在 4.0 版本中,OceanBase 也连续了这样的思路,然而也做了全新的设计,并且达到了两个特地好的后果—— 就是咱们在 4.0 版本的选举外面,彻底去掉了对节点之间 NTP 依赖,不再须要节点之间时钟严格同步;在设计上,也不再依赖于节点之间的相对工夫去做选举,而是变成齐全基于音讯驱动的绝对工夫去做选举。另一个比拟大的变动是咱们把整个选举 Lease 的工夫缩短到了 4 秒以内。
另一方面,咱们把底层的一致性协定也齐全从新做了设计。 OceanBase 的开源版里,有个很奇怪的目录叫 PALF(Paxos-backed Append-only Log File System),这是基于 Paxos 一致性协定全新进行设计的,将最底层的货色做了全新设计实现,并做了大量的优化。
咱们解决的是两个问题:一是咱们在缩小故障复原单元之后面临了一个挑战,即大家可能会问“一个 Paxos Group 能不能撑持 OceanBase 那么好的性能和 scale-up 的能力”,其余的数据库常常会说:“我的并行能力是基于多个 Paxos 组、多个 Raft 组去实现的”,他们须要把本人多正本之间同构的单元去做拆分,但这个形式和咱们做故障复原、分布式事务的逻辑是不相吻合的。所以 OceanBase 的所有性能,包含单机都跑在一个 Paxos Group 里。
咱们能够很自信地通知大家:咱们用一个 Paxos Group 能够跑到十分好的性能,并且能够超过 MySQL,咱们也对这套协定做了测试,咱们在本人的测试场景下,这套协定做到了靠近 200 万的 TPS,性能十分好。
第三方面,咱们从新基于 TCP 和 RPC 框架,做了故障检测机制的设计。 大家能够了解为:咱们须要在 TCP 层面做故障的检测,某端网络挂掉咱们要及时的发现,所以在 3.x 里,咱们利用了 TCP Keepalive 去做检测,这里有些场景不好解决——比如说因为某种原因过程 core 了,此时 TCP 是联通的,但在 RPC 层面看,却是发给这个节点的所有申请都 hang 住了。这种状况对 RTO 十分有挑战,咱们基于 TCP Keepalive 的机制,发现无奈解决这样的场景问题,所以咱们在更下层的 RPC 框架外部又从新设计了一套故障检测的机制,发现和帮忙解决这样场景的 RTO 复原。
▋ 产生故障之后,数据库如何疾速复原?
对于产生故障之后数据库如何疾速复原的问题,因为咱们在“1:1:1”的环境里承当主节点的集群和承当备节点的集群,是一个对等的构造。其中主节点的集群是并发写入的,而其余的备节点肯定要时刻做好筹备,在主节点故障之后可能立刻承当服务。 这外面波及到一个要害的外围:整个 Follower 节点要实时并行地去回放主节点写入的内容,即“主节点写入的有多快备节点回放就有多快”。
另外,咱们对立设计了故障检测框架和有主改选。 这里解决的是咱们在整个的故障检测里节点不可服务的问题,还有一些磁盘 hang 的场景,上面对端的整个网络都是通着的,此时你通过选举是发现不了问题的,那么在这种状况下咱们须要留足够的工夫去帮忙故障检测,发现磁盘内的故障。比方我须要 5 秒的工夫能力发现故障,那么 5 秒过来之后,留给复原的工夫其实就很少了,咱们没有机会去给 Lease 让他再做超时,如果这俩叠加 RTO 会翻倍。
因而,在这个过程里咱们从新做了设计:在发现整个磁盘层面呈现故障之后,不会再走无主选举,而是与选举协定做了更有机的联合,这种状况下会间接走有主的改选,能够在百毫秒的级别就把主的服务切换到一个新的 leader 上,这样能够保障更多的场景可能达到 RTO<8 秒的体验。
另外,咱们要基于 RPC 去做路由的刷新。 在分布式数据库外面有一个重要的概念:如果想要晓得我这个服务用户数据的节点地位在哪里,那么每次呈现故障的时候都是在变更数据库的地位元信息。在典型的数据库场景里,解决的形式是我的核心节点,可能是 OceanBase 外部的 Root Service 去记录节点信息,当这个节点呈现故障后,它就须要把本人的地位信息汇报给新的核心节点,集群里其余所有节点再去查问这张表拿到这个信息。
实际上,这个过程还是蛮麻烦的,因为波及到故障之后外部表的汇报两头要执行 SQL,可能还会引入一些对中控节点的依赖,此外,前面其余节点去查问地位相干信息的时候也须要走 SQL,这两头的耗时蛮长。OceanBase 外部做了一套新的机制——即齐全基于音讯的去查问。在故障之后新的主节点地位的信息,即路由信息查问的去中心化。
▋ 数据库复原后,如何帮忙业务疾速复原
当数据恢复之后怎么疾速帮忙业务复原?咱们回到后面 OceanBase 的拜访链路图,其中有个节点叫 OBProxy,咱们在 OBProxy 上也做了很多新的设计。
首先,咱们把之前 OBProxy 的探活策略进行了从新革新,咱们称之为“基于建连的探活策略”。 之前的探活策略是走整个 RPC 的框架,波及到整个队列的解决机制,很有可能在队列申请积压或者整个节点 load 升高的时候呈现误判,这种误判可能会导致 Proxy 误判把一个失常服务的节点杀掉了或把失常服务的节点标记在黑名单。因而,咱们从新设计了机制,去基于建连去做探活,防止申请排队的影响,从而大幅度缩小误判的概率。
另一方面,Proxy 也对故障节点做了实时的拉黑和洗白,在中间件层面,能够秒级判断故障的节点,呈现问题能够秒级把故障的节点从新加回到集群外面去也会比拟好。
以上就是我的全副分享,谢谢大家。
欢送拜访 OceanBase 官网获取更多信息:https://www.oceanbase.com/