亚马逊AWS官方博客

如何在 AWS 上构建并行文件系统 BeeGFS – 高可用篇

概述

BeeGFS ( www.beegfs.io ) 是行业领先的并行集群文件系统,设计时在优先考虑性能强大的同时,安装和管理非常方便,是I/O密集型工作负载的优质存储解决方案。 本篇文章主要会讲解如何搭建高可用的BeeGFS集群,BeeGFS服务的详细介绍和具体服务部署安装详细步骤请参考 如何在AWS上构建并行文件系统BeeGFS

BeeGFS高可用集群简介

从2012.10版本开始,BeeGFS支持元数据(MetaData)和文件内容(File Contents)镜像。镜像功能集成到正常BeeGFS服务,所以,不需要单独的服务或第三方工具。这两种类型的镜像(元数据镜像和文件内容镜像)可以相互独立的使用。从BeeGFS v6.0开始,元数据镜像也扩展成为高可用性的特性。

存储和元数据镜像的高可用性是基于Buddy Group。一般来说,一个Buddy Group是一对两个目标,内部管理彼此之间的数据复制。Buddy Group允许存储服务在两个目标之一失败时仍可以访问所有数据。它也支持把Buddy Group放在不同灾备区域,例如不同的机架或不同的服务器机房。

Storage Buddy Mirroring: 4 Servers with 1 Target per Server

存储服务器Buddy镜像也可以用于奇数个存储服务器。因为BeeGFS Buddy Group由独立的存储目标组成,独立于它们对服务器的分配是可行的,如下面的示例图所示,每个服务器有3个服务器和6个存储目标组成。

Storage Buddy Mirroring: 3 Servers with 2 Targets per Server

注意,这在元数据服务器上是不可能的,因为BeeGFS中元数据没有目标的概念。需要偶数个元数据服务器,以便每个元数据服务器都可以属于一个Buddy Group

在正常操作中,Buddy Group中的一个存储目标(或元数据服务器)被认为是主存储服务,而另一个是辅存储服务。修改操作总是先发送到主服务器,主服务器负责镜像过程。文件内容和元数据是同步镜像的,即在将两个数据副本传输到服务器后,客户端操作完成。

如果无法访问Buddy Group的主存储目标或元数据服务器,则会将其标记为脱机,并发出到辅存储的故障转移。在这种情况下,以前的辅存储将成为新的主存储。这样的故障转移是透明的,并且在运行应用程序时不会丢失任何数据。故障转移将在短暂的延迟后发生,以确保在将更改信息传播到所有节点时系统的一致性。如果服务只是重新启动(例如,在滚动更新的情况下),此短延迟还可以避免不必要的重新同步。

可以通过以下命令方面查询存储服务和元数据服务的节点状态

$ beegfs-ctl --listtargets --nodetype=storage --state
$ beegfs-ctl --listtargets --nodetype=meta --state 

For more information:
$ beegfs-ctl --listtargets --help 

只有在BeeGFS管理服务正在运行时,才能对Buddy Group进行故障转移。这意味着,如果具有BeeGFS管理服务的节点崩溃,则不会发生故障转移。因此,建议在不同的机器上运行BeeGFS管理服务。但是,不必为BeeGFS管理服务提供专用服务器。

BeeGFS高可用集群搭建

部署架构图

组件系统配置

角色 主机名 系统配置 vCPU 内存 (GB) 网络带宽 (Gbps) EBS带宽 (Mbps) 存储 备注
Management node1 c5.large 2 4 Up 10 Up 4750 8GB EBS
Metadata node201 c5d.xlarge 4 8 Up 10 Up 4750 1 x 100GB NVMe SSD
Metadata node202 c5d.xlarge 4 8 Up 10 Up 4750 1 x 100GB NVMe SSD
Storage-I node301 c5.4xlarge 16 32 Up 10 4750 2 x 2TB EBS target:3011、3012
Storage-II node302 c5.4xlarge 16 32 Up 10 4750 2 x 2TB EBS target:3021、3022
Storage-III node303 c5.4xlarge 16 32 Up 10 4750 2 x 2TB EBS target:3031、3032
Client node4 c5.large 2 4 Up 10 Up 4750 8GB EBS

