oceanbase了解

透明可扩展的企业级数据库

透明可扩展

企业级数据库面临的问题

企业级数据库是一个面向单机设计的数据库,没有解决可扩展性的问题。这跟企业数据库的技术有关,也跟企业级数据库的商业模式有关。

如果容量不足怎么办?可以采用垂直扩展的方式。通过不断扩展容量,虽然稳定性也能做得还不错,但是成本的代价会变得非常的高。

云数据库 != 透明可扩展

数据库的模式采用的是存储计算分离的方式,解决了存储可扩展的问题,但是没有解决更关键的问题,那就是事务与 SQL 可扩展的问题。

分库分表 != 透明可扩展

分库分表的方案从理论上讲就永远不可能实现全区索引这个功能。另外整个分库分表方案往往会在上面架一层中间件,通过中间件做简单的 SQL 转发、路由、聚合,以及一些比较基础的数据查询功能。

它不支持很多功能,包括全局快照——跨多台机器的全局快照,包括复杂查询——跨服务器的复杂查询,跨服务器的写入操作,也包括一个很重要的能力——带容错能力的分布式事务。

很多中间件是支持分布式事务的,但是中间件支持的分布式事务是不带容错能力的分布式事务。当服务器出现故障的时候,整个事务会被夯住,需要人肉去做容错。这种方案跟真正的分布式数据库里带容错的分布式事务是两个方案,有本质的差别。

透明可扩展的企业级数据库

透明可扩展的企业级分布式数据库需要具备一些基本的属性:

  1. 它需要像传统企业级数据库一样,无需业务修改,按需扩容
  2. 核心能力可扩展,包括存储,事务和 SQL。其中这里面存储可扩展是最容易实现的,事务可扩展是最难做到的,SQL 可扩展是工作量最大的。
  3. 持续可用,保持稳定:整个系统需要是持续可用的,不管服务器发生了什么故障,都必须做到系统稳定,整个系统对外体现一个持续稳定的输出,保证业务的连续性。
  4. 具备企业级数据库功能
  5. 通过核心业务和 benchmark 证明

透明可扩展的理论基础

事务是一个非常古老的概念,必须遵循 ACID 特性。

两阶段提交协议本身并不复杂。当我们需要把多台机器连起来做协调的时候,所有机器都叫做参与者,然后其中有一台机器会选出来做协调者。当要进行事务提交的时候,协调者先给所有的参与者发送 prepare 消息,如果所有的参与者都 prepare 成功,最终协调者认为整个事务可以提交了,然后再发出 commit 消息,让每一个参与者都提交事务。如果其中某个参与者因为各种情况比如资源不足最后没法提交事务,整个事务提交失败,协调者给参与者发送回滚消息。

这个协议看起来很简单,但没有考虑容错。假设协调者出现了故障,整个数据就会被 hung 住,即使是参与者出现故障,那参与者所在的那台机器也会被 hung 住。在一个高并发的系统里只要有一台机器被 hung 住,就意味着客户端被 hung 住。客户端被 hung 住就意味着整个系统被 hung 住。所以一台机器故障最终会导致整个集群的不可服务。

分布式事务:Paxos + 2PC

  • 中间件 XA:依赖数据库

其中的一种方案就是中间件 XA。中间件 XA 是一种分布式事务的实践方法, XA 的本质是把协调者跟参与者的状态持久化到数据库里,由数据库来支持容错,所以中间件是无状态的。但是我们自己是分布式事务数据库的设计者,不可能再把状态持久化到另外一个分布式数据库里来支持容错。

  • NOSQL 系统:回避一致性与分布式事务

另外一个思路是 NOSQL 系统中的 CAP 理论。CAP 三者不可兼得。在一个需要考虑容错的系统设计里面,P(分区容错)是不可选择的,一定会出现网络分区的情况。C(一致性)跟 A(可用性)二者只能取其一,要么要一致性,要么要可用性。

其实 NOSQL 系统从理论上就已经比较“巧妙”的回避了一致性分布式问题。分布式事务的问题就不处理了,或者根本就不支持分布式事务。

云时代的架构选择:采用 Paxos + 2PC

Paxos + 2PC 的论文。但是这个协议从理论走向工程实践,经过了十多年的时间。
CAP 与 Paxos

CAP 理论告诉我们,要么强一致,要么高可用。Paxos 却能同时实现强一致和高可用,那么 Paxos 协议是不是违背了 CAP 理论呢?我认为其实是没有违背的,本质在于 Paxos 里的高可用跟 CAP 里的可用性是两个不同的概念。

  • Paxos 是从系统整体的角度来看的,哪怕出现单个节点故障的时候,只要多数派能够快速恢复使得整个系统继续服务,它就是高可用的。

  • 但是 CAP 理论是从故障节点的角度来看的,当单个节点出现故障的时候,这个故障的节点能不能在有限的时间被访问到,这是 CAP 理论里可用性的意思。

Raft or Paxos

