• 支撑支付宝双十一4200万次/秒的数据库架构解析
  • 发布于 2个月前
  • 178 热度
    0 评论
一、发展历程
OceanBase数据库是阿里巴巴和蚂蚁金服完全自主研发的金融级分布式关系数据库系统,和基于开源数据库产品进行改造的解决方案不同的是:OceanBase内核100多万行代码都是我们的同学一行行写出来的,所以我们对其有完全的掌控力,这一点对OceanBase的持续发展以及获得更广泛的应用有着十分重要的意义。

从2010年立项开始算起的八年时间里,OceanBase版本号也从0.1版本升到即将推出的2.0版本。从最初的Key-Value存储系统发展到现在功能齐备的关系数据库系统。整个过程中,我们始终不变的初心就是服务业务,解决业务实际问题,不断增强产品能力,然后更好地服务业务。

遵循“解决问题→发展产品→解决更大的问题→锻炼出更好的产品”这个循环:
OceanBase从解决收藏夹的海量数据存储问题入手,有了一个小团队并活了下来;
为了解决高可用的问题,采用三集群部署方式;
为了降低业务迁移成本及支持分析型应用,增加了SQL功能;
到目前的全对等架构、三地五中心城市级自动容灾(可参考:城市级故障自动无损容灾的“新常态”方案)、支持主流关系数据库功能使得业务零修改迁移,最终使得支付宝核心业务能够运行在OceanBase上。

OceanBase从立项开始,目标之一就是在不可靠的硬件上提供可靠的关系数据库服务。我们诞生于高速发展的互联网行业,高端存储和专用服务器的订货周期太长,供应也很受限。能方便获取的硬件只有普通PC服务器,所以OceanBase只能依靠分布式架构,用软件的手段,在不可靠的硬件环境中实现金融级可靠性及数据一致性。

经过八年多的实践,从淘宝的收藏夹业务走到今天支撑支付宝所有核心业务,并且在每年的“双十一”持续地创造交易数据库峰值处理能力的世界纪录。在去年“双十一”大促中支撑了支付宝全部的核心业务(含交易、支付、会员、账务),峰值处理请求数达到4200万次每秒。

二、关键特性的逐步实现

从特性上说,OceanBase具备线性扩展、高可用、高性能、低成本,以及和主流关系数据库产品高度兼容等特点。

1集群架构特点

从1.0版本开始,OceanBase架构就进化成为全对等节点,无共享存储方式。这个架构特点消除了单点,每个节点都具有完备处理能力,能够管理本节点上的数据。在节点角色上,有几个节点(root service)负责管理集群拓扑结构等全局信息,相对特殊一点,但每个节点都具备承担这个角色的能力,如果当前承担该角色的节点发生故障,集群会自动选举出新的节点承担这个角色。

此外,为了高可用,集群节点分布在多个不同的可用区,可以是同城不同机房,或者异地多个机房;一份数据在多个可用区里有副本,副本个数通常是奇数个。在蚂蚁金服的实践中,通常是3个或者5个,少数副本故障不影响系统可用性。

百万级QPS前端代理

在OceanBase集群之上,我们提供一个反向代理OBProxy。看到这个,大家可能会联想到基于中间件构建的MySQL集群,但这两者是有本质区别的:简单地说,没有OBProxy,OceanBase集群一样能够工作,具备完整处理能力。

那我们为什么要有OBProxy呢?主要出于两方面的考虑:
一个是性能,通过OBProxy的路由功能,可以比较准确地将语句路由到合适的节点处理,减少集群内部转发;
另外一个是容错能力,在网络发生闪断情况下,OBProxy可以重建连接,让业务无感知。

分布式架构对业务透明

对业务来说,OceanBase分布式架构能做到的最好状态是什么呢?我认为是对业务透明。通过分布式架构,我们做到高可用、做到可扩展,但是对业务系统,要做到透明,表现为一个单节点数据库,体现在如下几点:

业务无需关心数据库对象的物理位置。业务连上OBProxy或者任何一个OB节点,就能看到完整的视图,能访问所有它有权限访问的数据。
集群SQL功能集等同于单节点SQL功能集。采用标准SQL语法,并且不因为数据分布影响SQL功能。当前版本大部分功能都做到了数据位置无关,但还有少数功能受位置影响,比如我们不支持在一条DML语句中修改多个节点的数据。在即将发布的2.0版本中,这些问题都会得到解决。
完整支持事务ACID特性,统一事务操作接口。业务无需区分分布式事务和单机事务,数据库内部会对不同的场景进行区分并做相应的优化。
自动处理分布式环境故障、做到业务无感知。通过OBServer 和OBProxy的重试机制,可以做到大多数环境故障对业务透明,但相对于之前建立在高可靠硬件上的单机系统,还有一些差异,个别场景异常需要业务处理。

2线性拓展
在满足业务高速发展的过程中,OceanBase数据库要解决的首要问题就是扩展性问题。通过全对等节点架构,我们消除了之前版本单点写入瓶颈。业务对数据库的要求是不停服务,永远在线,为此所有的操作都要是在线的。传统的垂直扩展的方式不行了,只能采用水平扩容的方式。这从方法上看也很直观,怎么做呢?分三步走:在集群中增加节点→让新节点具备服务能力→将一部分负载分发到新节点上。

看起来,似乎和将大象装进冰箱一样,步骤明确。但每一步都不是那么好做的。

因为OceanBase是无共享存储的,要想新增加的节点能够分担负载,新节点上先要有数据。最难的是此过程中既要保证数据一致性,又要不影响业务。无论是机房扩容(机房内新增机器)还是扩展到新机房(很有可能是异地或公有云场景),我们都必须做到在线。在OceanBase的实现中,主要依赖如下几点:

多副本机制。多副本不仅是高可用的基础,也是在线扩容的基础。从本质上来看,扩容无外乎两种:一种是将新数据写入到新节点,后续对该部分数据的读写也在新节点;另一种是将现节点上的部分数据移动到新节点并在新节点提供服务。
第一种情况容易处理;第二种情况就需要利用多副本机制,简单地理解就是把其中的一个副本从原节点迁移到新节点,说起来简单,做起来有很多的细节要考虑,比如在异地增加一个副本,怎么样做到既能高效地迁移数据同时又不影响现有服务。
可参考:多类型副本混搭:降低集群成本的利器
细粒度的主备关系。传统的主备大多数是节点级的,由于一个节点上保存的数据量较大,主备切换的影响很大。在OceanBase中,主备关系的粒度是分区级的,这是一个很细的粒度,切换对业务的影响比较小,并且切换是秒级的。
位置信息自动刷新。在扩容引起分区位置变化后,在第一次访问原位置时,系统会检测到变化,并且刷新位置信息来进行重试,执行成功后向客户端返回正确的结果。除OBServer端以外,OBProxy也会根据服务端的反馈来更新自己保留的位置信息,后续的访问就会被直接路由到正确的节点而无需集群内部转发。

扩容是在线的,缩容也是如此。

3高可用
高可用是OceanBase数据库安身立命的根本,以下三篇文章对此进行了详细的描述:
传统关系数据库高可用的缺失
如何在非可靠硬件上实现金融级高可用?
基于Raft分布式一致性协议实现的局限及其对数据库的风险

它们包括了“OceanBase和传统数据库的差异,以及,在选举协议上为什么我们选择Paxos协议而不是更容易理解的Raft协议?”等内容。在这里简短总结如下:

传统数据库高可用依赖专用硬件,而OceanBase是在普通商业硬件上实现高可用。
传统数据库在故障发生时缺乏仲裁机制,需要人在不丢数据和不停服务之间做选择;OceanBase基于Paxos协议在少数派副本故障情况下可以自动恢复,不丢数据(RPO=0),不停服务(受影响分区RTO小于30秒)。
采用Paxos协议而不是Raft协议的原因在于Raft协议要求日志确认必须是顺序的,如果前面的某条日志因为种种原因没有得到确认,后面的日志也都不能确认。这会造成一个严重后果,使得在业务逻辑层面不互相依赖的操作产生了互相依赖,对系统吞吐率有非常大的影响。尤其在高负载的时候。这种依赖是业务开发人员和DBA无法预测和规避的,发生的时候也无法有效解决。