服务安装过程

各服务组件的安装详细流程可以参考 如何在AWS上构建并行文件系统BeeGFS。为了统一安装流程,以下都是基于手动安装流程进行,只给出基础的安装命令。

手动安装BeeGFS组件

1、安装node1

# 安装管理服务应用
$ sudo apt install beegfs-mgmtd  
 
# 在对应目录创建管理服务     
$ sudo /opt/beegfs/sbin/beegfs-setup-mgmtd -p /data/beegfs/beegfs_mgmtd 

# 启动服务
$ sudo systemctl start beegfs-mgmtd    

2、安装node201,node202

# 安装元数据服务组件
$ sudo apt install beegfs-meta  

# 以下格式化 NVMe 卷成xfs文件系统,并挂载到 /data/lun_meta 路径
# 文档请参考https://docs.thinkwithwp.com/zh_cn/AWSEC2/latest/UserGuide/ebs-using-volumes.html

# 查看NVMe卷的名字,假设为 /dev/nvme0n1
$ lsblk                      

# 格式化成 xfs 文件系统             
$ sudo mkfs -t xfs /dev/nvme0n1   

# 创建挂载点              
$ sudo mkdir -p /data/lun_meta  

# 将格式化后的新卷挂载到 /data/lun_meta                
$ sudo mount /dev/nvme0n1 /data/lun_meta    
   
# 设置重新启动,注意是 restart 后自动挂载,Stop 后 NVMe 数据将丢失,如果需要 STOP 操作,请使用 EBS 卷做为存储

# 检查卷的 UUID,假设为abcd-efgh-1234-5678
$ sudo lsblk -o +UUID    

# 修改自动加载配置文件  
# 添加:UUID= abcd-efgh-1234-5678  /data/lun_meta  xfs  defaults,nofail  0  2              
$ sudo vi /etc/fstab                      

# 在对应目录创建元数据管理服务,并指定元数据服务 sid 为201或者202,管理节点名称为 node1, 如下:
# 对node201
$ sudo /opt/beegfs/sbin/beegfs-setup-meta -p /data/lun_meta -s 201 -m node1  

# 对node202 
$ sudo /opt/beegfs/sbin/beegfs-setup-meta -p /data/lun_meta -s 202 -m node1   

# 启动服务
$ sudo systemctl start beegfs-meta           

3、安装node301,node302,node303

# 登陆node301进行以下操作,之后同样登陆 node302,node303 执行相应操作
# 安装存储管理服务
$ sudo apt install beegfs-storage      

# 到此需要格式化 NVMe 卷,其过程与配置自己加载请参考元数据服务的卷配置过程,假设挂载路径为/mnt/lun_storage_1、/mnt/lun_storage_2
$ sudo mkfs -t xfs /dev/nvme0n1 && sudo mkfs -t xfs /dev/nvme1n1

# 加入本地存储卷到 BeeGFS 存储中,如下,301 是存储节点代号,3011是目前存储节点代码,在 301 实例上如果增加另外的卷,可以选择 3012,3013 等 301{n} 形式进行存储扩容。
$ /opt/beegfs/sbin/beegfs-setup-storage -p /mnt/lun_storage_1 -s 301 -i 3011 -m node1
$ /opt/beegfs/sbin/beegfs-setup-storage -p /mnt/lun_storage_2 -s 301 -i 3012 -m node1
$ /opt/beegfs/sbin/beegfs-setup-storage -p /mnt/lun_storage_1 -s 302 -i 3021 -m node1
$ /opt/beegfs/sbin/beegfs-setup-storage -p /mnt/lun_storage_2 -s 302 -i 3022 -m node1
$ /opt/beegfs/sbin/beegfs-setup-storage -p /mnt/lun_storage_1 -s 303 -i 3031 -m node1
$ /opt/beegfs/sbin/beegfs-setup-storage -p /mnt/lun_storage_2 -s 303 -i 3032 -m node1

