国产数据库在技术架构上主要分为集中式、基于中间件分布式和原生分布式架构,衍生出集中式架构和分布式架构。那么在这些部署架构中,从数据分布的视角来看,在数据库中数据分布的形态是怎样的。本文将简要分析OceanBase、PolarDB、OpenGauss、GaussDB、GoldenDB、TiDB和TDSQL这几个主流的国产数据库的存储类型及存储引擎。
1、国产数据库存储类型
国产数据库在技术架构上主要分为集中式、基于中间件分布式和原生分布式架构,衍生出集中式架构和分布式架构。那么在这些部署架构中,从数据分布的视角来看,在数据库中数据分布的形态是怎样的,主要分为本地存储、集中式存储和分布式存储:
- 本地存储:从应用访问的角度,表数据存储在当前数据库实例节点,数据的增删改查都是在当前实例进行的。
- 集中式存储:数据库多实例节点访问同一份数据,比如多个可读写实例、主备节点实例,访问相同的数据;
- 分布式存储:应用表数据存储在多个数据库实例中,应用访问存在跨多个数据库节点
以上定义是从应用表数据的分布形态出发,非传统意义上数据最终存储载体的定义。文中将简要分析OceanBase、PolarDB、OpenGauss、GaussDB、GoldenDB、TiDB和TDSQL这几个主流的国产数据库的存储类型及存储引擎。
1.1 OceanBase数据库
OceanBase是云原生分布式数据库,具备高可用、可扩展、高度兼容Oracle和MySQL协议等特性。OceanBase数据库采用Shared-Nothing架构(如下图所示),各个节点之间完全对等,每个节点都有自己的SQL引擎、存储引擎和事务引擎。
- OBProxy:OB数据库代理ODP,负责接收用户的SQL请求,结合请求中涉及数据的分布,将用户SQL请求转发到最佳的OBServer节点上,在OBServer节点上执行完成后接受结果并将执行结果返回给用户;
- OBServer:OB数据库实例包含SQL引擎、事务引擎和存储引擎,负责所在节点分区数据的读取、路由到本机的SQL语句的解析和执行。
1.1.1 存储层架构
在OB数据库中,一个表的数据可以按照某种划分规则水平拆分为多个分片,每个分片叫做一个表分区,简称分区(Partition),其中某行数据属于且只属于一个分区。分区的规则由用户在建表的时候指定,包括hash、range、list等类型的分区,还支持二级分区。一个表的若干个分区可以分布在一个可用区内的多个节点上。每个物理分区有一个用于存储数据的存储层对象,叫做Tablet,用于存储有序的数据记录。
OceanBase数据库的存储引擎基于LSM-Tree架构,将数据分为静态基线数据(SSTable中)和动态增量数据(MemTable中)两部分,其中SSTable是只读的,一旦生成就不再被修改,存储于磁盘;MemTable支持读写,存储于内存。数据库DML操作插入、更新、删除等首先写入MemTable,等到MemTable达到一定大小时转储到磁盘成为SSTable。在进行查询时,需要分别对SSTable和MemTable进行查询,并将查询结果进行归并,返回给SQL层归并后的查询结果。同时在内存实现了Block Cache和Row cache,来避免对基线数据的随机读。当内存的增量数据达到一定规模的时候,会触发增量数据和基线数据的合并,把增量数据落盘。同时每天晚上的空闲时刻,系统也会自动每日合并。
在OB中,每个分区的基本存储单元是一个个SSTable,而所有存储的基本粒度是宏块,数据文件按照2MB定长切分为一个个宏块,SSTable实际是多个宏块的集合。
1.1.2 复制层架构
当用户对Tablet中记录进行修改的时候,为了保证数据持久化,需要记录重做日志(REDO)到Tablet对应的日志流(Log Stream)里。日志流代表一些数据的集合,包括若干Tablets和有序的Redo日志流。在分布式环境下,OB会将同一个日志流数据拷贝到多个机器称之为副本,同一日志流的多个副本使用Multi-Paxos一致性协议保证副本的强一致,每个日志流和它的副本构成一个独立的 Paxos 组,其中一个日志流为主副本(Leader),其它日志流为从副本(Follower)。主副本具备强一致性读和写能力,从副本具备弱一致性读能力。
1.2 PolarDB数据库
PolarDB数据库是云原生的数据库产品,共有三个引擎,分别为PolarDB MySQL版、PolarDB PostgreSQL版、PolarDB分布式版。
1.2.1 PolarDB集中式架构
PolarDB集中式架构采用计算存储分离的共享存储架构,主节点和只读节点使用物理复制、RDMA网络低时延,能够快速同步数据。基于存储级别的复制解决了主从异步复制带来的备库数据一致性问题,保证数据库集群故障时候的数据零丢失。
- Proxy: 通过内部的代理层Proxy对外提供服务,应用程序的请求都先经过代理层,然后访问到数据库节点。代理层主要实现安全认证、保护和会话保持,SQL解析、读写操作分发以及实现读写分离功能。
- 计算节点:一写多读集群内有一个读写节点以及多个只读节点,多主集群(仅MySQL版支持)内可支持多个读写节点和多个只读节点,计算节点主要提供数据库SQL引擎功能。
- 共享存储:集群内的多个节点共享存储资源,单集群支持最高100TB存储空间。计算节点和存储节点之间采用高速网络互联,并通过RDMA协议进行数据传输,保证I/O性能。
- 存储数据多副本:存储节点的数据采用多副本形式,确保数据的可靠性,并通过Parallel-Raft协议保证数据的一致性。
PolarDB数据库采用存算分离的架构,计算节点仅存储元数据,而将数据文件、Redo Log等存储于远端的存储节点。各计算节点之间仅需同步Redo Log相关的元数据信息,极大地降低了主节点和只读节点间的复制延迟,而且在主节点故障时,只读节点可以快速切换为主节点。
1.2.2 PolarDB分布式架构
PolarDB分布式版(PolarDB-X)采用了基于计算存储分离的Share Nothing系统架构,具备高可用、高吞吐、大存储、低时延和易扩展特性。
- 元数据服务(Global Meta Service,GMS):主要提供分布式的元数据,提供全局授时服务(TSO),维护Table/Schema、Statistic等Meta信息、维护账号、权限等安全信息。
- 计算节点(Compute Node,CN):主要提供分布式SQL引擎,包含核心的优化器和执行器。基于无状态的SQL引擎提供分布式路由和计算,解决分布式事务2PC协调、分布式DDL执行、全局索引维护等。
- 存储节点(Data Node,DN):主要提供数据存储引擎,基于多数派Paxos共识协议提供高可靠存储、分布式事务的MVCC多版本存储,并提供分布式计算下推能力,可支持本地盘和共享存储。PolarDB-X的DN存储节点是基于强一致数据库X-DB构建,X-DB使用InnoDB引擎,兼容MySQL语法。
- 日志节点(Change Data Capture,CDC):主要兼容MySQL生态的主备复制协议,兼容Binlog协议和数据格式、支持主备复制Replication的协议和交互。通过PolarDB-X的CDC组件,提供与MySQL Binlog兼容的数据库变更日志,并提供给下游系统进行日志的消费和订阅。
1.3 OpenGauss数据库
OpenGauss是华为基于PostgreSQL内核开发的国产集中式数据库系统,采用木兰宽松许可证v2发行,具备高可靠、高性能、高安全、易运维和全开放等特性。和PostgreSQL数据库相比,二者在底层架构和数据存储方面类似,但OpenGauss在性能和扩展性方面进行了优化。
OpenGauss在部署架构上采用主备部署的模式,主备之间通过日志同步方式实现数据同步。在逻辑架构上分为管理模块OM和CM、数据库实例OpenGauss以及存储节点:
- 运维管理模块OM(Operation Manager):提供数据库日常运维、配置管理的管理接口、工具等
- 数据库管理模块CM(Cluster Manager):管理和监控数据库系统中各个功能单元和物理资源的运行情况,确保整个系统的稳定运行。CM提供数据库主备的状态监控、网络通信故障监控、文件系统故障监控、故障自动主备切换等能力。
- OpenGauss实例:负责存储业务数据、执行数据查询任务以及向客户端返回执行结果。在高可用架构下通常部署一主多备,并部署在不同的服务器上。
- 存储Storage:服务器的本地存储,用于数据持久化,支持集中式存储
- 客户端驱动:负责接收来自应用的访问请求,并向应用返回执行结果。客户端驱动负责与openGauss实例通信,发送应用的SQL命令,接收openGauss实例的执行结果。
其中CM支持两种DN选主仲裁协议,两种都适用于1主多备的集群,1主1备的不适用
- Quorum 模式:基于多数派模式仲裁,选出同步备。当DN分片处于无主场景时,CM在多数派DN redo完成后,选择term和lsn最大的节点(同步备)发送failover升主
- DCF(Distributed Consensus Framework)模式:基于Paxos协议的选主模式,该模式下DN自动选主,CM不再进行对DN选主,只负责数据采集,假死检测等。
1.3.1 存储层架构
OpenGauss支持可插拔的存储引擎架构,在原生的存储引擎基础上新增了in-place update存储引擎、索引多版本管理增加事务信息、内存表管理MOT。
1)In-place update存储引擎(Ustore)
In-place Update存储引擎(原地更新),是openGauss内核新增的一种存储模式,在此前的版本使用的行存储引擎是Append Update(追加更新Astore)模式。追加更新对于业务中的增、删以及HOT(HeapOnly Tuple)Update(即同一页面内更新)有很好的表现,但对于跨数据页面的非HOT UPDATE场景,垃圾回收不够高效。新增的In-place update存储引擎旨在解决Append update存储引擎空间膨胀和元组较大的问题,高效回滚段的设计是In-place update存储引擎的基础。
2)MOT内存优化存储引擎
MOT存储引擎是基于多核和大内存的服务器进行的优化,通过完全存储在内存中的数据和索引、非统一内存访问感知(NUMA-aware)设计、消除锁和锁存争用的算法以及查询原生编译,MOT可提供更快的数据访问和更高效的事务执行。
1.4 GaussDB数据库
GaussDB数据库(for openGauss)作为企业级的分布式数据库,支持分布式和主备的部署场景,其中分布式版本包含CN(计算节点)、DN(数据存储节点)和GTM(分布式事务管理器)等节点类型。GaussDB数据库的分布式版本是基于share-nothing架构实现的,通过GTM-Lite技术实现事务强一致,消除了无中心节点性能的瓶颈。
GaussDB数据库在数据库组件上相比OpenGauss数据库多了协调节点(Coordinator Node)和全局事务管理器(Global Transaction Manager),如下图所示。
- OM(Operation Manager):运维管理模块提供数据库日常运维、配置管理的管理接口、工具等
- CM(Cluster Manager):数据库管理模块管理和监控数据库系统中各个功能单元和物理资源的运行情况,确保整个系统的稳定运行。CM提供数据库主备的状态监控、网络通信故障监控、文件系统故障监控、故障自动主备切换等能力。
- GTM(Global Transaction Manager):全局事务管理器负责生成和维护全局事务ID、事务快照、时间戳和sequence等全局唯一的信息。
- CN(Coordinator Node):协调节点负责接收来自应用的访问请求,并向客户端返回执行结果;负责对SQL请求解析,并将请求路由到不同的DN分片上执行。
- DN(Data Node):数据节点负责存储业务数据、执行数据查询任务以及向CN或客户端返回执行结果
- ETCD:分布式键值存储系统,用于共享配置和服务发现
- CMS(cm_server):进行数据库实例管理和实例仲裁的组件。主要功能包括:1)接收各个节点上cm_agent发送的数据库各实例状态;2)提供数据库实例整体状态的查询功能;3)监控实例的状态变化并进行仲裁命令的下发
- Storage:服务器的本地存储,用于数据持久化,支持集中式存储
1.4.1 GaussDB存储引擎
存储引擎向上对接SQL引擎,为SQL引擎提供或接收标准化的数据格式(元组或向量数组);存储引擎向下对接存储介质,按照特定的数据组织方式,以页面、压缩单元(Compress Unit)或其他形式为单位,通过存储介质提供的特定接口,对存储介质中的数据完成读、写操作。
GaussDB存储引擎包括行存引擎和列存引擎以及MOT内存引擎,行存引擎主要面向TP类业务、列存引擎主要面向AP类业务。行存引擎对于读写并发操作,采用多版本并发控制(MVCC,Multi-Version Concurrency Control);对于写写并发操作,采用基于两阶段锁协议(2PL,Two-Phase Locking)的悲观并发控制(PCC,Pessimistic Concurrency Control)。
1.5 GoldenDB数据库
GoldenDB分布式数据库是基于分布式中间件的分库分表架构,该架构将数据分成不同的分片,每个分片又存储在不同的存储节点,且单个分片是主备复制架构以保证高可用。业务请求经过数据库中间件(计算节点)解析和路由分发到不同的数据分片,实现分布式功能。同时通过全局事务协调节点来保证事务的全局一致性。GoldenDB数据库在整体架构上由由计算节点、数据节点、全局事务管理器、管理节点四种核心模块组成。
- 计算节点CN:负责SQL优化、SQL路由、数据节点的负载均衡、分布式事务调度等;
- 数据节点DN:数据存储节点,每个数据节点对应一个MySQL实例,多个数据节点组成一个DBGroup;
- 全局事务节点GTM:用于协助计算节点进行分布式事务管理,主要包括全局事务ID(GTID)的生成和释放、维护活跃事务列表以及当前活跃事务的快照。GTM包括集群级别的GTM和租户级别的GTM,租户级别只用于当前租户、集群级别是整个集群共用;
- 管理节点:包括数据库运维管理平台Insight、元数据管理模块MDS、数据库集群管理模块CM和计算节点集群管理模块PM。
GoldenDB分布式数据库支持多租户管理模式、架构上支持横向动态扩展和节点扩缩容,提供读写分离策略。主备节点之间采用快同步方式同步复制,并采用gSync技术提高同步性能,满足金融级别的高可用要求。GoldenDB数据库的存储节点是基于MySQL数据库的,内核存储引擎上使用的是InnoDB引擎。
1.6 TiDB数据库
TiDB是开源云原生分布式关系型数据库,采用存储和计算分离的架构、提供行列存储引擎支持HTAP混合型业务、基于Multi-Raft多数派协议实现多副本之间数据同步,满足金融级别的高可用要求。TiDB兼容MySQL协议和MySQL生态,并提供多种数据迁移工具实现MySQL应用平滑迁移到TiDB。
TiDB分布式数据库将整体架构拆分成了多个模块,各模块之间互相通信,组成完整的TiDB系统。对应的架构图如下:
- TiDB Server:SQL层负责接受客户端的连接、执行SQL解析和优化,最终生成分布式执行计划。TiDB Server本身是无状态的,通过负载均衡组件对外提供统一的接入地址。
- PD(Placement Driver):TiDB集群的元数据管理模块,是整个集群的“大脑”,负责存储每个TiKV节点实时的数据分布情况和集群的整体拓扑结构,提供TiDB Dashboard管控界面,并为分布式事务分配事务ID。
- TiKV Server:分布式key-value存储节点,存储数据的基本单位是Region,每个Region负责存储一个Key Range的数据,每个TiKV节点会负责多个Region。
- TiFlash:列式存储引擎的存储节点,主要用于AP型的业务场景。
1.6.1 RocksDB存储引擎
RocksDB是由Facebook基于LevelDB开发的一款提供key-value存储与读写功能的LSM-tree架构引擎。RocksDB适用于多CPU场景、高效利用fast storage比如SSD、弹性扩展架构、支持IO-bound/in-memory/write-once等功能。
RocksDB不是一个分布式的DB,而是一个高效、高性能、单点的数据库引擎。RocksDB持久化存储key-value键值对数据,keys和values可以是任意的字节流,且按照keys以log-structured merge tree的形式有序存储。
上图就是Rocksdb的基础架构,主要完成以下功能:
- Rocksdb中引入了ColumnFamily(列族,CF)的概念,所谓列族也就是一系列kv组成的数据集。所有的读写操作都需要先指定列族。
- 写操作先写WAL,再写memtable,memtable达到一定阈值后切换为Immutable Memtable,只能读不能写。
- 后台Flush线程负责按照时间顺序将Immu Memtable刷盘,生成level0层的有序文件(SST)。
- SST又分为多层(默认至多6层),每一层的数据达到一定阈值后会挑选一部分SST合并到下一层,每一层的数据是上一层的10倍(因此90%的数据存储在最后一层)。
- Manifest负责记录系统某个时刻SST文件的视图,Current文件记录当前最新的Manifest文件名。
- 每个ColumnFamily有自己的Memtable,SST文件,所有ColumnFamily共享WAL、Current、Manifest文件。
RocksDB作为TiKV的核心存储引擎,用于存储Raft日志以及用户数据。每个TiKV实例中有两个RocksDB实例,一个用于存储Raft日志(通常被称为raftdb),另一个用于存储用户数据以及MVCC信息(通常被称为kvdb)。kvdb中有四个ColumnFamily:raft、lock、default和write:
- raft列:用于存储各个Region的元信息,仅占极少量空间
- lock列:用于存储悲观事务的悲观锁以及分布式事务的一阶段Prewrite锁。当用户的事务提交之后, lock cf中对应的数据会很快删除掉,因此大部分情况下lock cf中的数据也很少(少于1GB)。如果lock cf中的数据大量增加,说明有大量事务等待提交,系统出现了bug或者故障。
- write列:用于存储用户真实的写入数据以及MVCC信息(该数据所属事务的开始时间以及提交时间)。当用户写入了一行数据时,如果该行数据长度小于255字节,那么会被存储write列中,否则的话该行数据会被存入到default列中。由于TiDB的非unique 索引存储的value为空,unique索引存储的value为主键索引,因此二级索引只会占用writecf的空间。
- default列:用于存储超过255字节长度的数据
1.6.2 TiKV中的Raft算法
TiKV使用Raft算法来保证数据的一致性,默认情况下使用3副本组成一个raft group,过Raft的日志复制功能,将数据安全可靠地同步到raft group的每一个节点中。
- 当client端需要写数据的时候,它会发送请求给Raft Leader,Leader会将操作解码为log entry并以append方式写入自己的Raft log中
- Leader会根据Raft算法将log entry复制到Follower,Follower也会将这些entry追加到log entry中,并且通知Leader已经完成
- 当Leader发现log entry追加到多数majority节点中,它会认为这个log entry已经committed。之后Leader会解码entry中的操作,执行它们并应用到状态机中,这个过程称之为apply
另外,TiKV支持lease Read功能:对于读请求,可以直接发送给Leader,如果leader判断基于时间的lease没有过期,则可以直接提供读请求的客户端,不需要经过Raft算法过程;如果过期了,则leader需要强制通过Raft算法来更新lease内容提供该客户端。
1.7 TDSQL数据库
TDSQL(for MySQL)分布式数据库基于Shared Nothing架构和分布式中间件将数据拆分到多个物理分片节点上,支持自动水平拆分、主备同步复制满足金融级别高可用要求。TDSQL分布式数据库采用存算分离的架构,采用多租户的模式支持集中式和分布式实例部署、X86和ARM服务器混合部署。主要包括以下功能模块:
- 数据库存储层:由数据库节点组(SET)组成,SET是逻辑概念,由一组物理设备或虚拟化节点构成
- SET存储数据库核心数据,采用主从高可用(HA)架构,节点数通常≥2,根据业务实际需求可扩展
- 每个节点(Node)信息采集与管理模块(Agent),互相检测心跳以确保集群的健壮性
- 数据库计算层:是由SQL引擎(SQL-Engine)组成,又称为Proxy。计算层既要管理客户端的长短连接,还要处理复杂的SQL语句进行汇总计算,属于CPU密集型高内存消耗的组件。
- Proxy是无状态的,本身不存储数据,也没有主备之分可以同时与业务系统通讯。Proxy节点数通常≥2,根据业务实际需求进行动态扩展,并且前端需要部署负责均衡保证节点之前负载均衡。
- Proxy层存储和处理数据库元数据,负责语法和语义解析。在分布式场景下,还需要处理分布式事务、维护全局自增字段、分布式SQL语句的下推和汇聚等。
- 配置管理决策调度集群,是由Zookeeper、Scheduler、Manager等组件组成。集群管理调度组件满足多数派选举通常需要奇数台,以基于raft协议实现对实例高可用切换的第三方选举。
- GTM(Metacluster):提供分布式事务全局一致性的事务管理器,主要由Metacluster中心时钟源为事务的开启、提交阶段提供一个全局唯一且严格递增的事务时间戳以及事务管理器(TM)组成,为了提高并发效率TM模块目前内置于计算层。
- 运维支撑系统,是由OSS运营调度管理模块、监控采集与分析模块、赤兔管理系统组成。
以上组件共同构成了TDSQL分布式数据库的整体架构,实现分布式实例和集中式实例在数据库集群中的混合部署,并提供了扩展性、高可用性以及运维功能支持。
1.7.1 存储引擎
TDSQL for MySQL提供不同的存储引擎,包括InnoDB版本和TDStore版本。InnoDB版本是采用InnoDB作为数据库存储引擎,也是MySQL默认的存储引擎;TDStore版本是腾讯云自研的敏态存储引擎,兼容MySQL标准协议,专为适配金融级敏态业务而设计。
TDStore引擎采用存储和计算分离的结构,包括计算节点、存储节点和管控节点,计算层和存储层的节点均可根据业务需求独立弹性扩缩容。TDStore存储层基于LSM-Tree + SSTable结构存放和管理数据,具有较高的压缩率,能有效降低海量数据规模下的存储成本。对比InnoDB存储引擎,TDStore版最高可实现高达20倍的压缩率,单实例可支撑EB级别的存储量。
1.7.2 主备节点同步复制
由于MySQL原生的主备节点之间的半同步复制技术存在异步退化、relay log无法保证实时落盘以及等待Slave返回ACK工作线程处于阻塞状态等问题,TXSQL对主备节点的同步复制进行了优化:
- Master等待Slave ACK超时时,返回给客户端失败,不会退化为异步复制,保证了主备数据的强一致性;
- 采用组提交的方式,增加rpl_slave_ack_thread线程,循环取出io thread接收到的binlog name和pos等信息,且只处理最后一个;
- 采用线程池+业务线程异步化,在Master等待Slave ACK的过程中将会话保存起来,然后线程切换到其他的会话处理,不用无谓的等待;
TXSQL的强同步机制,主机等待至少一个备机应答成功后才返回客户端成功,保证了数据的一致性,满足金融级的高可用要求。同时采用并行多线程和组提交技术,大幅提升主备复制的性能。
如上图所示客户端写请求提交后,线程池分配连接处理请求,但是并没有立即返回给客户端,而是将这部分信息保存在内存会话信息中。Master发起主备同步请求,接收备机收到binlog的ACK请求,当接收到备机日志落盘的ACK返回后,主节点的工作线程唤起刚刚保存的会话,执行后半段的提交操作,并将结果返回给客户端。因此在Master节点开启了两组线程:接收备机ACK应答线程(Dump ACK Thread)和唤醒hang住的客户端连接线程(User ACK Thread)。
1.8 各数据库存储类型对比
以上数据库从架构类型上分为集中式和分布式,集中式架构包括PolarDB和openGauss、分布式架构包括OceanBase、PolarDB-X版本、GaussDB、GoldenDB、TiDB和TDSQL。其中在存储类型、存储类型和高可用协议上各不相同:
- 存储类型:PolarDB使用的是主备节点集中式存储、openGauss则是本地存储模式,主备节点是不同的存储;OceanBase和TiDB是严格意义上的分布式存储,而GaussDB、GoldenDB和TDSQL从应用角度是表数据分布在不同的实例,只是这个分片按照实例的维度,不是原生分布式按照更小的region维度。
- 存储引擎:OceanBase数据库是基于LSM-tree存储引擎、TiDB基于RocksDB引擎、PolarDB、GoldenDB和TDSQL都是基于InnoDB存储引擎,只是TDSQL又自研了TDStore存储引擎。OpenGauss和GaussDB都是基于PostgreSQL内核自研出UStore和MOT内存引擎。
- 高可用:副本的高可用算法,OceanBase、PolarDB-X、OpenGauss和GaussDB都支持Paxos协议、TiDB是基于Multi-Raft协议实现的、GoldenDB和TDSQL则是主备节点复制、PolarDB由于是集中式存储,通过存储级别的复制保证了高可用性。
参考资料:
- https://www.oceanbase.com/docs
- https://help.aliyun.com/zh/polardb
- https://docs-opengauss.osinfra.cn/zh/docs/5.0.0/docs
- https://support.huaweicloud.com/fg-gaussdb-dist/gaussdb-18-0144.html
- https://www.goldendb.com/#/docsIndex
- https://docs.pingcap.com/zh/tidb/stable/overview
- https://cloud.tencent.com/document/product/557