3.3.3 CephFS 高级特性
1. Snapshot(快照)
(1) Snapshot特性介绍
CephFS 支持快照功能,快照文件被创建后将保存在快照对象目录中的隐藏子目录里。通常来说,快照功能设计是为了保存文件系统在创建快照时间点的状态视图,但为了
实现以下的附加特性,CephFS快照设计选择有别于其他几类快照。
1) 任意子树:快照可以在选择的任何目录中创建(而非仅能在根目录下创建),并覆盖该目录下文件系统中的所有数据。
2) 异步:快照创建行为异步化,创建快照后由快照数据与实时数据差异造成的数据复制和数据迁移不能影响正常读写性能,只能延缓完成。
为了实现这两点,CephFS快照使用了基于COW的实现。
(2) Snapshot 特性实现原理与细节
CephFS 快照中,较为重要的数据结构如下。
◆ SnapContext
— 个 RADOS系统的 SnapContext由一个快照序列 ID(即 snapid)列表和每一个
RADOSObject在此列表上存亡时间所对应的关联表组成(如 Object在 snap02后创建,在 snap04 后删除,在表中会有所表示)。为了生成该列表,会将与 SnapRealm关联的快照ID和其 past_parents的所有有效快照 ID组合在一起(SnapClient 的缓存模式会过滤掉过期的快照,以确定哪些是有效快照)。
◆ SnapRealm
无论在任何时候创建快照,都会生成一个SnapRealm,它的功能较为单一,主要用于将SnapContext 与每个打开的文件关联,以进行写入。SnapRealm中还包含sr_tsrnode、past_parents、past_children、inodes_with_caps等信息。
◆ sr_(t srnode)
sr_t是存储在 RADOS系统 OSD 中的文件系统快照元数据结构,包含序列计数器、时间戳、相关的快照 ID列表和 past_parent。
◆ SnapServer
SnapServer管理快照 ID 分配、快照删除,并跟踪文件系统中有效快照的列表,一个文件系统只有一个 SnapServer实例。
◆ SnapClient
SnapClient用于与SnapServer通信,每个MDSrank(每个rank视作一个元数据分片 shard,从 MDS中选出当前管理此rank的 Server)都有其自己的 SnapClient实例,SnapClient还负责在本地缓存有效快照数据。
(3) Snapshot处理细节
◆ 创建快照
CephFS内部通过在目录创建 .snap 子目录的方式管理当前目录的快照。客户端会将请求发送到MDS服务器,然后在服务器的Server::handle_client_mksnap()中处理。它会从 SnapServer中分配一个 snapid,利用新的 SnapRealm创建并链接一个新的inode,然后将其提交到 MDlog,提交后会触发 MDCache::do_realm_invalidate_and_update_notify(),此函数将此 SnapRealm广播给所有对快照目录下任一文件有管辖权的客户端。客户端收到通知后,将同步更新本地 SanpRealm层级结构,并为新的SnapRealm结构生成新的 SnapContext,用于将快照数据写入 OSD 端。同时,快照的元数据会作为目录信息的一部分更新到OSD端(即sr_t)。整个过程是完全异步处理的。
◆ 更新快照
快照信息更新分为两种情况。快照删除:这个过程和快照创建类似,不过行为都变为删除;文件或目录重命名:从父目录SnapRealm中删除这个文件或目录 inode,rename代码会为重命名的inode创建一个新的 SnapRealm,并将对旧父目录(past_parent)SnapRealm有效的快照ID保存到新的 SnapRealm的past_parent_snaps中。
◆ RADOS 存储快照数据
CephFS文件被分割成 Object后,Object层级快照行为由 RADOS自行管理。此外,在将文件数据Object写入 OSD时,还额外用到了 SnapContext这一结构。
◆ RADOS存储快照元数据 sr_t
目录快照信息(及快照本身的 Inode信息)作为目录信息的一部分字段进行存储。所有目录项的快照字段都包含其生效的第一个和最后一个Snapid(表示这个目录项创建于哪次快照,消亡于哪次快照)。未快照的目录项,将快照字段的最后位置设置为 CEPH_NOSNAP。
◆ 快照回写
当客户端收到 MClientSnap消息时,它将更新本地SnapRealm内容,并将旧 Inode链接更新为需要回写的Inode的新链接,并为这些回写的 Inode生成 CapSnap。CapSnap被用于缓冲新写入的数据,直到快照回写在 OSD中完成。
同时,另一方面,在 MDS中,会为这些 CapSnap一并记录日志,以保障这一过程的完成。
◆ 删除快照
直接尝试删除带快照的目录会失败,必须先删除快照。在客户端删除快照信息后,将发送请求给映射的OSD,使其删除相关的快照文件数据。而通过将目录信息更新覆盖后写入 OSD对象的方式,快照元数据将被异步删除。
◆ 硬链接
具有过多硬链接的 Inode将被转移到虚拟全局 SnapRealm。虚拟全局 SnapRealm覆盖文件系统中的所有快照,以处理这种棘手情况。Inode的数据将为任何新快照保留,这些保留的数据也将覆盖 Inode的任何链接上的快照。
◆ 多文件系统
需要注意的是,CephFS的快照和多个文件系统的交互是存在问题的——每个 MDS集群独立分配 snappid,如果多个文件系统共享一个池,快照会冲突。如果此时有客户删除一个快照,将会导致其他人丢失数据,并且这种情况不会提升异常,这也是 CephFS的快照不推荐使用的原因之一。
(4) Snapshot 工具命令限制总结
◆ 创建快照
默认情况下,文件系统没有启用快照功能,要想在现有文件系统上启用它,可使用以下命令开启。
#创建快照
#ceph fs set <fs_name> allow_new_snaps true
启用快照后,CephFS中的所有目录都将具有一个特殊的 .snap目录(如果需要,可以使用客户端snapdir配置其他名称)。
要创建CephFS快照,请在 .snap 目录下创建一个具有你选择的名称的子目录。例如,要在目录“/1/2/3/”上创建快照,请调用以下命令。
#在⽬录 "/1/2/3/" 上创建快照
#mkdir/1/2/3/.snap/my-snapshot-name
◆ 恢复快照
#恢复快照
#cp -ra/1/2/3/.snap/my-snapshot-name/*/1/2/3/
◆ 删除快照
#删除快照
#rmdir/1/2/3/.snap/my-snapshot-name
◆ 快照限制(“s”标志)
要创建或删除快照,客户端除了需要“rw”外还需要“s”权限标志。请注意,当权限 字符串还包含“p”标志时,“s”标志必须出现在其后(除“rw”以外的所有标志都必须按字母表顺序指定)。例如,在以下代码段中,client.0可以在子文件系统“cephfs_a”的“bar”目录中创建或删除快照。
client.0
key:AQAz7EVWygILFRAAdIcuJ12opU/JKyfFmxhuaw==
caps: [mds] allow rw allow rws path=/barcaps: [mon] allow r
caps:[osd] allow rw tag cephfs data=cephfs_a
◆ ceph-syn
ceph-syn是一个适用于 CephFS的简单的人造载荷生成器。它通过 libcephfs库在当前运行着的文件系统上生成简单的载荷,此文件系统不必通过ceph-fuse或内核客户端挂载。可以用一个或多个--syn命令参数规定特定的载荷,而此测试工具也可以用来操作快照(但作为一个测试工具,不推荐直接使用)。
#在 path上创建⼀个名为snapname的快照
#ceph-syn --syn mksnap path snapname
# 删除path上名为snapname的快照
#ceph-syn --syn rmnap path snapname
◆ cephfs-shell
cephfs-shell提供类似于 shell的命令,可以直接与 CephFS系统进行交互(需要注意的是,cephfs-shell基于Python,需要依赖 cmd2模块)。
cephfs-shell[options][command]
cephfs-shell[options] –[command command ...]
-c--config FILE // Path to cephfs-shell.conf
-b --batch FILE// Pathto batch file
-t --test FILE // Path to transcript(s) in FILE for testing
创建或删除快照:
snap {create|delete} <snap_name> <dir_name>snap_name - Snapshot name to be created or deleted
dir_name- directory under which snapshot should be created or deleted
◆ 客户端版本
Mimic版本(13版本)以后的 fuse与 lib 库客户端都可以支持快照。内核版本等于及高于 4.17的内核客户端可以支持快照,这点与之后讲述的 Quota一致。
2. Quota配额
(1) Quota特性介绍
CephFS 允许在系统中的任何目录上设置配额。配额可以限制目录层次结构中该节点下方存储的字节或文件的数量。
(2) Quota 特性实现原理与细节
目前来说,CephFSQuota 特性有以下细节。
◆ CephFSQuota是针对目录的,可限制目录下存放的文件数量和容量。
◆ CephFS 没有一个统一的UID/GID机制,传统的基于用户和组的配额管理机制很难使用。
◆ CephFS一般与客户端应用配合使用,将用户关联到对应的 CephFS目录。
(3) Quota 目前实现的局限性
◆ 配额需要客户端合作
CephFSQuota 取决于挂载文件系统的客户端的合作,以在达到限制时停止写入程序。CephFS 服务端本身不能阻止客户端写入所需数量的数据,在客户端完全不受信任的环境中,Quota无法阻止客户端填满文件系统。
◆ Quota控制时间因素不精确
达到Quota 限制后,写入文件系统的进程将在短时间内停止而非立刻停止。客户端将不可避免地被允许写入超出配置限制的数据量。一般而言,在超出配置的限制后的 10s(取决于检测已使用 Quota 的时间间隔,此参数可以调整,但一般推荐默认为10s,过短可能会影响性能)内,进程将被停止写入。
◆ Quota仅在内核版本等于及高于 4.17的内核客户端中实现
Mimic版本(13版本)以后的 fuse与 lib库客户端都可以支持Quota。内核版本等于及高于 4.17的内核客户端可以支持 Quota。
◆ 在与基于路径的访问限制一起使用时,必须仔细配置 Quota
基于路径限制挂载时必须谨慎地配置 Quota。客户端必须能够访问配置了Quota的那个目录的索引节点,这样才能执行Quota管理。如果某一客户端被 MDS能力限制成了只能访问一个特定路径(如/home/user),并且无权访问配置了Quota的父目录(如/ home),这个客户端就不会受父目录(如/home)的限制去执行Quota。所以,基于路径做访问控制时,最好在限制了客户端的那个目录(如 /home/user)或者它更下层的子目录上配置 Quota。
◆ 快照未计入 Quota
目前创建快照造成的COW 增量数据未被计入Quota 进行限制。避免出现此种状况的基本方法是不要同时使用快照和Quota功能。快照 COW增量数据计入Quota统计有待未来开发。
(4) Quota工具命令总结
CephFS的 mount方式分为内核态 mount和用户态 mount,内核态使用 mount命令挂载,用户态使用ceph-fuse命令挂载。内核态只有在 kernel4.17+ Cephmimic以上的版本才支持 Quota,用户态则没有限制。
◆ 内核态 mount与用户态 mount挂载
#内核态 mount
# mount -t ceph 192.168.3.1:/test /mnt/cephfs/ -o name=adminsecret=AQCs2Q9bqAjCHRAAlQUF+hAiXhbErk4NdtvORQ==
# ⽤户态mount
#ceph-fuse -r/test /mnt/cephfs/ --nameclient.admin
◆ 配置 Quota
# ⾸先在 CephFS创建⼀个要限额的⽬录
#mkdir /mnt/cephfs
#ceph-fuse/mnt/Cephfs
# 然后在⽬录上使⽤ setfattr设置限额属性
#setfattr-n ceph.quota.max_bytes-v100000000 /mnt/cephfs/test
3. QoS服务质量
(1) QoS特性介绍
QoS(Quality of Service,服务质量)指一个网络能够利用各种基础技术,为指定的网络通信提供更好的服务的能力,是一种用来解决网络时延和阻塞等问题的网络安全机制。 在CephFS中,目前倾向使用限流的方式来实现 QoS 目的。此功能目前尚未引入,Ceph社区考虑在 16版本及之后着手开发限流功能。
(2) QoS特性实现设想与 Ceph社区方向
目前 Ceph 社区对限流功能设想的实现方向是在客户端进行令牌桶算法流控。通过将QoS信息设置为目录的 xattrs之一(和 Quota一样)来控制流控开启、关闭与监控,同时可以使用一次 QoS设置来控制访问相同目录的所有客户端的限流。
而配置 QoS 的流程则参照Quota 的配置流程,当MDS收到 QoS 设置时,它将向所有客户端广播该信息。流控限额可以在线更改,设置以后如 Quota一样由客户端进行具体的流控行为。
Ceph 社区为限流功能预留的配置方式如下。
setfattr -n ceph.qos.limit.iops -v 200 / mnt / cephfs/ testdirs /setfattr -n ceph.qos.burst.read_bps -v 200 / mnt / cephfs / testdirs/getfattr -n ceph.qos.limit.iops / mnt / cephfs / testdirs /
getfattr -n ceph.qos /mnt / cephfs /testdirs /
Ceph社区也讨论了这样设计可能会遇到的问题。由于CephFS客户端I/O路径中没有队列,因此,如果流控小于请求的块大小,则整个客户端将被完全阻塞,直到获得足够的令牌为止。
此外,在单个共享目录多客户端共享挂载情况下,如果不对客户端分别控制,流控会变得不可预测。对于这一点,Ceph社区计划了两种模式。
1) 所有客户端都使用相同的 QoS 设置而不去理会多个客户端的情况,即干脆放任上述不可预测性。这样做的好处是不会因为总的流控限制,间接影响了客户端的可挂载数量。
2) 所有客户端共享特定的QoS设置。
◆ 设置总限制,所有客户端均受平均数限制:total_limit/clients_num。
◆ 设置总限额,mds 通过客户端的历史I/O&BPS 分担客户端的限额。