注意
本文档适用于 Ceph 开发版本。
与POSIX的差异
CephFS旨在尽可能遵循POSIX语义。例如,与许多其他常见的网络文件系统(如NFS)相比,CephFS在客户端之间维护强大的缓存一致性。目标是,通过文件系统通信的进程在不同主机上和在同一个主机上的行为应该相同。
然而,由于各种原因,CephFS在某些方面偏离了严格的POSIX语义:
如果客户端正在写入文件并且失败,其写入操作不一定具有原子性。也就是说,客户端可能在一个使用O_SYNC打开的文件上调用write(2),使用一个8MB的缓冲区,然后崩溃,而写入可能只部分应用。(几乎所有文件系统,即使是本地文件系统,都有这种行为。)
在共享同时写入的情况下,跨越对象边界的写入操作不一定具有原子性。这意味着你可能有写入者A写入“aa|aa”,写入者B同时写入“bb|bb”(其中|是对象边界),最终得到“aa|bb”而不是正确的“aa|aa”或“bb|bb”。
稀疏文件错误地传播到stat(2)的st_blocks字段。因为CephFS没有明确跟踪文件哪些部分已分配/写入,所以st_blocks字段总是由文件大小除以块大小来填充。这将导致像du(1)这样的工具高估已使用的空间。(CephFS维护的递归大小字段在其计数中也包括文件“空洞”。)
当文件通过mmap(2)在多个主机上映射到内存时,写入操作不会一致地传播到其他客户端的缓存。也就是说,如果一个页面在主机A上缓存,然后在主机B上更新,主机A的页面不会一致地失效。(共享可写mmap似乎非常罕见——我们还没有听到任何关于这种行为的投诉,并且正确实现缓存一致性非常复杂。)
CephFS客户端呈现一个隐藏的
.snap
目录,用于访问、创建、删除和重命名快照。尽管虚拟目录被排除在readdir(2)之外,但任何尝试创建具有相同名称的文件或目录的进程都会收到一个错误代码。此隐藏目录的名称可以在挂载时通过-o snapdirname=.somethingelse
(Linux)或配置选项client_snapdir
(libcephfs,ceph-fuse)更改。CephFS目前不维护
atime
字段。大多数应用程序并不关心,但这会影响一些备份和数据层应用程序,这些应用程序可以将未使用的数据移动到二级存储系统。对于某些用例,您可能能够找到解决方法,因为CephFS确实支持设置atime
samba-container镜像 - 由Ceph管理setattr
操作。
观点
人们经常谈论“POSIX合规性”,但实际上大多数文件系统实现并没有严格遵守规范,包括像ext4和XFS这样的本地Linux文件系统。例如,出于性能原因,读取的原子性要求被放宽:处理从正在写入的文件中读取可能会看到撕裂的结果。
类似地,当多个客户端与相同的文件或目录交互时,NFS具有非常弱的连贯性语义,转而选择“接近打开”。在网络附加存储的世界中,大多数环境使用NFS,服务器文件系统是否“完全POSIX”可能并不重要,客户端应用程序是否注意到取决于客户端之间是否共享数据。NFS还可能“撕裂”并发写入的结果,因为客户端数据可能直到文件关闭之前甚至没有刷新到服务器(并且更普遍地,写入将比CephFS显著延迟,导致结果不太可预测)。
无论如何,这些都与POSIX非常相似,应用程序仍然大部分时间都能正常工作。许多其他存储系统(例如,HDFS)声称是“POSIX-like”,但通过放弃对原地文件修改、截断或目录重命名等特性的支持,与标准有显著差异。
总结
CephFS比本地Linux内核文件系统放松得更多(例如,跨越对象边界的写入可能会撕裂)。在多客户端连贯性方面,它比NFS放松得严格少,在写入原子性方面,它通常也比NFS放松得少。
换句话说,在POSIX方面,
HDFS < NFS < CephFS < {XFS, ext4}
fsync()和错误报告
POSIX对fsync报告错误后inode的状态有些模糊。通常,CephFS使用客户端内核中的标准错误报告机制,因此遵循与其他文件系统相同的约定。
在现代Linux内核(v4.17或更高版本)中,写回错误会报告给错误发生时打开的每个文件描述符。此外,在文件描述符打开之前发生的未报告错误也将在fsync时返回。
请参阅PostgreSQL对跨操作系统的fsync()错误报告的总结和Matthew Wilcox关于Linux IO错误处理的演讲 for more information.
由 Ceph 基金会带给您
Ceph 文档是一个社区资源,由非盈利的 Ceph 基金会资助和托管Ceph Foundation. 如果您想支持这一点和我们的其他工作,请考虑加入现在加入.