Paxos 协议有一个很大的设计假设,它要求支持多个投票,也就是数据库里的多条日志之间是可以乱序提交的,可以并行处理的。但是 raft 协议的做了一个约束,数据库的多个投票多条日志一定要按照顺序执行,只能前一个日志被确认了才能确认后一个日志。

这种简化使得 Paxos 协议走进了千家万户。但是有得必有失,他把这个约束变得更简单了以后,导致了两个问题,第一个问题是并发能力变得更差了。以前支持并发的提交,现在只能支持一个结束以后再来下一个,所以它的性能变差了。

第二个是可用性的问题。如果采用 Paxos 协议,当一台机器新上线的时候很快就能提供服务了,因为不需要等前面的数据确认它就能提供服务,但是如果使用的是 raft 协议,需要等前面的所有日志确认以后才能提供服务,所以说 raft 协议存在可用性的风险。在某些场景尤其是异地部署和比较差的网络环境下是有风险的。

自动负载均衡

有了分区表,把整个数据打散成很多数据分片以后,我们接下来要做的一件事就是把这些数据分片均匀的分布到整个后台的分布式集群里,这个过程我们称为自动负载均衡。

负载均衡里有一点想特别强调一下,就是复制的方式。复制的方式有两种:一种方式叫逻辑复制,一种方式叫物理复制。

顾名思义,逻辑复制相当于把数据一行一行读出来再写,这叫逻辑复制。物理复制,就是直接拷贝最终的数据文件或者是数据块。物理复制的性能很好,但是实现难度却很高。按照以往经验来看,物理复制的性能可以做到逻辑复制的 5 到 10 倍。

在大部分的分布式存储系统里面,负载均衡都实现了自动化。但是目前绝大部分的分布式数据库的负载均衡都是人肉负载均衡

分布式数据库里的自动负载均衡实现难度很大。因为分布式数据库里面临的负载均衡本质上是一个多因子负载均衡的问题,它需要考虑两种负载,一种负载叫做计算负载,主要考虑的是 CPU 跟内存。另外一种负载叫存储负载,主要考虑的是磁盘的占用量。

当计算负载比较高的时候,存储负载可能是比较低的。相反,当存储负载比较高的时候,计算负载又是比较低的。而且我们会发现计算存储的资源配比跟业务实际的计算存储负载是不一致的。同时,存储的迁移耗时很长。

分区容错

当我们有了分区表,假设已经把负载自动均衡到所有的机器后,下面我们要考虑的就是如何做容错的问题。容错分为两种情况,一种是分区自身发生的故障如何容错,还有一种情况是外部的用户请求如何动态的处理故障。

主备切换不杀事务

当发生主备切换的时候,需要做到新的事务在新的分区里开启,老的事务还需要动态地由原来的主分区一行一行迁移到新的主分区,整个过程需要做到事务的在线迁移。大家可以想象这是一个分布式场景的并发处理问题,它的难点在于怎么做多机的并发问题以及如何做异常的处理。

分区分裂不杀事务

分区分裂是我们内部的一个操作,这样的一个操作是不能杀事务的。如果杀事务用户就会感知到,感知到后台做了一些操作。而且数据库的事务可能是一个执行非常长的一个事务,有的甚至执行一到两天。我们需要做到新的事务在新的分区里执行,老的事务还能动态的一行一行迁移到新的分区里,整个过程需要做到对用户透明,这是其中最大的难点。

全链路请求容错

全链路的请求容错,难点在于请求涉及的环节特别多。从应用过来一个请求,首先会到一个叫 Proxy 的代理服务器,Proxy 再请求后端的分布式数据库的集群,整个过程是一台机器请求另外一台机器,一台机器再请求另外一台机器,任何一个过程都可能会发生故障。

在发生故障的时候都需要做到读写请求的重试,但是重试其实是一个很危险的操作。AWS 之前曾经因为重试产生了重试风暴导致大面积的故障。重试可能会产生连锁反应。原来用户发了一个请求,最后重试变成了一百个请求,整个系统就崩溃了,而且永远不可恢复,只能把用户的请求停掉,最后才能恢复。

重试也要做的,但是我们追求一点,就是需要做到任务级的重试。一个请求可能涉及的数据量很大,这个过程中会处理很多的数据分片,某一个数据分片出现故障的时候只重试这一个数据分片。整个请求的链路涉及到 Proxy 到数据库,当 Proxy 跟数据库做动态调整或者在线升级的时候,我们需要做到将它上面正在进行的请求动态的迁移到其他还能够工作的机器上。这是这件事情的难点,它需要做动态,但不能杀事务。

异常处理也有一个比较大的难点——是半死不活。当请求一个磁盘,它一会好一会不好,网络时好时坏。如何处理这种半死不活的状况。这个情况在大规模系统里面叫 hung 住。hung 住比失败要可怕得多。

企业级查询优化器

企业级数据库里有一个很重要的功能叫优化器。优化器在企业级数据库里面都是基于代价来实现的。因为优化器带来的问题特别多,我这里面只提两个问题。

