TPC-C规范要求被测数据库的性能(tpmC)与数据量成正比。TPC-C的基本数据单元是仓库(warehouse),每个仓库的数据量通常在70MB左右(与具体实现有关)。TPC-C规定每个仓库所获得的tpmC上限是12.86(假设数据库响应时间为0)。假设某系统获得150万tpmC,大约对应12万个仓库,按照70MB/仓库计算,数据量约为8.4TB。某些厂商采用修改过的不符合审计要求的TPC-C测试,不限制单个warehouse的tpmC上限,测试几百到几千个warehouse全部装载到内存的性能,这是没有意义的,也不可能通过审计。在真实的TPC-C测试中,存储的消耗占了很大一部分。OceanBase作为第一款基于shared nothing架构登上TPC-C榜首的数据库,同时也作为第一款使用LSM Tree存储引擎架构登上TPC-C榜首的数据库,在存储架构上有如下关键点:
- 为了保证可靠性,OceanBase存储了两个数据副本和三个日志副本,而传统的集中式数据库测试TPC-C只存储一份数据;
- 由于OceanBase存储两个数据副本,再加上OceanBase TPC-C测试采用了和生产系统完全一样的阿里云服务器i2机型,SSD硬盘的存储容量成为瓶颈。OceanBase采用在线压缩的方式缓解这个问题,进一步增加了CPU使用;相应地,集中式数据库测试存储一份数据,不需要打开压缩;
- OceanBase LSM引擎定期需要在后台做compaction操作,而TPC-C要求测试至少运行8小时且2小时之内抖动小于2%,因此,OceanBase存储需要解决LSM引擎后台操作导致的抖动问题;
两份数据
为了保证可靠性和不丢数据(RPO=0),有两种不同的方案:一种方案是在硬件层面容错,另一种方案是在软件层面容错。OceanBase选择在软件层面容错,优势是硬件成本更低,带来的问题是需要冗余存储多个副本的数据。OceanBase使用Paxos协议保证在单机故障下数据的强一致。在Paxos协议中,一份数据需要被同步到多数派(超过一半),才被认为是写入成功,所以一般来说副本个数总是奇数,出于成本考虑最常见的部署规格是三副本。
三副本带来的首要问题就是存储成本的上升,之前商业数据库的TPC-C测试大多基于磁盘阵列,而TPC-C规范中明确对磁盘阵列不做容灾要求,使用相对于传统数据库三倍的存储空间进行TPC-C测试显然难以接受。我们注意到这样一个事实,通过Paxos协议同步的只是日志,日志需要写三份,但数据不是,数据只需要有两份就可以完成单机故障的容灾了,当一份数据由于服务器宕机不可用时,另一份数据只要通过日志把数据补齐,就可以继续对外提供访问。和数据存储相比,日志的存储量比较小。我们将数据与日志分开,定义了三种不同的副本类型:F副本既包含数据又同步日志,并对外提供读写服务;D副本既包含数据又同步日志,但对外不提供读写服务;L副本只同步日志,不存储数据。当F副本出现故障时,D副本可以转换为F副本,补齐数据后对外提供服务。在TPC-C测试中我们使用FDL模式进行部署(一个F副本,一个D副本,一个L副本),使用了两倍数据副本的存储空间。无论是D副本还是L副本,都需要回放日志,D副本还需要同步数据,这些都是都会消耗网络和CPU。
在线压缩
在shared nothing架构下,OceanBase至少需要存储两份数据才可以满足容灾的要求,这意味着OceanBase需要比传统数据库多耗费一倍的存储空间。为了缓解这个问题,OceanBase
TPC-C测试选择对数据进行在线压缩,Oracle数据库中一个warehouse的存储容量接近70MB,而OceanBase压缩后存储容量只有50MB左右,大幅降低了存储空间。TPC-C规范要求磁盘空间能够满足60天数据量的存储,对于OceanBase,由于需要保存两份数据,虽然可靠性更好,但需要保存相当于120天的数据量,这些存储成本都要计入总体价格。OceanBase使用了204台ECS i2云服务器存储数据,服务器规格和线上真实业务应用保持一致。每台服务器的日志盘1TB,数据盘接近13TB。计算两份压缩后的数据60天的存储空间之后,服务器的数据盘基本没有太多余量,从服务器的资源成本消耗来看,已经达到了比较好的平衡。如果OceanBase的单机性能tpmC进一步提升,磁盘容量将成为瓶颈。OceanBase LSM引擎是append-only的,它的优势是没有随机修改,能够在线压缩。无论是TPC-C测试,还是最核心的OLTP生产系统(例如支付宝交易支付),OceanBase都会打开在线压缩,通过CPU换存储空间。
存储性能平滑
TPC-C测试很大的挑战在于在整个压测过程中性能曲线要求是绝对平滑的,曲线上的波动幅度不能超过2%,这对于传统数据库来说都是一件困难的事情,因为这要求对于所有后台任务的精细控制,不能由于某个后台任务的资源过度使用导致前台请求的阻塞积压。而对于OceanBase而言,事情变得更为困难,因为OceanBase的存储引擎是基于LSM Tree的,在LSM Tree要定期执行compaction操作。Compaction是个非常重的后台操作,会占用大量CPU和磁盘IO资源,这对前台的用户查询和写入天然就会造成影响。我们做了一些优化,来平滑后台任务对性能的影响,从最终的测试结果来看,性能曲线在整个8小时压测过程中的抖动小于0.5%。
- 分层转储
在LSM Tree中,数据首先被写入内存中的MemTable,在一定时候为了释放内存,MemTable中的数据需要与磁盘中的SSTable进行合并,这个过程被称为compaction。在很多基于LSM Tree的存储系统中,为了解决写入的性能问题,通常会将SSTable分为多层,当一层的SSTable个数或者大小达到某个阈值时,合并入下一层SSTable。多层SSTable解决了写入的问题,但是SSTable的个数过多,会极大拖慢查询的性能。OceanBase同样借鉴了分层的思路,但同时使用了更加灵活的compaction策略,确保SSTable总数不会太多,从而在读取和写入性能之间做了更好的平衡。
- 资源隔离
Compaction等后台任务需要消耗大量的服务器资源,为了减少后台任务对用户查询和写入的影响,我们在CPU、内存、磁盘IO和网络IO四个方面对前后台任务做了资源隔离。在CPU方面,我们将后台任务和用户请求分为不同的线程池,并按照CPU亲和性做了隔离。在内存方面,对前后台请求做了不同的内存管理。在磁盘IO方面,我们控制后台任务IO请求的IOPS,使用deadline算法进行流控。在网络IO方面,我们将后台任务RPC和用户请求RPC分为不同队列,并对后台任务RPC的带宽使用进行流控。
存储CPU占用
TPC-C基准测试主要考察整体性能tpmC,很多人也会关注单核的tpmC。然而,这个指标只有在相同架构下才有意义。对于存储模块的CPU占用,有如下三点:
- 对于集中式架构,除了数据库使用CPU之外,专用存储设备也需要使用CPU。例如,第二名Oracle 3000多万tpmC的测试中,数据库使用了108颗T3 SPARC处理器,共有1728个物理核心和13824个执行线程,同时存储设备使用的是Intel服务器作为机头,总共使用了97台服务器,194颗Intel
X5670 CPU,2328个物理核心。 - 集中式数据库使用高可靠硬件,只需要存储一个副本,而OceanBase通过软件层面容错,虽然硬件成本更低但需要两个数据副本和三个日志副本,维护多个副本需要耗费大量CPU;
- OceanBase在TPC-C测试和生产系统中都打开了在线压缩,进一步增加了CPU使用;
因此,简单地对比OceanBase和Oracle的CPU核是不科学的,还需要算上共享存储设备的CPU核,以及OceanBase存储多副本和在线压缩带来的CPU开销。TPC-C推荐的方案是不关注具体的软件架构和硬件架构,关注硬件总体成本。在OceanBase的测试中,硬件成本只占整体成本的18%左右,只考虑硬件的性价比大幅优于集中式数据库。
后续发展
OceanBase的优势在于采用分布式架构,硬件成本更低,可用性更好且能够做到线性扩展,但是,OceanBase单机的性能离Oracle、DB2还有不小的差距,后续需要重点优化单机存储性能。另外,OceanBase的定位是在同一套引擎同时支持OLTP业务和OLAP业务,而目前OceanBase的OLAP处理能力还不如Oracle,后续需要加强存储模块对大查询的处理能力,支持将OLAP算子下压到存储层甚至在压缩后的数据上直接做OLAP计算。
作者介绍:
赵裕众:现任蚂蚁金服OceanBase团队高级技术专家,2010年加入支付宝后从事分布式事务框架的研发,2013年加入OceanBase团队,目前负责存储引擎相关的研发工作。