# 启动服务
$ systemctl start beegfs-storage 

# 停止服务
$ systemctl stop beegfs-storage 

存储实例添加EBS卷

# 本地EBS列表
$ /home/ubuntu# lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
loop0         7:0    0   18M  1 loop /snap/amazon-ssm-agent/1480
loop1         7:1    0   89M  1 loop /snap/core/7713
loop2         7:2    0 93.8M  1 loop /snap/core/8935
loop3         7:3    0   18M  1 loop /snap/amazon-ssm-agent/1566
nvme0n1     259:0    0    2T  0 disk
nvme1n1     259:1    0    2T  0 disk
nvme2n1     259:2    0    8G  0 disk
└─nvme2n1p1 259:3    0    8G  0 part /
# 格式化
$ sudo mkfs -t xfs /dev/nvme0n1
$ sudo mkfs -t xfs /dev/nvme1n1

# 创建目录
$ mkdir /mnt/lun_storage_1
$ mkdir /mnt/lun_storage_2

# 挂载EBS卷
$ mount /dev/nvme0n1 /mnt/lun_storage_1
$ mount /dev/nvme1n1 /mnt/lun_storage_2

# 查询UUID
$ sudo lsblk -o +UUID
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT                  UUID
loop0         7:0    0   18M  1 loop /snap/amazon-ssm-agent/1480
loop1         7:1    0   89M  1 loop /snap/core/7713
loop2         7:2    0 93.8M  1 loop /snap/core/8935
loop3         7:3    0   18M  1 loop /snap/amazon-ssm-agent/1566
nvme0n1     259:0    0    2T  0 disk                             9f677321-d52d-4eb9-b00b-119c251aad26
nvme1n1     259:1    0    2T  0 disk                             9ea0044e-1774-416a-aff5-31afe054ddac
nvme2n1     259:2    0    8G  0 disk
└─nvme2n1p1 259:3    0    8G  0 part /                           651cda91-e465-4685-b697-67aa07181279

# 编辑 fatab文件,配置Mount点信息
$ sudo vim /etc/fstab
UUID=9f677321-d52d-4eb9-b00b-119c251aad26  /mnt/lun_storage_1  xfs  defaults,nofail  0  2
UUID=9ea0044e-1774-416a-aff5-31afe054ddac  /mnt/lun_storage_2  xfs  defaults,nofail  0  2

4、安装node4

# 安装客户端,命令行工具盒
$ apt install beegfs-client beegfs-helperd beegfs-utils 

# 指定管理节点 node1
$ /opt/beegfs/sbin/beegfs-setup-client -m node1 

# 修改beegfs-mounts.conf,第一项是挂载目录,第二项是配置文件路径,如下:
/mnt/beegfs /etc/beegfs/beegfs-client.conf
$ vim /etc/beegfs/beegfs-mounts.conf

# 启动heplerd服务,提供日志与 DNS 解析等服务
$ systemctl start beegfs-helperd   

# 启动客户端服务      
$ systemctl start beegfs-client          

$ beegfs-ctl --listnodes --nodetype=meta
node201 [ID: 201]
node202 [ID: 202]

# 存储节点列表
$ beegfs-ctl --listnodes --nodetype=storage
node301 [ID: 301]
node302 [ID: 302]
node303 [ID: 303]

# 元数据节点列表
beegfs-ctl --listtargets --mirrorgroups
beegfs-ctl --listnodes --nodetype=client

5、目标状态查询

$ beegfs-ctl --listtargets --nodetype=meta --state
TargetID     Reachability  Consistency   NodeID
========     ============  ===========   ======
     201           Online         Good      201
     202           Online         Good      202
     
$ beegfs-ctl --listtargets --nodetype=storage --state
TargetID     Reachability  Consistency   NodeID
========     ============  ===========   ======
    3011           Online         Good      301
    3012           Online         Good      301
    3021           Online         Good      302
    3022           Online         Good      302
    3031           Online         Good      303
    3032           Online         Good      303
    
$ beegfs-ctl --listtargets --help

