OceanBase分布式技术架构分析.docx
- 文档编号:24904294
- 上传时间:2023-06-02
- 格式:DOCX
- 页数:13
- 大小:272.39KB
OceanBase分布式技术架构分析.docx
《OceanBase分布式技术架构分析.docx》由会员分享,可在线阅读,更多相关《OceanBase分布式技术架构分析.docx(13页珍藏版)》请在冰豆网上搜索。
OceanBase分布式技术架构分析
OceanBase分布式技术架构分析
OceanBase作为金融级分布式数据库一直备受瞩目
OceanBase
OceanBase1.0项目从2013年初开始做总体设计,2014年开始编码、测试,2015年底正式上线并无缝迁移部分集团MySQL业务,直到2016年中才正式上线蚂蚁核心业务,包括会员视图、花呗、账务,等等,最后“丝般柔顺”地通过了2016年双十一大考。
从技术架构的角度看,一个分布式数据库主要就是两个部分:
一个部分是怎么做存储,怎么做事务;另外一个部分是怎么做查询。
首先我们看第一个部分,主要是三个关键点:
可扩展、高可用以及低成本,它们代表了OceanBase的核心技术优势。
1.分布式存储&事务
第一我们怎么理解数据,如何把数据划分开来从而分布到多台服务器?
这个问题其实传统关系数据库已经帮我们解决好了。
无论是Oracle还是MySQL,都支持一个叫做两级分区表的概念。
大部分业务都可以按两个维度划分数据:
一个维度是时间,数据是按照时间顺序生成的;另外一个维度,对于互联网业务来讲,往往就是用户。
不同的用户生成不同的数据,不同用户之间的数据相关度比较低,而同一个用户的数据往往会被同时访问。
图1OceanBase数据分布
如图1,通过时间和业务主键两个维度将表格划分为P1~P8总共8个分区。
OceanBase跟传统数据库不一样的地方在哪里呢?
传统数据库所有的分区只能在一台服务器,而OceanBase每个分区可以分布到不同的服务器。
从数据模型的角度看,OceanBase可以被认为是传统的数据库分区表在多机的实现。
对于常见的分布式系统,要么采用哈希分区,要么采用范围分区。
OceanBase的数据划分方案和这些系统有较大的差别,通过两级分区表,我们可以把不同的用户,以及在不同时间点生成的数据全部融合到统一的表格里面。
无论这些分区在在多台服务器上是如何分布的,甚至可以对在线数据采用内存计算,对历史数据采用更高压缩率的压缩算法或者执行预计算,整个系统对使用者呈现的都是一张表格,后台实现对使用者完全透明。
当然,这里面还会有很多的工作要做。
第二点是我们底层的分布式架构。
图2OceanBase整体架构
图2是OceanBase整体架构图。
OceanBase架构图往往都是三个框框。
为什么这样呢?
这是基于高可用考虑的。
为了实现机房故障无损容灾,OceanBase需要部署到三个机房。
每个机房又会有很多服务器,每台服务器又会服务很多不同的分区。
如图2,P1到P8代表不同的分区,每个分区有3个副本,分布在三个机房内。
用户的请求首先发给ObProxy。
ObProxy是一个访问代理,它会根据用户请求的数据将请求转发到合适的服务器。
ObProxy的最大的亮点在于性能特别好,我们对它做了非常多的针对性优化,使得它可以在非常一般的普通服务器上达到每秒百万级的处理能力。
ObServer是OceanBase的工作机,每台工作机服务一些分区。
与大多数分布式系统不同的地方在于,OceanBase这个系统没有单独的总控服务器/总控进程。
分布式系统一般包含一个单独的总控进程,用来做全局管理、负载均衡,等等。
OceanBase没有单独的总控进程,我们的总控是一个服务,叫做RootService,集成在ObServer里面。
OceanBase会从所有的工作机中动态地选出一台ObServer执行总控服务,另外,当总控服务所在的ObServer出现故障时,系统会自动选举一台新的ObServer提供总控服务。
这种方式的好处在于简化部署,虽然实现很复杂,但是大大降低了使用成本。
接下来我们看整个数据库最核心的部分。
数据库最基础,也是最核心的部分是事务处理,这点对于多机系统尤其重要。
如果只是操作单个分区,因为单个分区一定只能由一台服务器提供服务,本质上是一个单机的事务,OceanBase的实现机制和Oracle、MySQL这样的传统数据库原理类似,也是多版本并发控制。
不同点在于,OceanBase做了一些针对内存数据库的优化,主要有两点:
1.日志同步。
因为要做高可用,一定要做日志的强同步。
OceanBase之所以既能做到高可用,又能做到高性能,是因为我们做了很多针对日志强同步的优化,包括异步化、并行,等等;
2.内存数据库。
OceanBase借鉴了内存数据库的设计思路,实现了无锁数据结构、内存多版本并发控制、SQL编译执行等优化手段。
如果操作多个分区,这又分成两种情况:
1.多个分区在同一台服务器。
由于多个分区在一台服务器,本质上也是单机事务,实现方案与之前提到的单分区事务类似。
2.多个分区分布在多台服务器上。
由于多个分区跨ObServer,OceanBase内部通过两阶段提交实现分布式事务。
当然,两阶段提交协议性能较差,OceanBase内部做了很多优化。
首先,我们提出了一个表格组的概念,也就是说,我们会把多个经常一起访问,或者说访问模式比较类似的表格放到一个表格组里面。
与此同时,OceanBase后台会将同一个表格组尽可能调度到一台服务器上,避免分布式事务。
接下来的优化手段涉及到两阶段提交协议的内部实现。
两阶段提交协议涉及多台服务器,协议中包含协调者、参与者这两种角色,参与者维护了每台服务器的局部状态,协调者维护了分布式事务的全局状态。
常见的做法是对协调者记日志来持久化分布式事务的全局状态,而OceanBase没有这么做。
如果协调者出现故障,OceanBase通过查询所有参与者的状态来恢复分布式事务。
通过这种方式节省了协调者日志,而且只要所有的参与者都预提交成功,整个事务就成功了,不需要等协调者写日志就可以应答客户端。
OceanBase里面高可用是基于Paxos协议实现的。
GoogleChubby系统的发明者说过一句话,这个世界上所有的高可用强一致的协议都是Paxos或者Paxos的变种,我们也认为一切不是Paxos协议实现的高可用机制都是耍流氓。
图3OceanBase高可用原理
如图3,OceanBase最底层的技术就是通过Paxos协议实现的分布式选举和多库多活。
Paxos协议的好处在于节点是多活的,当服务节点出现故障时,其它正常的节点可以在几秒内替代这个故障的节点,很快恢复服务,而且完全不丢数据。
Paxos协议同时实现了高可用和强一致,这是很牛的。
当然除了最底层核心的Paxos协议,OceanBase还会通过分布式调度将同一个分区的不同副本调度多多个机房,而不是在一个机房或者一个机架里面。
当服务器出现故障,OceanBase客户端能够很快自动感知到,并把服务切到没有故障的服务器上。
通过这一系列组合拳,OceanBase真正做到了持续可用。
图4高可用:
OceanBaseVSOracle
图4是OceanBase和Oracle的高可用能力对比。
1.单个节点故障,相比OracleRAC,OceanBase单个节点故障的影响会小一些,为什么?
因为OceanBase的集群规模往往会比较大,单个节点的故障只影响很小一部分数据。
另外,OceanBase的恢复速度也会更快。
OceanBase采用基线加增量的存储引擎,最热的增量数据都是全部在内存的。
当主库出现故障,备库只需要把最后一部分未完成的日志回放出来就能够提供服务,非常快。
而Oracle底层存储是基于页面的,它需要逐步恢复页面,这个过程相对更长。
2.机房整体故障。
OceanBase在蚂蚁都是三机房部署的,当一个机房出现故障,OceanBase也能够做到几十秒恢复,和单个节点故障的恢复速度基本相当。
但是,传统的关系数据库,即使是Oracle也做不到,OracleRAC不太可能部署到多个机房的。
接下来我们看看OceanBase的性能。
长远来看,性能取决于底层的引擎如何设计,而OceanBase的引擎跟传统数据库的引擎有较大的差别。
图5:
两类数据库引擎
在互联网里面能够看到各种各样的存储系统,引擎非常多,我认为基本可以分为两个大类。
如图5,第一类是传统关系数据库引擎。
关系数据库本质上是面向磁盘设计的,它把数据分成很多很多的页面,通过页面缓存机制来管理页面,底层的索引是B+树。
这种引擎发展得非常成熟,但是写入性能差,原因是关系数据库的写入放大效应。
用户数据是按行写入的,但是关系数据库却是按页面管理的,有时只写了一行数据,却不得不把整个页面刷入磁盘。
另外一类互联网公司流行的引擎是LSM树。
Google里面有一个很有名的开源系统LevelDB,Facebook基于它又开发了一个类似的系统RocksDB。
这种引擎采用基线加增量的设计,数据首先以增量的形式写入到内存中,当增量达到一个阀值时统一写到磁盘。
这种做法的好处是解决了关系数据库写入放大的问题,但是它的合并代价会比较大,可能出现合并速度赶不上内存写入的情况。
图6OceanBase存储引擎
OceanBase本质上是一个基线加增量的存储引擎,跟关系数据库差别很大,但是我们借鉴了传统关系数据库的优点对引擎进行了优化。
如图6,第一个优化就是合并性能的优化,传统数据库把数据分成很多页面,我们也借鉴了传统数据库的思想,把数据分成很多2MB为单位的宏块。
执行合并时,如果只有一部分数据修改,那么,只需要合并那些修改过的宏块,而不是把所有没有修改的宏块也一起合并。
通过这个方式,OceanBase的合并代价相比LevelDB和RocksDB都会低很多,这是第一点。
第二,我们会利用OceanBase的分布式机制做优化。
在多机系统中,数据一定是存在多个副本。
OceanBase实现了一个称为轮转合并的机制。
当主副本提供服务时,其它副本可以执行合并;等到其它副本合并完成以后,原来的主副本接着合并,并把流量切到已经合并完成的副本。
通过这种方式,OceanBase把正常服务和合并时间错开,使得合并操作对正常用户请求完全没有干扰。
由于OceanBase采用基线加增量的设计,一部分数据在基线,一部分在增量,原理上每次查询都是既要读基线,也要读增量。
为此,OceanBase做了很多的优化,尤其是针对单行的优化。
OceanBase内部把很多小查询的结果缓存在内存里面,以行为单位,而不是以块为单位。
行缓存包括两个部分,如果这个行存在,缓存这个行的原始数据;否则,缓存布隆过滤器。
OLTP业务大部分操作为小查询,通过小查询优化,OceanBase避免了传统数据库解析整个数据块的开销,达到了接近内存数据库的性能。
另外,由于基线是只读数据,而且内部采用连续存储的方式,OceanBase可以采用比较激进的压缩算法,既能做到高压缩比,又不影响查询性能,大大降低了成本。
图7SQL-VM
多租户隔离有不同的实现方式,这些实现方式的效果是类似的。
最传统的实现方式是虚拟机。
这种方案比较成熟,在云环境也经常使用,然而,这种方案比较重量级,开销比较大。
另外一种最近比较流行的技术类似GoogleCgroup这样的轻量级隔离技术,或者一些Cgroup衍生的技术,比如Docker。
OceanBase的隔离方式很不一样,我们采用的是在数据库内部做了一个SQL虚拟机。
为什么这么做呢?
这种做法在业内也是有例可寻的,例如Oracle12c以及AzureSQLServer。
它的好处是DB内把很多业务统一的管理,会把整个管理机制做得对用户特别透明。
另外,隔离的开销比较低,单台服务器可以服务更多的租户,降低云服务的整体成本。
图8OceanBase多租户原理
OceanBase是分布式系统,多租户除了单机层面怎么做隔离,还涉及到在多机层面如何做调度。
如图8,在OceanBase中,有的租户比较小,位于一台服务器上,例如租户B或者租户C;有的租户比较大,位于多台服务器上,例如租户A。
图8中的租户A在每台服务器上有一个资源容器,限制了该租户能够使用的CPU、网络、内存、IOPS等系统资源。
OceanBase的负载均衡分为两个层面:
第一个层面是租户负载均衡,它的原理就是把每个租户的资源容器分布到很多台ObServer上面去;第二个层面是分区负载均衡,如果租户只在一台服务器,第二个层面是没有必要的。
如果租户在多台服务器上,需要把这个租户的分区均匀地分布到它的资源容器中。
OceanBase内部会尽量使得小租户只在一台服务器上,避免分布式事务。
当租户需要的资源逐步增加时,OceanBase也能做到自动扩展,对用户是透明的。
SQL-VM是OceanBase实现的资源隔离方案,分为三个部分:
CPU、IO还有内存,网络目前还不是瓶颈,我们做得比较少。
CPU隔离是基于时间片的主动调度,跟操作系统的调度比较类似。
IO隔离我们借鉴了虚拟机隔离方案,采用基于Deadline和优先级的隔离算法。
这里最大的难点在于既要把资源的利用率提高,又要做到尽可能公平,这两个目标本身是矛盾的。
内存隔离基本上是两个机制,一个机制是怎么做内存的限制,另外一个机制是怎么做公平挤占算法。
2.分布式查询
用户的请求首先会发送到一台称为ObProxy的代理服务器,它的功能就是一个透明转发的代理服务。
ObProxy会解析SQL,识别SQL操作哪个分区,然后把该SQL转发到它所操作的分区所在的服务器。
图9ObProxy原理
如图9,可以看到,如果SQL请求操作分区P2,ObProxy就会转发到左边的服务器;如果涉及到多个分区,例如同时操作P1、P4,由于它们位于不同的服务器,ObProxy就会随机或者根据负载选择一台服务器。
ObProxy最大的亮点还是在于它的性能。
世面上有很多数据库代理服务方案,ObProxy的性能是其中的佼佼者。
我们实现了大量的优化技术,包括:
1.轻量级SQLParser。
如果采用传统的数据库SQL解析框架,性能肯定是不高的,OceanBase做了大量的手工解析工作。
2.异步框架。
ObProxy是全异步框架,无论是SQL转发,还是网络收发包,所有操作都是全异步的,从而把CPU利用到极致。
3.可扩展性。
ObProxy内部会使得对一个请求的转发尽可能做到每一个线程内部,避免跨线程访问或者访问全局的数据结构。
我们基本上做到每个请求都是在一个线程内完成的,ObProxy可以做到随着CPU核心完全线性扩展。
除了性能卓越之外,ObProxy还实现了在实际生产系统非常关键的运维特性。
第一个运维特性是热升级,ObProxy的升级对使用者是无感知的。
升级过程中,ObProxy内部会有两个版本,新的请求会由新的版本提供服务,老的请求由老的版本提供服务,过了很长时间才会把老版本退出。
另外一个运维特性是全链路监控,ObProxy作为用户使用OceanBase的入口,和服务端一起联合实现了全链路监控功能。
当SQL请求到了ObServer服务端,经过SQL解析、重写、优化等一系列过程后,再由SQL执行器来负责执行。
分为三种情况:
1.本地计划。
如果ObProxy请求转发对了,转发的位置就是分区所在的ObServer,这是个本地请求,其执行方式和传统的单机数据库相同。
2.远程计划。
SQL请求只操作一个分区,但是ObProxy应用缓存的信息失效,或者出现一些BUG,把请求转发到另外一个服务器。
OceanBase会自动发现这一点,并把SQL当成远程计划来处理,即内部把SQL执行计划发到另外一台有数据的服务器,等那台服务器计算出结果再返回。
3.分布式计划。
如果SQL请求涉及的数据在多台服务器,需要走分布式计划。
这种请求涉及的数据量往往比较大,OceanBase后台会做并行处理,比如说对任务做拆分,对每个子任务的结果做合并、处理并发、限制并发数,等等。
基本上可以这么讲,在并行数据库或者OLAP分析型数据库看到的东西,在OceanBase的分布式计划中都有。
3.经验&思考
第一点关于高可用。
首先,我认为强一致加高可用是未来云数据库的标配。
我们以前做应用架构和存储选型的时候会谈很多东西,比如数据库异步复制提高性能,或者CAP理论导致一致性和高可用不可兼得,等等。
然而,通过OceanBase的实践我们也已经得出一个结论,实现强一致相比实现弱一致性能开销不是那么大,性能的损耗比较低,而且可以获得非常多的好处,这一定是以后的趋势。
另外,实现云数据库级别的高可用底层一定要用Paxos协议,回避该协议的实现方案本质上都是耍流氓。
目前我们已经从各大互联网公司,包括Google、Amazon以及Alibaba的云数据库实践看到了这一趋势。
第二点关于自动化。
以前传统的关系数据库规模往往比较小,只有少数几台机器,有一个DBA运维就够了。
然而,在云数据库时代,一定要做规模化运维,一个DBA对几千甚至上万机器,达到这个量级一定要做自动化。
强一致是自动化的前提,没有强一致很难自动化,主库故障备库会丢数据,自动化是很难的。
虽然每次宕机概率很低,但是规模上来概率就高了。
另外云数据库设计的时候也会有很多不一样的考虑,尽可能地减少人工干预。
例如数据库配置项,或者比较流行的SQLHint,在云数据库时代一定需要尽可能减少。
系统设计者需要在服务端自己消化,不要把灵活性留给运维的人员,因为运维的人要做的就是规模化运维。
最后一点关于成本。
成本是云的关键,很多用户上云就是为了节省成本。
首先,性能不等于成本。
性能虽然很重要,但是成本需要考虑更多的因素,性能、压缩比、利用率、规模化运维,等等。
以利用率为例,云数据库的一个成本节省利器就是提高机器利用率。
在云数据库中,可以通过分布式方案把整个利用率提高来,即使单机性能类似,但是利用率提上来以后,成本会特别的低。
最后是OceanBase的存储引擎跟传统数据库有很大的区别,是基线加增量引擎,这种引擎有特别多的好处,能够比较完美地解决OLTP和OLAP业务融合的问题。
如果实现得当,把这种引擎的缺陷规避地比较好,能够收获大量的好处,相信也是未来的趋势。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- OceanBase 分布式 技术 架构 分析