一、 整体介绍
传统RDS架构在高可用的实现上采用了主备复制的模式,通过Binlog逻辑复制保证高可用。该架构存在以下几个问题:
• 增加计算节点需要同步扩容存储,导致存储成本随着节点增加而上升。
• 扩展只读节点较麻烦,需要进行数据重建。在数据量较大的情况下,数据重建耗时较久,可能会影响HA的耗时。
不同于传统的主备复制,PolarDB采用共享存储架构,存储和计算分离,中间通过PolarFS分布式的文件系统和存储进行共享数据。
RW负责数据写入,主要流程为:RW调用文件系统的API,文件系统经过内部处理将数据写入到共享存储,数据的可靠性依赖于共享存储的多副本机制。因此在DB层面,无需关心多份数据的写入。因为天然存在多副本的机制,对于DB而言,只需写一份数据在共享存储。
共享存储中,所有节点可共享同一份数据,PolarFS分布式文件系统天然解决了一写多读场景下的数据一致性问题。该架构下存储和计算节点分离,计算节点的扩容和存储节点的扩容互相不耦合,均可单独进行扩容。并且因为共享一份数据,新增RO节点时,无需再进行数据重建,可以秒级拉起RO节点,存储层面也可独立扩容,无需扩容计算节点。
PolarFS文件系统是专门为DB设计的用户态文件系统,并且基于共享存储支持了一写多读的实现,向上提供兼容posix的接口。
写节点的数据写入流程如下:调用PolarFS创建目录,PolarFS将数据写入到共享存储。由于采用了共享存储的机制,数据已经存在于存储内,但是因为PolarFS层面本身也有文件系统的元数据,需要在RO节点上通过日志同步的方式进行感知。
以上设计的好处在于PolarFS提供posix兼容,DB无需再大刀阔斧地改造代码,可以以较小的代价实现分布式架构,并且天然地在共享存储架构下实现了高可用。比如新增RO或HA的场景下,相较主备复制,它无需进行数据拷贝,RTO可达到分钟级甚至秒级。
PolarFS和常见的文件系统类似,主要有以下几个元数据的概念。
• Direntry:记录文件或目录的名字。
• Inode:描述文件或目录的基本属性,比如inode类型、文件长度、atime/mtime/ctime等。
• Blktag:描述该block所属的文件以及在文件中的位置,每个block都拥有一个对应的blktag。
比如上图,创建gcc文件并进行写入时,需要为其分配数据块空间,每个数据块默认大小为4M,需要分配大于4M的空间时,将多个block进行连接,达到索引链接的目的。
文件系统的目录输入采用了典型的树状结构。
文件系统中需要进行MakeFS的操作,目的为对文件系统的空间进行划分,将底层的共享存储块设备进行管理。
假设是40G的存储设备,PolarFS将按照实际的chunk对空间进行划分,划分出4个chunk的空间。每个chunk内部又划分了大小为4M的多个block。每个chunk的第0个block将作为superblock,用于记录文件系统的元数据信息,多为blktag、direntry以及inode。每一个4兆的superblock最多可以存储2048个direntry和inode,意味着每个chunk下可以创建2048个文件或目录。
除了superblock之外的所有的datablock用于存放文件的数据,共有2560个。blktag元数据会负责管理datablock,映射到datablock。
使用PolarFS文件系统时,首先会执行格式化,主要目的是将元数据在superblock内进行格式。
日志是文件系统中很重要的组成。文件系统对文件的修改往往涉及多个不同类型的元数据修改,如果修改不能原子性完成,则会造成数据的不一致或损坏。
PolarFS的日志除了保证事务提交的完整性,还有一个关键用途为通过一写多读同步数据。
文件系统内部有很多元数据需要进行管理,当RW节点对内部的元数据进行修改之后,如果要保证一致性,RO节点上也需要对元数据进行同样的修改,才能保证一致性。该能力通过Journal的设计实现。
Journal文件是固定大小的空间,其中head lsn为当前事务提交到的最新位点。因为日志是循环覆盖写的过程,如果日志提交后空间不够,需要做checkpoint操作,将日志trim到磁盘上,变更也将反映到磁盘的共享存储上。checkpoint操作可将位点不停地推进,将块空间进行释放,用于提交新的log。
RW提交元数据之后,RO要访问文件时,首先会读取最新位点。同时,RO内部本身会维护已有的事务位点,然后判断最新位点与已有事务位点的差距,比如最新位点为10,已有位点为5,则意味着中间有5个事务尚未同步。RO会将这5个数据进行同步,并进行内存回放。同步完以后,将RO本身的已有事务位点更新至10。
接下篇:https://developer.aliyun.com/article/1223072?groupCode=polardbforpg