状态查询配置:https://www.beegfs.io/wiki/TargetStates

6、可达性状态的描述

可达性状态用来描述系统是否可以访问目标。它由管理服务监视。这种状态是Buddy镜像的重要组成部分,因为Buddy镜像组中的目标的故障转移是基于主目标的可达性状态的。定义了以下可达状态:

  • Online:可以到达目标或节点。
  • offline:检测到此目标或节点的通信失败。这是一个中间状态,在这个状态中,关于可能发生故障的信息将传播到所有节点,以便系统为将此目标转换为脱机状态做好准备。如果不能达到的目标或节点快速关机,回来后(如短服务重启滚动更新的一部分),或者是遥不可及的由于临时网络故障,它还可以回到不在线状态和故障转移或同步将会发生。
  • Offline:无法到达目标。如果这是镜像Buddy Group的主要目标,则在目标转换到脱机状态时将立即发出故障转移。

7、一致性状态描述

一致性状态描述存储目标或元数据节点上的数据状态。定义了以下一致性状态:

  • Good:数据被认为是好的。 需要重新同步:这种一致性状态只适用于镜像Buddy Group的次要目标或节点。目标或节点上的数据被认为是不同步的(例如,因为它是离线的),需要重新同步。
  • Needs-resync:目标或节点上的数据被认为是不同步的,重新同步的尝试正在进行中。
  • Bad:目标或节点上的数据被认为是不同步的,重新同步的尝试失败。请查看日志文件以获得关于为什么选择此状态的更多信息。

8、配置Meta Buddy,Storage Buddy 自动定义Meta和Stroage的Group

# 自动创建元数据Group
$ beegfs-ctl --addmirrorgroup --automatic --nodetype=meta
New mirror groups:
BuddyGroupID   Node type Node
============   ========= ====
           1     primary      201 @ beegfs-meta node201 [ID: 201]
               secondary      202 @ beegfs-meta node202 [ID: 202]
      
# 自动创建存储Group         
$ beegfs-ctl --addmirrorgroup --automatic --nodetype=storage
New mirror groups:
BuddyGroupID Target type Target
============ =========== ======
           1     primary     3011 @ beegfs-storage node301 [ID: 301]
               secondary     3021 @ beegfs-storage node302 [ID: 302]
           2     primary     3031 @ beegfs-storage node303 [ID: 303]
               secondary     3012 @ beegfs-storage node301 [ID: 301]
           3     primary     3022 @ beegfs-storage node302 [ID: 302]
               secondary     3032 @ beegfs-storage node303 [ID: 303]

Mirror buddy group successfully set: groupID 1 -> target IDs 3011, 3021
Mirror buddy group successfully set: groupID 2 -> target IDs 3031, 3012
Mirror buddy group successfully set: groupID 3 -> target IDs 3022, 3032

$ beegfs-ctl --addmirrorgroup --help 

# 激活 metadata mirroring,需要重启所有的meta service
# https://www.beegfs.io/wiki/MDMirror#hn_59ca4f8bbb_2
$ beegfs-ctl --mirrormd
NOTE:
 To complete activating metadata mirroring, please remount any clients and
 restart all metadata servers now.
 
# 重启beegfs-meta服务
$ systemctl restart beegfs-meta
# 查询元数据服务状态
$ beegfs-ctl --listmirrorgroups --nodetype=meta
     BuddyGroupID     PrimaryNodeID   SecondaryNodeID
     ============     =============   ===============
                1               201               202
            
            beegfs-ctl --listmirrorgroups --nodetype=meta
     BuddyGroupID     PrimaryNodeID   SecondaryNodeID
     ============     =============   ===============
                1               201               202

$ beegfs-ctl --listmirrorgroups --nodetype=storage
     BuddyGroupID   PrimaryTargetID SecondaryTargetID
     ============   =============== =================
                1              3011              3021
                2              3031              3012
                3              3022              3032

# 查询存储服务状态                
$ beegfs-ctl --listtargets --mirrorgroups
MirrorGroupID MGMemberType TargetID   NodeID
============= ============ ========   ======
            1      primary     3011      301
            1    secondary     3021      302
            2      primary     3031      303
            2    secondary     3012      301
            3      primary     3022      302
            3    secondary     3032      303

