#文件系统高可用

YFS通过diskgroup和多副本技术实现数据的高可用,通过集群化部署实现服务的高可用。

# 数据高可用

# 磁盘组、故障组和冗余度

磁盘组(Diskgroup)是YFS管理的磁盘集合。根据业务需要,YFS中可能存在多个磁盘组。YFS要求磁盘组中的所有磁盘大小相等,如果磁盘大小不同,向磁盘组添加磁盘时可指定磁盘可用空间为所有磁盘中的最小值,这会造成磁盘空间浪费,推荐使用相同大小的一组磁盘。

yfs_diskgroup_diagram

YFS支持为磁盘组配置External、Normal和High三个级别的磁盘冗余度。在Normal和High冗余度(Redundancy)的磁盘组中创建的文件,YFS为这些文件创建若干数据镜像,文件的每个镜像称为该文件的1个副本。文件的副本会分布在不同故障组(Failgroup),确保部分磁盘故障不会造成所有副本数据损坏,保证文件的完整性。YFS中文件的副本数量由文件所在的磁盘组决定,可以在创建磁盘组时指定冗余度参数,多副本的磁盘空间消耗也会成比例放大,指定磁盘组冗余度时应平衡数据保护强度和磁盘空间效率。

冗余度 说明
External 仅保存一份数据,无多副本保护。
Normal 用户数据2副本,YFS元数据最多3副本。
High 用户数据3副本,YFS元数据最多5副本。

对于Normal和High冗余度,冗余度越高意味着YFS内部存在更多副本,对磁盘损坏具备更高的容忍度而不会造成数据丢失,提供更高的数据可用性保护。当发生磁盘故障时,YFS会检查文件副本的完整性,如果所有副本都损坏,YFS将卸载(Dismount)该磁盘组;如至少有一个副本是完整的,数据库不感知磁盘故障,数据库可继续提供服务。

External冗余度磁盘组中的文件没有额外副本,YFS不提供保护,数据的可用性依赖外部存储,如RAID。当外部存储设备发生故障时,对应的磁盘组被卸载不可用。由于External冗余度没有额外的副本,因此磁盘空间利用效率最高,请综合考虑数据价值和外部存储的可靠性,谨慎选用。

Warn:

External冗余度的磁盘组不支持数据高可用,一旦发生磁盘故障整个磁盘组都将不可用,甚至数据丢失,请做好数据备份。

故障组(Failgroup)是磁盘组的子集,用来保存数据副本,创建磁盘组时需要根据冗余度配置每个磁盘组中的故障组。故障组的配置要求如下:

  1. 同一个故障组的磁盘故障率高度相关,通常可以根据磁盘的物理关系进行划分,比如同一机柜的磁盘、同一电源的磁盘、通过同一网络连接共享的磁盘等等,当发现其中部分磁盘故障时,通常这些磁盘都不可用。

  2. 要求同一磁盘组内所有故障组的磁盘数量必须相同。

  3. YFS中所有磁盘都必须属于某个故障组,如磁盘未指定所属故障组,YFS自动为该磁盘创建默认故障组,即创建只包含1个磁盘的故障组。磁盘组创建完成后可通过Alter操作修改故障组,如为所有故障组增加或删除磁盘、新增或删除故障组,操作结束后依然需要满足该磁盘组内所有故障组的磁盘数量相同。

  4. External冗余度的磁盘组,至少需1个故障组,用户数据和YFS元数据副本数量均为1;Normal冗余度的磁盘组,至少需2个故障组,用户数据和YFS元数据的副本数为2,如果存在3个以上故障组,则用户数据副本数为2而YFS元数据的副本数为3;High冗余度的磁盘组,至少需要3个故障组,用户数据和YFS元数据副本数为3,如果存在4个以上的故障组,则YFS元数据的副本数至少为4最多为5个副本。

  5. YFS的故障组用于保存数据副本,总是需要副本数整倍数的故障组分配磁盘空间,如果磁盘组中的故障组数量不是副本数的整倍数,余数个故障组内的磁盘空间将不可用,请确保故障组数量为用户文件副本数的整倍数,提高空间利用率。

推荐创建足够多的故障组,为YFS元数据提供额外的副本保护。创建磁盘组以后新增故障组不能改变YFS元数据的副本数量,请在创建磁盘组时做好规划。

以Normal冗余度的磁盘组为例,其中的文件为2个副本,YFS会选择该磁盘组的2个不同故障组,分别保存2个数据副本。当某个故障组的磁盘发生故障时,另一个故障组中的数据副本可以保证文件数据的完整性;当2个故障组都有磁盘故障时,文件的2个副本可能全部损坏,文件数据不完整。