第一个是大小账号的问题,很多人在互联网公司都经历过,比如一张表格有很多的用户,有的用户数据量很大,有的数据量很小。假设一个企业级数据库,同样一条 SQL 进来的时候,能够动态的判断请求的用户是哪个,并且可以根据统计信息来选择执行计划。如果请求的是大账号,就选择一个全表扫描的执行计划,如果小账号选择一个索引回表的执行计划来达到最优。

数据库后台调整的时候,特别让人害怕的一点就是数据库后台调整以后执行计划变了,使得原来执行很快的执行计划变得很慢,这个时候该怎么办呢?在企业级数据库里,有执行计划演进这样的一个功能。

当有调整的时候也会生成新的执行计划,但是新的执行计划并不会立刻生效,而是把流量一点一点从老的执行计划切到新的执行计划,等到最终内部验证了整个新的执行计划的性能没有回退以后,我们再用新的执行计划完全替代老的执行计划。这是企业级数据库里面优化器的一些基本的功能。

分布式数据库相比企业级数据库又多了一个问题,主要是并行优化的问题。假设一个单机数据库,以 Oracle 为例,优化器的实现会把整个优化分成两个阶段,第一个阶段叫串行优化,不会考虑一些分布式的问题,也不会考虑网络开销的问题。第二个阶段它会对第一个阶段串行优化结果里部分的算子做局部的并行化。所以大家可以想象,分成了这两个阶段以后,它的搜索空间并不是那么的全面,有一些应该搜索的这样的一些执行计划就被忽略掉了。

但是如果是一个分布式数据库,我们一开始就应该考虑并行优化器,一开始就应该考虑所有的单机的开销以及分布式的开销,直接搜索全部的空间,然后生成一个涉及全部开销的并行执行计划,最终才可能达到一个最优。

OceanBase 的业务实践

OceanBase 是一个工业级的 share-nothing 透明可扩展的分布式架构,可以无限扩展。

OceanBase 可以给用户提供全局一致的数据库视图,并且能够支持跨服务器任意的复杂查询。

ceanBase 对 MySQL 全兼容,还支持部分 Oracle 版本的兼容。

  • 交易支付透明拆分

原来交易支付是按照 UserID 拆分成 N 份的,后来发现容量不够,要拆分成 M*N 份。以前做拆分都是中间件跟业务一起来改造,每一次拆分都需要技术部门几百人的开发花费一年的时候来完成改造。导致一方面耗时耗力,另外一方面技术风险非常高。

OceanBase 的解决方案:

OceanBase 解决的方案就是使用 OceanBase 分区表实现透明拆分。通过 OceanBase 分区表在数据库底层实现拆分,业务完全没有感知,也基本上不需要任何的改造。

  • 会员系统全局索引

公司的核心系统,它存储了用户的重要信息。一个用户的信息是多维度的,除了根据 userID 还可能根据用户名,邮箱手机号码等进行查询。

本质上就是全局索引的需求,但是我们都知道分库分表的方案是不支持全局索引的,带来的问题就是单机数据库只能垂直扩展,没有办法做到水平扩展。

OceanBase 的解决方案:

OceanBase 的解决方案就是 OceanBase 分区表 + 强一致的全局索引,通过这样的方案在数据库底层实现可扩展,而且对用户透明。

  • 结算系统小机下移

外部业务相比蚂蚁的业务对透明可扩展的要求更高,在蚂蚁内部我们有非常强大的 DBA ,有很强大的开发能力可以改造,但是在外部客户基本上是不能改造的。某金融机构有大量批处理场景,有多张大表关联的复杂计算,并且涉及到大量的数据更新。批处理意味着每一次处理的数据量很大,而且有很多张大表要做关联,经常要做一些比较复杂的查询,并且更新量也比较大。业务的痛点在于传统的集中式数据库,单点出现了瓶颈,并且小型机的成本很高。如果扩容只能扩容成大型机,成本就变得不可接受。

OceanBase 的解决方案:

OceanBase 的解决方案就是透明可扩展的 OceanBase,通过 OceanBase 的 HTAP 场景的并行处理能力,使得处理时间相比现有的时间缩短了一半,并且 TCO 得到了大幅度的降低。通过 OceanBase 迁移服务(又名 OMS)进行平滑迁移实现了可灰度可回滚。过去金融行业进行业务迁移都是停机迁移,OceanBase 做到了在线迁移并且可灰度可回滚在金融行业是一件非常了不起的事情。

参考

https://zhuanlan.zhihu.com/p/70676722


   转载规则


《oceanbase了解》 wangyixin-tom 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
2PC与3PC 2PC与3PC
2PC二阶段提交就是将事务的提交过程分成了两个阶段来进行处理。 阶段一 事务询问协调者向所有的参与者询问,是否准备好了执行事务,并开始等待各参与者的响应。 执行事务各参与者节点执行事务操作,并将 Undo 和 Redo 信息记入事务日志中
2021-06-23
下一篇 
CAP和BASE理论 CAP和BASE理论
CAP定理一个分布式系统不可能同时满足一致性(C:Consistency),可用性(A: Availability)和分区容错性(P:Partition tolerance)这三个基本需求,最多只能同时满足其中的2个。 一致性,指数据在多个
2021-06-23
  目录