$ beegfs-ctl --listtargets --help

支持手动设置Buddy Group:https://www.beegfs.io/wiki/BuddyGroups

如果您想要设置自定义组id,或者想要确保Buddy Group位于不同的故障域中(例如,不同的机架),那么手动定义镜像Buddy Group是非常有用的。使用beegfs-ctl工具手动定义镜像Buddy Group。通过使用下面的命令,您可以创建一个ID为100的Buddy Group,由目标1和目标2组成

# 手动指定Buddy Group
$ beegfs-ctl --addmirrorgroup --nodetype=storage --primary=3011 --secondary=3021 --groupid=1 

$ beegfs-ctl --addmirrorgroup --help

9、定义条带模式 在您的系统中定义了存储Buddy镜像组之后,您必须定义一个使用它的数据条带模式。

# 获取目录属性
$ beegfs-ctl --getentryinfo /mnt/beegfs
EntryID: root
Metadata buddy group: 1
Current primary metadata node: node201 [ID: 201]
Stripe pattern details:
+ Type: RAID0
+ Chunksize: 512K
+ Number of storage targets: desired: 4
+ Storage Pool: 1 (Default)
# 创建RAID0模式的目录
mkdir /mnt/beegfs/raid0-dir
$ beegfs-ctl --setpattern --pattern=raid0 --chunksize=1m --numtargets=4 /mnt/beegfs/raid0-dir
New chunksize: 1048576
New number of storage targets: 4

$ beegfs-ctl --getentryinfo /mnt/beegfs/raid0-dir
EntryID: 0-5E9E76DD-C9
Metadata buddy group: 1
Current primary metadata node: node201 [ID: 201]
Stripe pattern details:
+ Type: RAID0
+ Chunksize: 1M
+ Number of storage targets: desired: 4
+ Storage Pool: 1 (Default)
# 创建Buddy模式的目录
mkdir /mnt/beegfs/buddy-dir
$ beegfs-ctl --setpattern --pattern=buddymirror --chunksize=1m --numtargets=4 /mnt/beegfs/buddy-dir
New chunksize: 1048576
New number of storage targets: 4

$ beegfs-ctl --getentryinfo /mnt/beegfs/buddy-dir
EntryID: 0-5E9E7791-C9
Metadata buddy group: 1
Current primary metadata node: node201 [ID: 201]
Stripe pattern details:
+ Type: Buddy Mirror
+ Chunksize: 1M
+ Number of storage targets: desired: 4
+ Storage Pool: 1 (Default)

故障恢复

BeeGFS的Buddy Group支持自动的故障转移和恢复。如果存储目标或元数据服务发生故障,会将其标记为脱机,并且不会获取数据更新。通常,当目标或服务器重新注册时,它将自动与Buddy Group中的剩余镜像同步(自动修复)。但是,在某些情况下,也可以支持手动启动同步过程。

以下通过分别模拟存储服务和元数据服务的故障,演示在发生故障时如何进行服务恢复和数据同步操作。

# 获取元数据服务的同步状态
$ beegfs-ctl --resyncstats --nodetype=meta --mirrorgroupid=1
Job state: Not started
# of discovered dirs: 0
# of discovery errors: 0
# of synced dirs: 0
# of synced files: 0
# of dir sync errors: 0
# of file sync errors: 0
# of client sessions to sync: 0
# of synced client sessions: 0
session sync error: No
# of modification objects synced: 0
# of modification sync errors: 0

# 获取存储服务的同步状态
$ beegfs-ctl --resyncstats --nodetype=storage --mirrorgroupid=1
Job state: Not started
# of discovered dirs: 0
# of discovered files: 0
# of dir sync candidates: 0
# of file sync candidates: 0
# of synced dirs: 0
# of synced files: 0
# of dir sync errors: 0
# of file sync errors: 0
# 模拟Boddy Group存储服务的Failover