除了异常情况下的可用性,系统升级、DDL变更等计划中的操作也不能影响系统可用性。我们通过逐个Zone升级的方式,实现升级过程的可灰度、可回滚;同时通过多个Zone之间的数据一致性校验来验证新升级系统的正确性。

通过实现多版本的数据库对象定义,我们实现了DDL操作和查询、更新操作互相不等待。针对多版本的数据库对象定义,多补充一句,DDL操作对数据库对象的影响保证能被对于同一个用户Session后续的操作看到,哪怕这个用户Session对应的是OBProxy到集群不同服务器的多个Session。

4高性能
高性能不仅仅意味着服务能力强,也意味着成本降低,在相同硬件条件下可以支撑规模更大的业务。OceanBase通过读写分离架构(LSM tree),将更新暂存在内存中,并且在内存中维护两种类型的索引:Hash索引和B+树索引,分别用来加速主键查询和索引范围查询,达到准内存数据库的性能。

和传统数据库不同的是:更新操作不是原地进行的,没有传统数据库的写入放大问题,对于一般规模的系统,内存可以放下一天的增量。在系统高负载运行的时候,几乎没有数据文件写,这会大大减少IO;在系统负载轻的时候,将内存增量批量合并到持久化存储上。

除了读写分离架构带来的性能提升外,我们在整个执行链路上做了不少优化,主要包括如下几类:

Cache机制。在数据层面有行缓存和数据块缓存,对于经常访问的数据,IO读大大降低了;在SQL引擎层,有执行计划缓存。
JIT编译执行。在表达式计算及存储执行过程中,都支持编译执行,大大加速了大量数据行的计算。
自适应能力。SQL引擎会根据语句操作数据的分布情况选择采用本地、远程、分布式执行,并基于代价选择合适的计划。在分布式执行的情况下,根据代价计算尽量将计算下降到节点。事务层会尽量采用本地事务,减少分布式事务以提升性能。
共享工作线程以及异步化。和传统数据库不同的是,OceanBase没有采用专有工作线程方式,工作线程多Session共享。此外,在语句执行过程以及事务提交时,多处采用异步化操作,最大限度地减少了无谓等待,充分利用CPU。

除上述情况以外,我们还做了很多细致的工作。整体来看效果非常明显:2017年“双十一”峰值4200万次操作每秒,用户体验相当顺滑,系统表现很平稳。

5低成本
OceanBase一方面需要满足业务对数据库的要求,另一方面也要节约成本,不仅仅是运营成本,还包括业务迁移和人员学习成本。

OceanBase的成本优势主要来自以下三点:
通过执行路径性能提升降低计算成本;
通过读写分离架构优势降低存储成本,一个真实的案例是某内部业务从Oracle迁移到OceanBase,原先的100TB缩小到30几个TB。因为OceanBase中可以采用压缩比更高的压缩算法,而在Oracle中,由于是原地更新要兼顾性能,没法采用消耗CPU过多的高压缩比压缩算法;
通过多租户架构,不同负载类型的业务通过多租户方式混合部署,能更加充分地利用了机器资源(可参考:多租户机制概述)。从实际应用来看,采用OceanBase数据库的金融业务,单账户成本只有原先的1/5到1/10。

6兼容性
以上的几个特点使得OceanBase具有竞争优势,但要将业务真正从原系统迁移到OceanBase还需要一个额外的特性——兼容性。高兼容性使得系统迁移能在可控的成本下进行。

对公司内部MySQL业务,OceanBase能做到业务零修改迁移。可以这么说,主流关系数据库具备的常用功能OceanBase都具备了。不仅是在语法层面,而且是在用户体验和业务体验上完全一致。

从2017年开始,OceanBase开始服务外部客户,我们发现兼容性做得还不够,还需要再上一层楼:不仅常用功能要兼容,更要全面兼容;不仅是要兼容MySQL,还要兼容商业数据库。只有这样,才能使得外部业务具备零修改迁移OceanBase的可能性。这些工作正是我们目前在做的。

三、未来展望

接下来,OceanBase 2.0版本即将发布,这个全新的版本在分布式能力和SQL功能上相对于1.X版本都有质的提升,我们也真诚希望,OceanBase 2.0能够让分布式架构对业务透明、让业务更方便地获得更好的数据库服务。
用户评论