为什么 OceanBase 架构特别适合双十一
感谢所有同学的共同努力, 2016 年 OceanBase 分布式关系数据库渡过了一个成功的双十一:支持了支付宝核心的交易、支付、会员和账务等,并且创造了新的纪录:交易创建 17.5 万笔 / 秒、交易支付 12 万笔 / 秒、全天累计支付 10.5 亿笔!
其实,虽然不是刻意设计的,但 OceanBase 确实比传统数据库更适合像双十一、聚划算、秒杀以及银行国库券销售等短时间突发大流量的场景:
短时间内大量用户涌入
短时间内业务流量非常大,数据库系统压力非常大
一段时间(几秒钟、几分钟、或半个小时等)后业务流量迅速或明显回落
虽然 2010 年设计 OceanBase 架构时,其实并没有特别考虑到这个突发大流量的因素。让我们从 OceanBase 的架构说起。
OceanBase 是“基线数据(硬盘)” + “修改增量(内存)”的架构,如下图所示:

即整个数据库以硬盘(通常是 SSD )为载体,新近的增、删、改数据(“修改增量”)在内存,而基线数据在保存在硬盘上,因此 OceanBase 可以看成一个准内存数据库。这样的好处是:
写事务在内存(除事务日志必须落盘外),性能大大提升
没有随机写硬盘,硬盘随机读不受干扰,高峰期系统性能提升明显;对于传统数据库,业务高峰期通常也是大量随机写盘(刷脏页)的高峰期,大量随机写盘消耗了大量的 IO ,特别是考虑到 SSD 的写入放大,对于读写性能都有较大的影响
基线数据只读,缓存( cache )简单且效果提升
线上 OceanBase 的内存配置是支撑平常两天的修改增量(从 OceanBase 1.0 开始,每台 OceanBase 都可以写入,都承载着部分的修改增量),因此即使突发大流量为平日的 10-20 倍,也可支撑 1~2 个小时以上。

一个问题是:修改增量在内存,大概需要多大的内存?即使按双 11 全天的支付笔数 10.5 亿笔,假设每笔 1KB ,总共需要的内存大约是 1TB ,平均到 10 台服务器, 100GB/ 台。
另一个问题是:在类似双十一这种流量特别大的场景中,就像前面说到的, OceanBase 内存能够支持峰值业务写入 1~2 个小时以上,之后 OceanBase 必须把内存中的增删改数据(“修改增量”)尽快整合到硬盘并释放内存,以便业务的持续写入。整合内存中的修改增量到硬盘, OceanBase 称为每日合并,必然涉及到大量的硬盘读写( IO ),因此可能对业务的吞吐量和事务响应时间( RT )产生影响。如何避免每日合并对业务的影响呢? OceanBase 通过“轮转合并”解决了这个问题。
众所周知,出于高可用的考虑, OceanBase 是三机群( zone )部署:

根据配置和部署的不同,业务高峰时可以一个机群( zone )、两个机群( zone )或者三个机群( zone )提供读写服务。 OceanBase 的轮转合并就是对每个机群( zone )轮转地进行每日合并,在对一个机群( zone )进行每日合并之前,先把该机群( zone )上的业务读写流量切换到另外的一个或两个机群( zone ),然后对该机群( zone )进行全速的每日合并。因此在每日合并期间,合并进行中的机群( zone )没有业务流量,仅仅接收事务日志并且参与 Paxos 投票,业务访问 OceanBase 的事务响应时间完全不受每日合并的影响,仅仅是 OceanBase 的总吞吐量有所下降:如果先前是三个机群( zone )都提供服务则总吞吐量下降 1/3 ,如果先前只有一个或两个机群( zone )提供服务则总吞吐量没有变化。
轮转合并使得 OceanBase 对 SSD 十分友好,避免了大量随机写盘对 SSD 寿命的影响,因此 OceanBase 可以使用相对廉价的“读密集型” SSD 来代替传统数据库使用的相对昂贵的“读写型” SSD ,而不影响性能。此外由于轮转合并对服务器的 CPU 使用、硬盘 IO 使用以及耗时长短都不敏感(高峰期的传统数据库在刷脏页的同时还要优先保证业务访问的吞吐量和事务响应时间,刷脏页的 CPU 及 IO 资源都非常受限),因此 OceanBase 在每日合并时可以采用更加高效的压缩或者编码算法(比如压缩或编码速度略慢,但压缩率较高、解压缩很快的算法),从而进一步降低存储成本并提升性能。