自研一款共享集群数据库,有多难?
共享集群数据库管理系统是一种单库多实例的多活数据库管理系统,用户连接任意实例都可以访问同一个数据库,具备透明多写、高可用、高性能等特性。共享集群技术因其开发难度高,一直被国外垄断,也被称为数据库领域的“塔尖”技术。
2023 年,YashanDB 正式发布共享集群产品形态,实现了国产数据库在高端领域“零”的突破。本次共享集群系列文章将围绕 YashanDB 共享集群,深入探讨架构原理、关键技术以及运维管理等核心内容。作为该系列的首篇,本文将全面而系统地介绍共享集群的架构,为用户提供一个全面的理解框架,为后续的学习和实践打下坚实基础。
背景与挑战
国内近十几年分布式数据库是个热点领域,但从今年北京的 DTC 会上来看,各大数据库厂商对其共享集群数据库都做了一定的介绍,共享集群这两年逐步又成为了热点话题,研发共享集群的厂商很多,类别也很多——云上共享集群、主备共享集群、多写共享集群,看上去 RAC 技术并不像十几年前所认知的是已经过时的技术。
这两年各大厂商又纷纷在共享集群上发力,可能主要有三方面原因:
一是潜在客户群体的需求。RAC 仍然是集中式数据库下的典型架构,在一般企业的 OLTP 关键业务场景下具备明显的优势。RAC 提供了强一致的应用透明多写能力,用户可以像使用单机数据库使用集群;同时提供了集群高可用能力,只要有存活节点集群仍可提供正常的服务。
二是数据库厂商技术积累的结果。国内数据库技术发展有三十余年,各大数据库产商在数据库内核领域、集群领域都有了一定的突破和积累,具备了做 RAC 架构的基础。
三是新型硬件环境要求。国内金融、政企、电信等领域近几年都在做基于新硬件的数据库系统升级,对共享集群有一定的诉求,目前国内可以做到平替的数据库产品有限。
尽管如此,国内发布共享集群产品的数据库厂商仍然是少数,主要原因还是共享集群架构的复杂性,以及内核架构的适应性。
YashanDB 之所以在其自研内核基础上可以快速推出共享集群也与此有关系,主要有两方面原因:
一方面,YashanDB 采用了自研内核引擎技术路线,在数据库内核架构初期在事务引擎设计、MVCC、表索引存储等各个方面为未来的共享集群产品形态打好了良好的基础,YashanDB 内核架构是天然适合演进共享集群的。
另一方面,YashanDB 通过自研的聚合内存技术、集群文件系统、集群管理服务共同构建共享集群的架构体系。
YashanDB 共享集群架构
YashanDB 共享集群形态(YashanDB for Cluster),是基于共享存储的多活集群,提供计算/存储扩展和金融级高可用能力。通过自研 Cohesive memory(聚合内存)核心技术,协同集群数据库各实例之间数据类资源的读写访问以及各种非数据类资源的并发控制。
图 1 YashanDB 共享集群架构图
YashanDB 共享集群具备三大特点:
应用透明性:应用透明层面,用户层面无感知,用户连接任意实例可以访问并操作数据库所有数据,可执行全量的 DDL、DML 操作。具体而言,单机支持的协议、驱动、SQL 兼容性、功能,集群下使用都是没问题的。
高性能性:每个节点对外提供的读写性能是完全对等的,多节点下的性能提升是线性的。
极致高可用:YashanDB 从多个维度塑造高可用性,有集群管理软件层面的高可用仲裁,数据库实例的自动故障恢复,自研文件系统层面的存储高可用,集群间的高可用等。
聚合内存技术 Cohesive memory
聚合内存是共享集群架构的基础能力,YashanDB 通过对数据缓存、数据字典缓存、锁等各类内存资源进行全局资源抽象,采用全局一致性哈希算法在多个实例间均衡管理全局资源,任一资源元数据在集群内具备唯一性。每个数据库实例管理一部分全局资源的元数据信息。
图 2 聚合内存组件关系
聚合内存通过以下关键组件完成全局资源的协同与访问:
全局资源目录(GRC,Global Resource Catalog),提供全局资源元数据信息管理、访问能力,并通过全局请求排队机制管理数据块以及锁资源的请求,提供全局资源的并发访问控制。
全局缓存服务(GCS,Global Cache Service),负责完成数据块在多个实例间的传输与失效,提供强一致的并发访问、修改能力。
全局锁服务(GLS,Global Lock Service),提供集群下的全局并发控制的锁服务,主要包括数据字典锁、内存锁等。
内部通信服务(ICS, inter-connect serivce),提供集群内部消息交互服务,是集群内部缓存融合的基础组件。
图 3 聚合内存技术关键角色职责图
以数据块融合为例,聚合内存技术定义了三种关键的角色:
请求者:需要该数据块的实例。
协调者:负责该数据块的状态信息管理的实例,它知道该数据块的拥有者是谁,以及拥有者当前持有的锁类型,所有数据库实例对该数据块的请求都在协调者这里排队,依次处理。
拥有者:该数据块的实际拥有实例(指全局缓存中持有该数据块的最新版本的数据库实例),拥有者可能是一个写锁持有实例,也可能是多个读锁持有实例。
一次典型的数据块访问,需要三个角色配合完成,请求结束后请求者变成新的拥有者。
实际运行期,单次数据块请求涉及三种逻辑角色可能运行在最多三台不同的物理主机上,通过最多不超过四次网络消息完成。
崖山集群服务 YCS
崖山集群服务(YCS,Yashan Cluster Service)是 YashanDB 自研的集群管理软件,提供节点管理、资源管理、资源监控和集群高可用仲裁等能力,为 YashanDB 共享集群的稳定运行保驾护航。
图 4 YCS 架构图及心跳策略
YCS 采用对等架构设计,每个节点部署一套 YCS 服务,每个 YCS 管理一个 YashanDB 实例以及崖山文件系统 YFS 实例。
YCS 通过共享存储 YCR 盘获取集群的节点、资源信息等,并与其他节点建立通信,管理资源等。同时各节点的 YCS 通过定期读写 Voting Disk 进行磁盘心跳。
YCS 采用了多种心跳策略,来确保及时感知到节点和资源状态变化,在出现异常时进行资源处理或脑裂仲裁。
崖山文件系统 YFS
崖山文件系统(YFS,Yashan File System)是 YashanDB 自研的用户态存储服务组件,提供了文件系统和磁盘组管理能力。
图 5 YFS 架构及层级管理
其重点包括了两部分:文件管理和卷管理。其有三大特点:
高性能
YFS 绕过系统缓冲对磁盘设备进行直接 IO,以同步方式写入块设备和直接读取块设备,达到接近裸设备的性能指标。
在共享集群部署模式下,YFS 管理挂载在各集群节点的共享磁阵,对外提供一致和高效的文件管理接口。
实现共享集群多节点并发读写,充分释放集群系统的计算能力。
兼容性
yfscmd 客户端:进行基本的文件管理操作,与一般文件系统类似,例如目录或文件的创建、删除等。
API 接口:YFS 还提供丰富的 API 接口,客户程序(例如 YashanDB)通过调用这些 API 执行存储管理,实现组件可插拔。YFS API 兼容一般文件系统的大多数操作。
高可用性
数据高可用:YFS 通过磁盘组(diskgroup)的方式管理磁盘设备,内部通过多个故障组和多副本机制,支持数据高可用。可配置的冗余级别,方便用户根据业务特征决定数据冗余度。
服务高可用:当集群节点数发生变化或个别节点异常退出时,YFS 可进行自动调整,恢复服务能力。
一致/可靠性:YFS 内部采用了与 DB 相同的 redo 和 checkpoint 机制,用于保证 YFS 状态的一致性和可靠性,因此当整个集群发生异常重启时,系统能够自动从异常中恢复服务。
YashanDB 集群关键内核技术
前面也提到了 YashanDB 内核是天然适合共享集群的,在最初的内核架构设计选型时,在 MVCC 技术、快照技术以及事务引擎架构充分考虑了未来的共享集群形态。
原地更新块级 MVCC 技术
YashanDB 综合考虑了三种 MVCC 方案:Append-only 行级 MVCC、原地更新行级 MVCC、原地更新块级 MVCC。结合每种 MVCC 方案的优劣,YashanDB 采用了原地更新的块级 MVCC 技术。
图 6 三种 MVCC 技术架构图
Append-only 行级 MVCC:其特点是历史数据版本和当前数据版本在数据块内混合存储。看上去管理简单,实际上带来问题却不少:
空间膨胀。随着数据的变更,历史版本的垃圾数据会越来越多,存储性能都带来了下降。
扫描需要跳过那些历史版本的数据,查询性能受到影响。
随着历史版本累积,需要设计一套复杂的垃圾数据回收机制,代价巨大。
即使更新仅更新行的某一个列,也需要将整个行拷贝。
原地更新行级 MVCC:其和 Append-only 的区别是将历史版本挪到了独立的 Undo 表空间进行管理,可以有效的解决空间膨胀问题。但这套方案同样存在问题:
行级 MVCC 意味着行上要存储事务信息以及 UNDO 地址,空间浪费严重。
其次其一致性读结果是无法复用的,每次读取一行都需要访问当前版本页面,会造成当前版本大量的读写冲突。
YashanDB 采用了原地更新块级 MVCC,在数据块中设计了物理的事务槽位 SLOT,一致性读以数据块为单位进行,其优点有:
采用原地更新方式,历史版本存储在 Undo 表空间内,数据不膨胀。
行内不需要存储事务信息以及 UNDO 地址,避免空间浪费。
查询一致性读页面,只访问一次当前版本页面,减少当前版本页面上的读写冲突。
一致性页面按需缓存,重复利用。
以数据块为单位的 MVCC 还有个优点就是集群场景下按更大力度的数据块请求,而不需要按行请求,减少交互次数。
数据块内设计物理事务槽位 XSLOT,在缓存融合中事务信息天然随着页面的传输而转移,不需要额外的全局内存锁控制,同时减少实例间的信息交互,提升访问效率。
基于时间戳的快照技术
另外一个关键核心的技术选型就是快照技术方案。YashanDB 技术选型对比了两种快照方案,一种是基于活跃事务的快照技术,另外一种是基于时间戳的快照技术。
图 7 基于时间戳的快照技术架构图
基于活跃事务的快照技术的特点是:
每个会话每条语句查询都需要加全局的锁,来获取一致性的快照,这种快照更类似于一个活跃事务的数组,需要锁定所有会话并记录查询这一时刻的活跃事务 ID,在高并发下容易成为全局瓶颈。
使用快照进行可见性判断时,需要查表判断行上的事务与快照中事务的关系,在活跃事务列表中则不可见,大并发下影响判断效率。
此外当这套设计扩展到共享集群或者分布式架构下时,全局快照的维护和生成的代价会急剧上升,严重影响了系统的性能。
YashanDB 采用的是基于时间戳的轻量级快照技术,其特点如下:
采用基于时间戳的快照机制下,快照的管理非常简洁,仅为一个时间戳,没有全局查询锁。
事务提交获取系统最新的时间戳对应的 SCN,作为事务提交的 SCN。
查询通过获取系统 SCN 作为查询的快照,通过比较 SCN 大小判断可见性,大并发下执行效率是非常高的。
并且这套方案在扩展到共享集群或分布式架构下不需要维护全局事务快照,系统具备极致的扩展性。
去中心化事务引擎技术
事务引擎的设计决定了多个实例是不是可以做到真正的对等,是不是可以做真正的线性扩展。
对于共享集群架构下,数据是完全共享的,此时多实例之间必然存在事务的交互。而这种架构下的事务一般有两种方案,一个是中心化事务设计思想,另外一种是去中心化事务设计。
图 8 去中心化事务技术架构图
中心化事务设计的特点是,其需要存在一个集中的事务控制节点,甚至集中的锁控制节点。
所有的事务启动、提交等事务状态都需要去控制节点上申请,并同步到其他节点,需要做到事务状态全局的实时同步。
控制节点上事务处理高负载,多节点扩展性较差。
非控制节点上的事务都需要去控制节点上申请,导致集群下多节点无法做到真正对等,非控制节点性能较差。
YashanDB 采用的是去中心化的事务设计,其特点如下:
事务无中心节点,各实例事务 ID 具备全局唯一性,事务本地生命周期管理,不受其他实例影响。
所有实例完全对等,多节点扩展性好。
通过广播 SCN 以及语句查询同步 SCN 来实现多节点下的 SCN 同步,确保多实例间并发访问事务的一致性。
如上文介绍,共享集群研发的难度在于它的存储组织以及各实例间的复杂交互,这会涉及到核心交易系统数据存储、事务处理等核心底层机制。如果在开源技术的基础上去开发,受限于其架构和技术路线,往往很难实现共享集群这一形态。
YashanDB 对存储等底层机制和核心技术完全掌控,通过这些核心方案的架构选型以及能力构建,能够快速构建共享集群架构并进行产品化落地,为用户提供对等透明多写能力,应用连续性以及高可用能力,提供在高端核心场景对国际主流数据库系统 1:1 平替的能力。
本篇是共享集群系列文章的第一篇技术干货,接下来我们还会深入讲解 YashanDB 共享集群高可用核心技术、文件系统 YFS 等。欢迎关注“YashanDB”公众号,持续关注我们系列技术文章!也欢迎广大数据库技术爱好者加入 YashanDB 官方技术交流群,共同探讨数据库前沿技术~
评论