# 模拟写入1GB数据
$ cd /mnt/beegfs/buddy-dir
dd if=/dev/zero of=testdata bs=1G count=1
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 1.59144 s, 675 MB/s

# 登陆node301,停止beegfs-storage服务
systemctl stop beegfs-storage

# 查询存储服务,301的目标服务已经变为Offline状态
$ beegfs-ctl --listtargets --nodetype=storage --state
TargetID     Reachability  Consistency   NodeID
========     ============  ===========   ======
    3011          Offline         Good      301
    3012          Offline         Good      301
    3021           Online         Good      302
    3022           Online         Good      302
    3031           Online         Good      303
    3032           Online         Good      303
    
# 继续模拟写入1GB数据,服务是可用的
dd if=/dev/zero of=testdata2 bs=1G count=1
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 3.67663 s, 292 MB/s

# 恢复301节点的存储服务
$ systemctl start beegfs-storage

# 301节点的存储服务在自动恢复
$ beegfs-ctl --listtargets --nodetype=storage --state
TargetID     Reachability  Consistency   NodeID
========     ============  ===========   ======
    3011           Online         Good      301
    3012           Online Needs-resync      301
    3021           Online         Good      302
    3022           Online         Good      302
    3031           Online         Good      303
    3032           Online         Good      303

# 使用命令手动触发数据同步
$ beegfs-ctl --startresync --nodetype=storage --targetid=3011 --timestamp=0 --restart
Waiting for running resyncs to abort.
Resync request sent.

$ beegfs-ctl --startresync --nodetype=storage --targetid=3012 --timestamp=0 --restart
Waiting for running resyncs to abort.
Resync request sent.

# 检查301节点的存储服务已经完全恢复
$ beegfs-ctl --listtargets --nodetype=storage --state
TargetID     Reachability  Consistency   NodeID
========     ============  ===========   ======
    3011           Online         Good      301
    3012           Online         Good      301
    3021           Online         Good      302
    3022           Online         Good      302
    3031           Online         Good      303
    3032           Online         Good      303
# 模拟元数据服务的Failover

# 查询元数据服务状态
$ beegfs-ctl --listtargets --nodetype=meta --state
TargetID     Reachability  Consistency   NodeID
========     ============  ===========   ======
     201           Online         Good      201
     202           Online         Good      202

# 登陆node201,停止beegfs-meta服务
$ systemctl stop beegfs-meta

# 查询元数据服务状态,201节点已经在脱机状态
$ beegfs-ctl --listtargets --nodetype=meta --state
TargetID     Reachability  Consistency   NodeID
========     ============  ===========   ======
     201 Probably-offline         Good      201
     202           Online         Good      202
     
# 模拟写入1GB数据,成功写入    
$ dd if=/dev/zero of=testdata3 bs=1G count=1
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 1.71778 s, 625 MB/s

# 查询元数据服务状态,已经完全离线
$ beegfs-ctl --listtargets --nodetype=meta --state
TargetID     Reachability  Consistency   NodeID
========     ============  ===========   ======
     201          Offline Needs-resync      201
     202           Online         Good      202

# 恢复201节点的元数据服务  
$ systemctl start beegfs-meta

# 201节点的元数据在自动恢复
$ beegfs-ctl --listtargets --nodetype=meta --state
TargetID     Reachability  Consistency   NodeID
========     ============  ===========   ======
     201           Online Needs-resync      201
     202           Online         Good      202
  
# 可以使用命令手动触发数据同步   
$ beegfs-ctl --startresync --nodetype=meta --nodeid=201
Resync request sent.

# 查询元数据服务,已经完全恢复
$ beegfs-ctl --listtargets --nodetype=meta --state
TargetID     Reachability  Consistency   NodeID
========     ============  ===========   ======
     201           Online         Good      201
     202           Online         Good      202

参考资料

 

本篇作者

唐健

AWS解决方案架构师,负责基于AWS的云计算方案的架构设计,同时致力于AWS云服务在移动应用与互联网行业的应用和推广。拥有多年移动互联网研发及技术团队管理经验,丰富的互联网应用架构项目经历。