前言
CynosDB是新一代分布式数据库 100%兼容MySQL和PostgreSQL支持存储弹性扩展一主多从共享数据性能更是超越社区原生MySQL和PostgreSQL。 CynosDB采用share storage架构其弹性扩展和高性价比的基石则是CynosDB File System(简称CynosFS) 一款腾讯云自研的用户态分布式文件系统。本文旨在从整体上讲述CynosDB和CynosFS的核心架构设计。
挑战与应对
CynosDB是公有云原生架构的其核心思想是在资源池化的基础上实现公有云高性价比、高可用性以及弹性扩展等诸多优势。实现资源池化的最大技术挑战是高效、稳定的弹性调度能力该能力也是公有云产品高可用性的基石。计算、网络和存储是公有云三大类Iaas产品前面两类都有比较成熟的弹性调度架构唯独存储产品例外。究其根本还是数据调度的代价太高。数据库是典型的计算+存储的产品要做到资源池化需要l存储与计算分离这样计算资源(主要包含CPU和内存)就可以使用现有成熟的容器、虚拟机等技术实现资源池化l分布式存储将数据分割成规格化的块 引入分布式调度系统实现存储容量和IO的弹性调度从而实现存储资源的池化
那么对于数据库产品来说是否有现成架构可以很好的满足以上两个需求呢。我们发现虚拟机+分布式块存储(云盘)的方案非常合适 目前主流公有云平台也都有非常成熟的产品。腾讯云今年早些时候推出的MySQL基础版以及AWS上的RDS都是基于这种架构。 图1简单描述了这种架构
图1
但该架构有如下不足
l网络IO重可以看到就1个数据库实例就有大量数据需要写到云盘这些数据主要包括WAL LOG、页数据、防止页部分写的Double Write或者Full Page Write。除此之外云盘还要将这些数据做多个备份l主从实例不共享数据一方面浪费了大量存储另一方面进一步加重了网络IO
这些不足导致基于该架构的数据库产品在系统吞吐能力上无法与基于物理机部署的主从架构竞争而且延迟也受到很大的挑战这对OLTP类业务的影响非常明显。 同时每个数据库实例都单独拥有一份(实际可能是2-3份)存储成本也很高。
CynosDB针对这两个不足采用了如下设计l日志下沉 WAL LOG从逻辑上已经包含了数据的所有变动 CynosDB将WAL LOG下沉到存储层数据库实例就只需要将WAL LOG写到存储层不再需要写页数据(页数据以及Double Write或Full Page Write) 同时这个WAL LOG也作为RAFT协议的日志来完成多个数据备份的同步进一步减少了网络IO。l主从实例共享数据 CynosDB的主从实例共享共一份存储数据进一步减少了网络IO 同时极大的减少了存储容量
循着这两个解决思路我们对传统基于云盘的架构进行优化就有了CynosDB如下架构
图2
图中组件包括lDB Engine数据库引擎支持一主多从。
lDistributed File System用户态分布式文件系统主要提供分布式的文件管理负责将文件的读写请求翻译为对应的BLOCK读写lLOG/BLOCK API Storage Service提供的读写接口对于读写请求有不同处理n写请求将修改日志(等价于WAL LOG)通过LOG API发送到Storage Servicen读请求直接通过BLOCK API读取数据lDB Cluster Manager负责一主多从DB集群的HA管理。lStorage Service负责日志的处理、 BLOCK数据的异步回放、读请求的多版本支持等。 同时还负责将WAL LOG备份到Cold Backup StoragelSegment(Seg) Storage Service管理数据BLOCK和日志的最小单元(10GB) 也是数据复制的实体。图中同样颜色的3个Seg实际存储同一份数据通过一致性协议(Raft)进行同步我们叫做SegmentGroup(SG) 。lPool多个SG从逻辑上构成一个连续的存储数据BLOCK的块设备供上层的DistributedFile System分配使用。 Pool和SG是一对多的关系。lStorage Cluster Manager负责Storage Service以及Segment Group的HA调度 以及维护Pool和SG的对应关系。lCold Backup Service接收到WAL LOG后进行增量备份根据增量备份可以灵活的生成全量备份和差异备份
可以看到上面中除了DB Engine和DB Cluster Manager外的所有模块构成了一个与数据库引擎无关的用户态分布式文件系统我们命名为 CynosFS。
日志下沉和异步回放
这里CynosDB借鉴了AWS Aurora论文中日志即数据库的思想将WAL LOG下沉到Storage Serivce计算层只写WAL LOG而由Storage Serivce异步地将WAL LOG应用到对应的BLOCK上在减少写IO的同时也是Storage Serivce提供MVCC读能力的基础。而MVCC是主从节点共享存储的基础。 Storage Serivce中的数据和日志都是以Segment为单元进行管理的 图3描述了写的基本流程
图3
1.接收到更新日志写到磁盘并行发起第2步
2.发起RAFT日志复制
3.RAFT多数派提交成功返回写日志成功
4.异步的将日志记录挂载到对应数据BLOCK的更新链上
5.合并更新链中的日志记录到数据BLOCK
6.将日志备份到冷备系统
7.回收无用日志
这里第4步会对更新的数据BLOCK形成1个更新链从而支持数据BLOCK多个版本的读进而提供MVCC能力。通过控制第5步的合并进度就可以控制MVCC的起始窗口。
同时CynosDB还将页面CRC等操作放到了存储服务中充分利用存储服务器的CPU资源
MVCC实现
CynosFS的MVCC能力是CynosDB一主多从架构的基础本小节会详细描述其运行机制。
首先我们引入一系列概念lMini-transaction(MTR) 就像数据库事务用来保证事务的ACID特性 MTR用来保证磁盘上页数据的ACID特性。举个例子 1个B+树的插入操作在造成节点分裂的情况下最多会修改3个数据页这3个数据页的修改需要当做1个事务来处理这就是MTR。数据库实例在磁盘上的数据是按照MTR为最小单元进行更新的
lWrite Ahead Log(WAL LOG) 关系数据库常用的保证数据一致性的技术。 WAL LOG是一个增量日志流水里面的日志记录(Log Records)保存了页面修改操作。 由于CynosFS是与具体数据库引擎无关的分布式文件系统其WAL LOG中记录的是对数据BLOCK的二进制修改是物理日志lLog Sequence Number(LSN) WAL LOG中每条Log Record都会有1个唯一标识的序列号从1开始按Log Record产生的连续单调递增。lConsistency Point LSN(CPL) 一个MTR可能对应多个磁盘数据页的修改相应的会产生多条日志记录这批日志记录中的最后1条(也就是LSN值最大的1条)标识为CPL这条日志记录对应了一个磁盘上的数据状态该状态表示1个MTR的完整应用也是MVCC的读一致性状态lSegment Group Complete LSN(SGCL) 1个数据库实例的数据页会分布到多个SG上 因此每个SG只会持有部分日志记录SCL表示该SG已经将所有小于等于SCL的日志记录持久化到磁盘上了。对于CynosFS来说 因为SG采用了Raft协议 SCL就是Raft的CommitIndex。lPool Complete LSN(PCL) 表示构成该Pool的所有SG已经将小于等于PCL的日志持久化到磁盘上。因为LSN是连续单调递增的这也要等价于中间没有空洞lPool Consistency Point LSN(PCPL) 不大于PCL的最大的CPL。逻辑上表示 已经持久化到磁盘的可提供MVCC读一致性的点。
写
首先主实例对所有数据页的修改都经过DistributedFile System的转换形成Pool级别的日志并附带连续单调递增的LSN分发到不同的SG。 SG会在完成Raft Commmit后推进自己的SGCL并返回主实例根据所有SG的完成情况推进PCL和PCPL。下面我们通过2幅图描述PCL和PCPL的推进过程
图4
首先该Pool由2个SG构成每个SG中有3个Segment存储同一份数据。当前有LSN为1~8的日志已经持久化到2个SG中其中1、 3、 4、 7在SG A上 2、 5、 6、 8在SG B上。这8条日志属于3个MTR分别是 MTR-x(1、 2、 3) MTR-y(4、 5) MTR-z(6、 7、 8) 其中3和5都是CPL表示MTR-x和MTR-y对应的日志已经全部持久化了 8不是CPL说明MTR-z后续还有日志记录。按照上面的定义此时PCL为8而PCPL为5
图5
图5中 MTR-z的1条日志CPL9被持久化到SG A按照定义此时PCL和PCPL都更新到了9。
读
这里主要指从实例的读流程。从实例具有自己的内存数据在主实例更新了数据后需要同步更新从实例的内存数据否则会出现不一致的情况。主实例会将日志记录以及最新的PCPL值推送给从实例。因此从实例的PCPL值会较主实例有所延迟。这个PCPL值决定了从实例上所有事务能读到的最后1个MTR。 同时为了减少从实例的延迟主实例可能不等PCPL值推进先把日志推送到从实例因此从实例需要保证大于本地PCPL值的那些日志不被应用。从实例对这些更新日志的处理方式有两类如果对应修改的数据页在Buffer Pool中则应用此日志更新到对应数据页否则直接丢弃。最后从实例上的读事务在每次访问数据页时(不管直接从Buffer中获取到还是从Storage Service获取) 因为可能一次读入多个页所以需要取当前的PCPL值为Read Point LSN(简称 RPL) 用RPL达成到一致性读(因为PRL是一个PCPL值其一定能保证MTR的完整性) 。 CynosDB支持一主多从每个从实例上都会有很多读事务这些读事务都具有自己的RPL所有这些RPL中最小的我们称之为Min-RPL(简称 MRPL) 那么在MRPL和PCPL之间可能会有多个CPL点不同读事务的RPL可能在这个区间的任何1个CPL点上。因此Storage Service要能支持读取在这个区间内任意CPL点的数据也就是MVCC。 CynosDB使用数据页+更新日志链的方式来实现。
最后让我们回到图3 SG需要定期回收无用的日志记录我们可以看到所谓无用的日志记录就是其LSN值小于MRPL的那些。而大于等于MRPL的那些日志因为要用来支持MVCC所以必须保留。
事务提交
一个数据库事务由多个MTR组成最后1个MTR的最后1条日志的LSN(必然也是个CPL)我们称之为Commit LSN(简称 CLSN) 。为了提升效率 日志到Storage Service的推送采用异步流水线的方式 同时按照SG进行分组并行推送。全局来看 因为是并行的所以可能会有乱序但推送到某个SG上的日志一定是按照LSN单调递增的(不连续) 。随着PCPL的推进一旦PCPL值大于某个事物的CLSN该事物就可以完成Commit操作了。
崩溃恢复
首先CynosDB会持续的保存主实例的PCPL这个PCPL的备份值我们称之为Last PCPL(简称L-PCPL) 。CynosDB需要保证L-PCPL值的更新足够快以确保那些大于L-PCPL的日志记录没有被回收。在此前提下我们通过如下步骤实现崩溃恢复
图6
首先新的主实例获取到L-PCPL值为3。该实例由2个SG组成其中SG A中已经持久化了日志(1 、
4、 5) 而SG B中持久化了日志(2、 3、 6、 8) 。
图7
主实例向2个SG读取大于3的所有日志LSN获取到SGA的4、 5以及SG B的6、 8。这样形成了3、
4、 5、 6、 8的日志流。按照定义 因为没有LSN为7的日志所以8是无效的其次6不是CPL所以6也是无效的这样就计算出了最新的PCPL值为5。然后将新的PCPL值推送给所有的从实例。
图8
最后主实例将新的PCPL=5推送给所有SG 以便其将大于5的所有日志都清理掉。
经过上面三步整个数据就回到了PCPL=5这个一致性的点。主实例和从实例就可以提供服务了。
持续备份
实际上在CynosDB中几乎不需要全量的备份操作只要保证SG的WAL LOG在回收前被增量保存到了冷备系统中就行了。因为逻辑上WAL LOG是包含了所有数据的修改操作我们可以使用增量的WAL LOG按照客户需求生成全量备份和差异备份。而这些操作都可以是由另一套独立的系统基于增量备份数据离线处理的对CynosDB的线上系统不会造成任何的影响。另外我们还需要对实例的状态配置信息进行备份以便恢复时能获取到相关信息。
恒创科技:SonderCloud Limited旗下数据中心基础业务服务品牌,APNIC/ARIN会员单位,专注云服务器、香港服务器、高防服务器租用,基于BGP+双向CN2中港专线,提供高速网络服务。
tmhhost放出了2021年的端午佳节+618年中大促的优惠活动:日本软银、洛杉矶200G高防cn2 gia、洛杉矶三网cn2 gia、香港200M直连BGP、韩国cn2,全都是高端优化线路,所有这些VPS直接8折,部分已经做了季付8折然后再在此基础上继续8折(也就是6.4折)。 官方网站:https://www.tmhhost.com 香港BGP线路VPS ,200M带宽 200M带...
传统农历新年将至,国人主机商DogYun(狗云)发来了虎年春节优惠活动,1月31日-2月6日活动期间使用优惠码新开动态云7折,经典云8折,新开独立服务器可立减100元/月;使用优惠码新开香港独立服务器优惠100元,并次月免费;活动期间单笔充值每满100元赠送10元,还可以参与幸运大转盘每日抽取5折码,流量,余额等奖品;商家限量推出一款年付特价套餐,共100台,每个用户限1台,香港VPS年付199元...
这两天在站长群里看到不少有使用DEDECMS织梦程序的朋友比较着急,因为前两天有看到来自DEDECMS,我们熟悉的织梦程序官方发布的公告,将会在10月25日开始全面商业用途的使用DEDECMS内容管理程序的会采用授权收费模式,如果我们有在个人或者企业商业用途的,需要联系且得到授权才可以使用,否则后面会通过维权的方式。对于这个事情,我们可能有些站长经历过,比如字体、图片的版权。以及有一些国内的CMS...