yfs_data_copy_corrupt

# 故障场景

# 数据块错误

YFS管理磁盘的最小单元称为AU(Allocate Unit),可选1M(默认值)、4M、8M、16M、32M。YFS中的文件由一些在磁盘上离散的AU组成,YFS通过文件元数据实现文件AU的磁盘寻址。冗余度为Normal和High磁盘组中的文件,数据在AU级别实现冗余。对于Normal冗余度磁盘组中的文件,其数据副本数为2,即每1个AU大小的文件数据,在不同故障组的2块磁盘中各有1个AU与之对应,它们存储相同的数据。

img

写入YFS文件时,YFS会同时更新文件位置对应的2个AU;YFS读取文件时会对数据进行完整性校验(例如checksum校验),依次读取对应位置的2个AU,读取到任意完整的数据,即认为文件对应位置的数据完整,不再读取后续副本。例如Disk1出现数据块错误,可能由磁盘坏道、上一次写入不完整等引起,使得AU21数据错误(不是IO错误),YFS通过数据完整性校验检测到此处数据不完整,则继续读取AU22。AU22处读取的数据通过数据完整性校验,那么文件AU2处的数据依然是完整的,业务层不感知数据块错误。

img

YFS读取数据时,如发现块级数据错误,且至少存在1个完整的副本,那么YFS会尝试将完整数据写入损坏的数据块,自动完成坏块修复。YFS的坏块修复时,可以在对应YFS实例的日志中看到:

[YFS] repair dg:磁盘组id, fd:文件fd, offset:文件偏移, len:修复长度, copyIndex:修复的副本编号

如果文件AU对应的所有副本都出错,则此处数据被损坏,无法恢复。发生这种情况时,可以在对应YFS实例的日志中看到:

[YFS IO] all copies corrupted, message: dgid=磁盘组id, fd=文件fd, offset=文件偏移, size=IO长度

# 磁盘故障

  • YFS读写文件时,如读、写某磁盘失败则认为该磁盘故障,YFS检查其他副本所在故障组的故障状态,如果该磁盘保存的是最后一个可用副本,说明当前节点没有修改该文件的任何副本,YFS只需在当前实例将故障磁盘Offline,卸载其所在磁盘组,当前实例将无法对该磁盘组执行任何IO,数据库会报IO错误;
  • 如果该磁盘保存的数据,在其他故障组还有可用副本,说明当前节点无法更新故障磁盘上的副本,但可能更新其他副本数据,此时多副本的数据可能不一致,YFS广播所有实例Offline该故障磁盘,避免各实例读取到不同副本不一致的结果。

例如3实例YFS集群,3个共享磁盘(图中为每个实例绘制3块磁盘,实际上是各实例可见的3块共享磁盘)组成的磁盘组。以3副本为例,每个数据副本会保存在一个磁盘中。

img

当只有1个磁盘故障时

当实例1的数据库读写Disk1失败,检测到Disk1故障,数据库向本实例的YFS上报Disk1故障。YFS检测到该磁盘组还有Disk2、Disk3可用,3副本数据还有2个有效副本,磁盘组依然具备服务能力,磁盘组状态不变,依然可用,但标记Disk1为Offline状态。同时YFS发送广播消息,通知集群其他节点,也将Disk1设置为Offline。Offline磁盘时,可以在YFS日志中看到如下内容:

[YFS DISK] offline disk name: 磁盘名称, path: 磁盘路径, diskstatus: 当前磁盘状态

也可以通过yfscmd工具查询,所有节点的Disk1的状态为Offline,Disk2、Disk3状态为Normal。

此时集群内3个节点的共享磁盘状态达成一致:Disk1 Offline,Disk2和Disk3状态为Normal,磁盘组正常。数据库完成故障上报后继续执行读写操作,直到写完所有副本所在Disk,即Disk2、Disk3,或者从Disk2、Disk3之一读到完整副本,数据库不感知Disk1的故障。

当有多个磁盘故障时

如果Disk2,Disk3已经处于Offline状态,当数据库读写Disk1失败时,向本实例YFS上报磁盘故障,YFS检测到本实例该磁盘组的三个磁盘都故障,所有副本都不可访问,则YFS将本实例的Disk1 Offline,且将磁盘组Dismount。可在本实例YFS日志中看到如下内容:

[YFS DISK] offline disk: 磁盘路径 cause data lost, diskgroup 磁盘组名称 will dismount

数据库运行日志中会看到如下内容:

