注意
本文档适用于 Ceph 的开发版本。
CephFS 快照
CephFS 支持快照,通常通过在 .snap 目录中调用 mkdir 来创建。请注意,这是一个隐藏的特殊目录,在目录列表中不可见。
概述
通常,快照正如其名:它们创建文件系统在拍摄快照时的时间点上的不可变视图。CephFS 快照与您可能预期的不同之处在于以下几个主要功能:
任意子树。快照创建在您选择的任何目录中,并涵盖该目录下文件系统中的所有数据。
异步。如果您创建快照,缓冲的数据会被延迟刷新,包括来自其他客户端的数据。因此,“创建”快照非常快。
重要数据结构
SnapRealm:每当您在层次结构中的新位置创建快照(或者当一个已拍摄快照的 inode 被移出其父快照之外时),就会创建一个 SnapRealm。SnapRealms 包含一个 sr_t srnode 以及作为快照一部分的 inodes_with_caps。客户端也有一个 SnapRealm 概念,它维护较少的数据,但用于将 SnapContext 与每个用于写入的打开文件相关联。
sr_t:sr_t 是磁盘上的快照元数据。它是包含目录的一部分,包含序列计数器、时间戳、关联快照 ID 列表和 past_parent_snaps。
SnapServer:SnapServer 管理快照 ID 分配、快照删除并跟踪文件系统中有效快照的列表。一个文件系统只有一个 SnapServer 实例。
SnapClient:SnapClient 用于与 SnapServer 通信,每个 MDS rank 都有自己的 SnapClient 实例。SnapClient 还在本地缓存有效快照。
创建快照
CephFS 快照功能在新文件系统上默认启用。要在现有文件系统上启用它,请使用以下命令。
$ ceph fs set <fs_name> allow_new_snaps true
启用快照后,CephFS 中的所有目录都会有一个特殊的 .snap 目录。(如果您愿意,可以使用 client snapdir 设置配置不同的名称。)
要创建 CephFS 快照,请在 .snap 下创建一个您选择名称的子目录。例如,要在目录“/1/2/3/”上创建快照,请调用 mkdir /1/2/3/.snap/my-snapshot-name 。
注意
快照名称不能以下划线 (‘_’) 开头,因为这些名称保留供内部使用。
注意
快照名称不能超过 240 个字符。这是因为 MDS 在内部使用长快照名称,其格式为:_<SNAPSHOT-NAME>_<INODE-NUMBER>。由于文件名通常不能超过 255 个字符,而 <node-id> 占用 13 个字符,因此长快照名称最多可以占用 255 - 1 - 1 - 13 = 240 个字符。
这作为带有 CEPH_MDS_OP_MKSNAP 标签的 MClientRequest 传输给 MDS 服务器,并最初在 Server::handle_client_mksnap() 中处理。它从 SnapServer 分配一个 snapid,用新的 SnapRealm 投射一个新的 inode,并像往常一样将其提交给 MDLog。提交后,它会调用 MDCache::do_realm_invalidate_and_update_notify(),它会通知所有在“/1/2/3/”下拥有文件能力的客户端有关新 SnapRealm 的信息。当客户端收到通知时,它们会更新客户端的 SnapRealm 层次结构,将“/1/2/3/”下的文件链接到新的 SnapRealm,并为新的 SnapRealm 生成一个 SnapContext。
请注意,这不是快照创建的同步部分!
更新快照
如果您删除快照,则会遵循类似的过程。如果您将 inode 从其父 SnapRealm 中删除,重命名代码会为重命名的 inode 创建一个新的 SnapRealm(如果 SnapRealm 尚不存在),将原始父 SnapRealm 上有效的快照 ID 保存到新 SnapRealm 的 past_parent_snaps 中,然后遵循类似于创建快照的过程。
生成 SnapContext
RADOS SnapContext 由快照序列 ID (snapid) 和对象已是其一部分的所有快照 ID 组成。为了生成该列表,我们结合了与 SnapRealm 关联的 snapids 和 past_parent_snaps 中所有有效的 snapids。陈旧的 snapids 通过 SnapClient 缓存的有效快照进行过滤。
存储快照数据
文件数据存储在 RADOS “自管理”快照中。客户端在使用正确的 SnapContext 将文件数据写入 OSD 时会非常小心。
存储快照元数据
已拍摄快照的目录项(及其 inodes)作为其在拍摄快照时所在的目录的一部分进行内联存储。所有目录项都包含一个 first 和 last snapid,表示它们有效的快照范围。(非快照目录项的 last 将设置为 CEPH_NOSNAP)。
快照回写
有大量的代码用于高效地处理回写。当客户端收到 MClientSnap 消息时,它会更新本地 SnapRealm 表示及其与特定 Inodes 的链接,并为 Inode 生成一个 CapSnap。CapSnap 作为能力回写的一部分被刷新出去,如果存在脏数据,CapSnap 将用于阻塞新数据写入,直到快照完全刷新到 OSDs。
在 MDS 中,我们生成代表快照的目录项作为刷新它们的常规过程的一部分。具有未完成 CapSnap 数据的目录项保持固定并保留在日志中。
删除快照
通过对其根目录下的“.snap”目录调用“rmdir”来删除快照。(尝试删除根目录下的快照目录将失败;您必须首先删除快照。)删除后,它们会进入 OSDMap 的已删除快照列表,并且文件数据由 OSDs 删除。随着目录对象被读入并再次写出,元数据将被清理。
硬链接
具有多个硬链接的 Inode 被移动到一个虚拟的全局 SnapRealm。虚拟 SnapRealm 涵盖文件系统中的所有快照。inode 的数据将为任何新快照保留。这些保留的数据将涵盖 inode 任何链接上的快照。
多文件系统
快照和多文件系统不能很好地协同工作。具体来说,每个 MDS 集群独立分配 snapids;如果您有多个文件系统共享一个池(通过命名空间),它们的快照将发生冲突,删除一个快照将导致其他快照丢失文件数据。(这甚至可能是不可见的,不会向用户抛出错误。)如果每个文件系统都有自己的池,那么事情可能会奏效,但这尚未经过测试,也可能不正确。
注意
为了避免 mon-managed 快照和文件系统快照之间的快照 ID 冲突,不允许将具有 mon-managed 快照的池附加到文件系统。此外,也不能在已附加到文件系统的池中创建 mon-managed 快照。