引入
与Oracle在华大规模裁员相比,国产数据库好消息连连,2019年可以说是国产数据库年。举几个例子,华为推出GaussDB,并成功上线招商银行/工商银行核心系统;中信信用卡系统运行在中兴GoldenDB之上;Oceanbase登顶TPC-C….
虽然近些年国内外云计算如火如荼,但如果你关心IT新闻的话会发现,国产数据库针对的并不是云,而是on premise,特别是金融业(《盘点2019:对国产数据库的一点观察和总结》)。本文主要分析一下on premise 数据库,特别是分布式数据库。
现在的分布式数据库基本上都借鉴Google的spanner/F1论文,采用paxos/raft协议来保证数据的强一致性,所以从架构上来都类似,可以明显区分出计算节点和存储节点。但Oracle Exadata脱胎于集中式的共享存储,令人惊讶的是,它的架构与这些分布式数据库不谋而合。
Oracle
Oracle是国产数据库最大的竞争对手,也是大家相对熟悉的数据库,让我们从它入手。 下图是一个经典的Oracle体系架构图。
图 1
硬件上它由至少2台服务器以及共享的存储组成,它们之间的通讯通过高速网络完成,软件上,一般是Oracle RAC。
在2008年,Oracle推出了数据库一体机Exadata,它的架构如下图:
图 2
共享的集中式存储变成了多个普通的x86存储节点,它和后面我们提到的share nothing的国产分布式数据库有很多相似之处。
关于Oracle Exadata的详细文档,可以参考《Oracle Exadata技术白皮书》,这里只对几个主要组件做一个大概介绍。
- DBServer:其实就是一个Linux,它采用的是OEL(Oracle Enterprise Linux)而不是Redhat,是数据库软件和实例运行的地方,除了OS必须是Linux(其实也可以是SPARC sunos)外,它和普通经典的Oracle RAC基本一样。
- Network:一体机自带Infiniband网络,这是一种高性能的网络,具体可以参考百科。
- Storage cell:存储节点,它可以配置普通的硬盘,也可以配置高性能SSD。简单的理解就是Linux上运行了一个cellsrv服务,该服务只针对Oracle软件服务,这也Exadata最大的亮点。
TIDB
TiDB是近几年很火的分布式数据库,它的架构最近似Oracle,下图和主要组件的解释来自官网。
图 3
TiDB
TiDB 是无状态的,推荐至少部署两个实例,前端通过负载均衡组件对外提供服务。当单个实例失效时,会影响正在这个实例上进行的 Session,从应用的角度看,会出现单次请求失败的情况,重新连接后即可继续获得服务。单个实例失效后,可以重启这个实例或者部署一个新的实例。
PD
PD 是一个集群,通过 Raft 协议保持数据的一致性,单个实例失效时,如果这个实例不是 Raft 的 leader,那么服务完全不受影响;如果这个实例是 Raft 的 leader,会重新选出新的 Raft leader,自动恢复服务。PD 在选举的过程中无法对外提供服务,这个时间大约是3秒钟。推荐至少部署三个 PD 实例,单个实例失效后,重启这个实例或者添加新的实例。
TiKV
TiKV 是一个集群,通过 Raft 协议保持数据的一致性(副本数量可配置,默认保存三副本),并通过 PD 做负载均衡调度。单个节点失效时,会影响这个节点上存储的所有 Region。对于 Region 中的 Leader 结点,会中断服务,等待重新选举;对于 Region 中的 Follower 节点,不会影响服务。当某个 TiKV 节点失效,并且在一段时间内(默认 30 分钟)无法恢复,PD 会将其上的数据迁移到其他的 TiKV 节点上。
可以简单地和Oracle做个对比:
- 1. 概念的对齐:
- TiDB=OracleDB Server
- PD=Oracle Clusterware
- TiKV=Storage Server
- 2. 在图中PD是单独安装的,如果和TiDB安装在一起呢,是不是和Oracle RAC更接近?
- 3. TiKV中提到Region的概念,它和Oracle ASM AU的概率也比较接近。
- 4. 不过Oracle AU的缺省大小是1M,显然不太适应时代的发展。
- 5. 图中右边部分被忽略,Oracle不需要额外组件支持OLAP。
Oceanbase
Oceanbase组件概念:
图 4 – Oceanbase组件,原来于云栖社区
OceanBase由如下几个部分组成:
客户端:用户使用OccanBase的方式和MySQL数据库完全相同,支持JDBC、C客户端访问,等等。基于MySQL数据库开发的应用程序、工具能够直接迁移到OceanBase。
RootServer:管理集群中的所有服务器,子表(tablet)数据分布以及副本管理。RootServer一般为一主一备,主备之间数据强同步。
UpdateServer:存储OccanBase系统的增量更新数据。UpdateServer一般为一主一备,主备之间可以配置不同的同步模式。部署时,UpdateServer进程和RootServer 进程往往共用物理服务器。
ChunkServer:存储OccanBase系统的基线数据。基线数据一般存储两份或者三份,可配置。 MergeServer:接收并解析用户的SQL请求,经过词法分析、语法分析、查询优化等一系列操作后转发给相应的ChunkServer或者UpdateServer。如果请求的数据分布在多台ChunkServer上,MergeServer 还需要对多台ChunkServer返回的结果进行合并。客户端和MergeScrver之间采用原生的MySQL通信协议,MySQL客户端可以直接访问MergeServer。 OceanBase支持部署多个机房,每个机房部署一个包含RootServer、MergeServer、ChunkServer以及UpdateServer 的完整OceanBase集群,每个集群由各自的RootServer负责数据划分、负载均衡、集群服务器管理等操作,集群之间数据同步通过主集群的主UpdateSever往备集群同步增量更新操作日志实现。客户端配置了多个集群的RootServer地址列表,使用者可以设置每个集群的流量分配比例,客户端根据这个比例将读写操作发往不同的集群。
再翻译一下,
- RootServer=ClusterWare
- UpdateServer = DBWR/LGWR
- ChunkServer=Storage server
- MergeServer=DB server
tablet是一个类似AU 和Region的概念。Oracle中AU是datafile的一部分,TiDB中Region和oceanbase tablet都是table的部分数据。
从文中描述中还可以看到所有的写操作都要经过UpdateServer。这是一个潜在问题?
在Oracle中有个DRM概念,每个对象都有一个master,针对这个对象的读写都要通过这个master来获得相应的权限。但DRM的bug很多,多个版本中都要求关闭这个特性。Oceanbase似乎将这个功能独立出来,将UpdateServer作为所有对象的master并负责所有的写,以避免相应问题,但显而易见也可能引入了另外一个瓶颈。
如有可能,是不是在多租户环境把另外一个备updateserver利用起来,甚至是部署多个updateserver为不同的租户服务?
单活rootserver不是一个问题,在大部分集群包括Oracle RAC中也有相应的OCR/PE master概念,重要的是切换时间。
GaussDB
GaussDB 架构图:
图 5 – GaussDB 架构图 (来源于《GaussDB 200 一体机 6.5.1 产品文档》)
简单明了
- DataNode=Storage
- DBserver = coordinator Node(CN)
- Cluster= Cluster Manager
GaussDB中没有类似AU/Region/tablet这样的概念,它的同步是通过主备DN完成的。副本的同步单位是DN,这个颗粒度很大。一个DN其实就是一个数据库,日志和数据存在于同一个节点。为防止一个DN崩溃的时候数据丢失,主备最好采用强同步,类似用Oracle中的最大保护模式,众所周知这种模式会导致性能下降,并增大系统的不可用性。
TDSQL
腾讯TDSQL 架构图:
图 5 – TDSQL 架构图 (来源于《腾讯专有云数据库TDSQL白皮书 V2.0》)
l 物理节点组(SET):由 MySQL 、 监控和信息采集(TAgent)组成,通常情况下
- SET 默认采用一主多从架构,通常部署在跨机架物理服务器中;
- 每个节点(DataNode)都部署TAgent并实时向决策集群上报,提供决策依据
l 决策集群:TzooKeeper它是TDSQL提供配置维护、选举决策、路由同步等,并能支撑数据库节点组(分片)的创建、删除、替换等工作,并统一下发和调度所有 DDL (数据库模式定义语言)操作, 通常决策集群需要采用奇数台,实际部署的时候应 大于等于 3 组并跨机房部署 。
l 接入网关集群(OLTP Proxy):在网络层连接管理 SQL 解析、分配路由 。请注意,OLTP Proxy并非腾讯云网关 TGW 集群 。
1. OLTP Proxy 通常与 MySQL 混合部署,也可以部署在不同物理设备中
2. 从配置集群(TzooKeeper)拉取数据库节点(分片)状态,提供分片路由,实现透明读写;
3. 记录并监控 SQL 执行信息,分析 SQL 执行效率,记录并监控用户接入信息,进行安全性鉴权,阻断风险操作;
4. OLTP Proxy 通常可以直接访问,但仍然建议前端部署,需部署可提供负载均衡能力网关并由网关对用户提供唯一虚拟IP服务。
比较容易提取出我们关心的几个组件
- 物理节点组(SET):由属于主从关系的多个DataNode组成,等同于Oracle Storage cell。
- 决策集群(TzooKeeper):类似于Oracle集群软件。
- 接入网关集群(OLTP-Proxy):可以简单理解为DBSever。
从图中可以看到类似于GaussDB的数据节点主从关系的架构,但TDSQL采用了自研的MySQL协议的异步多线程强同步复制方案(Multi-thread Asynchronous Replication MAR),性能远优于Mysql/Mariadb。
详细的技术解释可以参考《腾讯自主可控数据库TDSQL的架构演进》。
达梦DM
达梦数据库架构图:
图 7 – 达梦数据库架构图 (来源于《DM8大规模并行处理MPP》)
DM8 MPP不能明显区分DBServer和数据节点,MAL类似于Oracle Cache Fusion,将多个普通DM数据库融合在一起的。
上图不包含数据节点的备份,其高可靠环境中推荐对EP采用交叉守护的方式。比较接近GaussDB和TDSQL。
从手册中可以看到节点扩展比较复杂,针对不同表类型和表进行专门的sql进行重分发。参考5.2.2 动态增加节点。
对比表格
把上面内容做个表格
|
Oracle/Exadata |
GaussDB |
Tidb |
Oceanbase |
TDSQL |
DM |
---|---|---|---|---|---|---|
存储节点 |
Cell/Exadata |
Datanode(DN) |
TiKv server |
Chunk server |
Set(DataNode) |
EP |
存储软件 |
cellsrv |
pg |
rocksdb |
|
Mysql/mariadb |
DM |
计算节点 |
Db server |
Coordinator Node(CN) |
TiDB server |
MergeServer |
Oproxy |
EP |
副本单位 |
ASM AU(4M) |
DN |
Region(96M) |
Tablet(256M) |
DN |
EP |
集群 |
RAC |
Cluster Manager(CM) |
PD cluster |
Root server |
Tzookeeper |
DMMPP |
总结
Oracle RAC对网络延时有严格要求,在现实中很少见到异地双活/多活的RAC,而且从Oracle Exadata手册中,Infiniband 的最长的距离是10米,这也导致异地双活成为不可能。而基于paxos/raft协议的分布式数据库是可以的,甚至是两地三活,n地n活。
在最新版本的Exadata中,Oracle已经用100Gb RoCE替代了Infiniband,但异地副本多活并未提及。
在副本颗粒度上而言,Oracle,TiDB 和oceanbase采取的是KV存储的模式。
这里熟悉Oracle读者可能比较困惑,Oracle从来没有提过KV啊。来看Oracle中的2个概念。
- Rowid:是一个伪列,用来定位Oracle任意一条记录的唯一地址,它主要包含了对象编号,文件编号,块编号,行编号。
- AU:AU是Oracle ASM 磁盘组中的最基本单位,一个或多个AU组成一个extent,一个或多个ASM extent,一个或多个ASM extent组成了一个ASM文件,一个或多个ASM文件组成tablespace。
再看看TiDB中的Region,存储数据的基本单位是 Region,每个 Region 负责存储一个 Key Range(从 StartKey 到 EndKey 的左闭右开区间)的数据。
简单看table的Key:TiDB 对每个表分配一个 TableID,每一个索引都会分配一个 IndexID,每一行分配一个 RowID(如果表有整数型的 Primary Key,那么会用 Primary Key 的值当做 RowID),其中 TableID 在整个集群内唯一,IndexID/RowID 在表内唯一,这些 ID 都是 int64 类型。
每行数据按照如下规则进行编码成 Key-Value pair: Key: tablePrefix_rowPrefix_tableID_rowID Value: [col1, col2, col3, col4]
这个key不就是rowid么?
GaussDB/TDSQL/DM副本是DataNode级别的,它并没有形成Google论文中分布式存储的架构,这增加单点故障的概率。另外,以DN为单位的副本的设计没有天然分片特性,所以他们都引入了shardkey的建表语法。
GuassDB
create table T1(c1 INT,C2 INT) distribute by hash(c1);
TDSQL
create table test1 ( a int, b int, c char(20),primary key (a,b),unique key u_1(a,c) ) shardkey=a;
DM
CREATE TABLE T1(C1 INT,C2 INT) DISTRIBUTED BY HASH(C1);
单机版本和分布式版本建表语法是不一样的,给用户迁移到分布式带来额外的工作。从达梦的手册来看,增加节点操作是个很繁琐的操作。删除节点?只在TiDB文档中明确提到。
副本的粒度还带来分布式事务实现的不同。在DN粒度下,任何一个事务都可能变成分布式事物,采用两阶段提交,因为每个DN是作为一个独立的关系型数据库存在的。
KV模式是不是更优秀,由于本人学识有限,不做过多讨论,另外有些大名鼎鼎的数据库MongoDB sharding/Oracle Sharding采用的也是DN方式。
TiDB存储(TiKV)采用了rocksdb,从Oracle Exadata的发展来看,存储这一层可以做的文章还很多,比如flashcache,flashlog,cell2cell 数据传输等。采用racksdb是否放弃了这一层?
Oceanbase集群中只有一个updateserver,它有可能是一个瓶颈,而且很容易让人联想到1写n读这种架构,希望未来可以扩展。
华为的优势在于软硬件都有,它的GuassDB在鲲鹏芯片上应该运行得最好,能一站式满足自研可控需求。
TDSQL和GuassDB有类似的主备同步问题,但这2家公司都是有自主的分布式存储产品,是否可以用来解决主备存储节点强一致的缺点。
DM是一家传统的国产数据库企业,圈外人对其了解不多,但它其实是政企圈内的老大。分布式产品成熟度有待检验,文档是国内数据库厂商中最完整最诚实的。
题外话,本人并未有国产数据库使用经验,在网上翻来覆去找到最多的是各个厂商的宣传资料,而对产品运维开发这些方面讨论很少。产品好坏只是一方面,另一方面是生态的培养建立。希望当大家真正使用上国产数据库的时候,寻找资料会像Oracle,MySQL,PG那样方便。
Links
关于作者
张黎钦,原Oracle系统架构和性能服务团队成员,DBA,高级技术经理。他是构建Oracle 云服务中的高可用数据库服务的主要架构师之一。
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/310148.html