[YFS IO] all copies corrupted, message: dgid=磁盘组编号, fd=文件fd, offset=IO偏移, size=IO大小

由于当前节点不会更新任何数据,磁盘故障不会引入多副本的不一致性,YFS无需通知集群其他节点Disk1的状态变化。由于各节点与共享磁盘的连接状态差异,集群中各节点看到的磁盘组状态可能不一致,例如图中节点1的Disk1状态为Offline、磁盘组状态为Dismount,其他2个节点Disk1状态为Normal、磁盘组状态正常。这种差异避免了节点1的故障扩散到集群其他节点,确保集群的最大可用。

YFS的元数据操作(如增删改查文件、目录等)由YFS集群自选主节点执行,如果主节点某个磁盘组状态为Dismount,在任意节点上执行该磁盘组的元数据操作都会失败,提示磁盘组处于Dismount状态,与发起请求的实例看到的磁盘组状态无关。如YFS集群中有节点的磁盘组状态正常,请参考以下步骤使正常节点成为新主节点,即可恢复YFS元数据操作。

以3节点集群为例,登录任意节点,通过以下指令查看YFS集群当前主节点:

$ export YASCS_HOME=/your/yascs/home
$ ycsctl status
---------------------------------------------------------------------------------------------
Self Host ID|Cluster Master ID|YasFS Master ID|YasDB Master ID|Active Host Count
---------------------------------------------------------------------------------------------
1            1                 1               1               3         
---------------------------------------------------------------------------------------------
Host ID   |Target    |State     |YasFS     |YasDB     |VIP
---------------------------------------------------------------------------------------------
1          online     online     online     online                                                                 
2          online     online     online     online                                                                 
3          online     online     online     online

根据YasFS Master ID列可知YFS主节点为1号节点,登录节点1查看磁盘组DG0为Dismount状态:

$ export YASCS_HOME=/your/yascs/home
$ yfscmd show diskgroup
id name     type     level    au_size  stat     block_size  total_mb    free_mb     usable_file_mb
0  SYSTEM   SYSTEM   0        1.00MB   MOUNTED  4096        1024        764         764        
1  DG0      USER     0        32.00MB  DISMOUNTED 4096        0           0           0

此时节点1上的磁盘组DG0不可用,如数据库正在使用该磁盘组,数据库无法正常服务,请在节点1执行以下指令停止该节点:

$ ycsctl stop ycs

此时节点1从集群离线,并自动触发YFS集群重构,集群会自动从节点2和节点3中选取一个新主。可登录节点2或节点3查看集群最新状态:

$ export YASCS_HOME=/your/yascs/home
$ ycsctl status
---------------------------------------------------------------------------------------------
Self Host ID|Cluster Master ID|YasFS Master ID|YasDB Master ID|Active Host Count
---------------------------------------------------------------------------------------------
2            2                 2               2               2         
---------------------------------------------------------------------------------------------
Host ID   |Target    |State     |YasFS     |YasDB     |VIP
---------------------------------------------------------------------------------------------
1          online     offline    offline    offline
2          online     online     online     online
3          online     online     online     online

可知节点2为YFS主节点,只要节点2上磁盘组DG0正常,则集群恢复YFS元数据操作。

# 服务高可用

以集群模式部署YFS,当服务器数量发生变化或某个服务器发生故障无法服务时,YFS自动重构,恢复服务。只要集群中至少还有1个可用服务器,YFS集群服务就可用。

另外,YFS利用redo和checkpoint机制确保了数据的一致性和可靠性,当发生极端故障时,重启YFS是通过回放redo日志恢复到有效状态。

# 主备复制

YFS集群状态的一致性非常重要,YFS主实例向所有备实例的实时数据复制,通过传送redo日志实现,如下图:

yfs_redo_replay.png

1. 日志插入

YFS集群至少包含1个主实例(Primary)和若干备实例(Standby)。主实例负责处理所有元数据变更,同时将产生对应的redo log,插入Log Cache。

2. 日志刷盘

YFS自身的redo file也由YFS管理,受YFS多副本技术保护。

redo log被持久化到redo file,这些数据保存在共享存储上,确保恢复时所有YFS实例都可以访问该文件。

3. 日志发送

主实例将本机日志发送给所有备实例,由于YFS的元数据变更数据量很少,这里采用同步发送。

4. 日志回放

备实例收到日志后,通过重演主实例redo log更新元数据页面,最终备实例状态与主实例状态同步一致。

edit-icon
反馈
coperate-icon
coperate
合作
communication-icon
communicate
交流