注意
本文档适用于 Ceph 开发版本。
文件布局
文件的布局控制其内容如何映射到 Ceph RADOS 对象。您可以使用虚拟扩展属性或 xattrs。
客户端在写入文件的布局时必须使用p
标志。参见布局.
布局 xattrs 的名称取决于文件是普通文件还是目录。普通文件的布局 xattrs 称为ceph.file.layout
,而目录的布局 xattrs 称为ceph.dir.layout
。当后续示例引用ceph.file.layout
时,在处理目录时应适当替换dir
。
提示
您的 Linux 发行版可能默认不提供用于操作 xattrs 的命令,所需的软件包通常称为attr
.
布局字段
- pool
这是一串字符,包含 ID 或名称。字符串只能包含
[a-zA-Z0-9\_-.]
集合中的字符。这决定了存储文件数据对象的 RADOS- pool_id
这是一串数字。这是 Ceph 在创建 RADOS 池时分配的池 ID。
- pool_name
这是一串字符。这是用户在创建池时定义的 RADOS 池名称。
- pool_namespace
这是一串仅包含
[a-zA-Z0-9\_-.]
集合中字符的字符串。这决定了数据池中对象将被写入哪个 RADOS 命名空间。- stripe_unit
这是一个整数。文件数据分布中使用的数据块的大小(以字节为单位)。文件的所有 stripe_unit 具有相同的大小。最后一个 stripe_unit 通常只有部分满:它包含文件数据直到 EOF 以及填充固定 stripe_unit 大小剩余空间的填充。
- stripe_count
整数。构成文件数据 RAID 0 “stripe” 的连续 stripe_unit 数量。
- object_size
整数。对象的大小(以字节为单位)。文件数据被分块成此大小的 RADOS 对象。
提示
RADOS 对对象大小执行可配置的限制:如果您将 CephFS 对象大小增加到该限制以上,则写入可能不会成功。OSD 设置是osd_max_object_size
,默认为 128MB。
使用 ... 读取布局getfattr
将布局信息作为单个字符串读取:
$ touch file
$ getfattr -n ceph.file.layout file
# file: file
ceph.file.layout="stripe_unit=4194304 stripe_count=1 object_size=4194304 pool=cephfs_data"
读取单个布局字段:
$ getfattr -n ceph.file.layout.pool_name file
# file: file
ceph.file.layout.pool_name="cephfs_data"
$ getfattr -n ceph.file.layout.pool_id file
# file: file
ceph.file.layout.pool_id="5"
$ getfattr -n ceph.file.layout.pool file
# file: file
ceph.file.layout.pool="cephfs_data"
$ getfattr -n ceph.file.layout.stripe_unit file
# file: file
ceph.file.layout.stripe_unit="4194304"
$ getfattr -n ceph.file.layout.stripe_count file
# file: file
ceph.file.layout.stripe_count="1"
$ getfattr -n ceph.file.layout.object_size file
# file: file
ceph.file.layout.object_size="4194304"
Note
在读取布局时,池通常会以名称指示。然而,在池刚刚创建的罕见情况下,可能会输出 ID 而不是名称。
目录直到自定义之前没有明确的布局。如果从未修改过布局,则读取布局的尝试将失败:这表示将使用具有明确布局的下一个祖先目录的布局。
$ mkdir dir
$ getfattr -n ceph.dir.layout dir
dir: ceph.dir.layout: No such attribute
$ setfattr -n ceph.dir.layout.stripe_count -v 2 dir
$ getfattr -n ceph.dir.layout dir
# file: dir
ceph.dir.layout="stripe_unit=4194304 stripe_count=2 object_size=4194304 pool=cephfs_data"
以 json 格式获取布局。如果没有为特定 inode 设置特定的布局,系统会向后遍历目录路径,找到具有布局的最近祖先目录并以 json 格式返回它。ceph.file.layout.json
vxattr。
添加一个名为inheritance
的虚拟字段到 json 输出来显示布局的状态。inheritance
可以具有以下值:
@default
表示系统默认布局@set
表示为该特定 inode 设置了特定布局@inherited
表示返回的布局已从祖先继承
$ getfattr -n ceph.dir.layout.json --only-values /mnt/mycephs/accounts
{"stripe_unit": 4194304, "stripe_count": 1, "object_size": 4194304, "pool_name": "cephfs.a.data", "pool_id": 3, "pool_namespace": "", "inheritance": "@default"}
使用 ... 写入布局setfattr
使用setfattr
:
$ ceph osd lspools
0 rbd
1 cephfs_data
2 cephfs_metadata
$ setfattr -n ceph.file.layout.stripe_unit -v 1048576 file2
$ setfattr -n ceph.file.layout.stripe_count -v 8 file2
$ setfattr -n ceph.file.layout.object_size -v 10485760 file2
$ setfattr -n ceph.file.layout.pool -v 1 file2 # Setting pool by ID
$ setfattr -n ceph.file.layout.pool -v cephfs_data file2 # Setting pool by name
$ setfattr -n ceph.file.layout.pool_id -v 1 file2 # Setting pool by ID
$ setfattr -n ceph.file.layout.pool_name -v cephfs_data file2 # Setting pool by name
Note
修改布局字段。setfattr
修改文件的布局字段时,此文件必须为空,否则将发生错误。
# touch an empty file
$ touch file1
# modify layout field successfully
$ setfattr -n ceph.file.layout.stripe_count -v 3 file1
# write something to file1
$ echo "hello world" > file1
$ setfattr -n ceph.file.layout.stripe_count -v 4 file1
setfattr: file1: Directory not empty
文件和目录布局也可以使用 json 格式设置。inheritance
在设置布局时会被忽略。pool_name
和pool_id
字段,则pool_name
会优先考虑以更好地消除歧义。
$ setfattr -n ceph.file.layout.json -v '{"stripe_unit": 4194304, "stripe_count": 1, "object_size": 4194304, "pool_name": "cephfs.a.data", "pool_id": 3, "pool_namespace": "", "inheritance": "@default"}' file1
清除布局
如果您希望从目录中删除明确的布局,恢复到继承其祖先的布局,您可以这样做:
setfattr -x ceph.dir.layout mydir
类似地,如果您设置了pool_namespace
属性并希望
# Create a dir and set a namespace on it
mkdir mydir
setfattr -n ceph.dir.layout.pool_namespace -v foons mydir
getfattr -n ceph.dir.layout mydir
ceph.dir.layout="stripe_unit=4194304 stripe_count=1 object_size=4194304 pool=cephfs_data_a pool_namespace=foons"
# Clear the namespace from the directory's layout
setfattr -x ceph.dir.layout.pool_namespace mydir
getfattr -n ceph.dir.layout mydir
ceph.dir.layout="stripe_unit=4194304 stripe_count=1 object_size=4194304 pool=cephfs_data_a"
布局的继承
文件在创建时继承其父目录的布局。但是,对父目录布局的后续更改不会影响子文件。
$ getfattr -n ceph.dir.layout dir
# file: dir
ceph.dir.layout="stripe_unit=4194304 stripe_count=2 object_size=4194304 pool=cephfs_data"
# Demonstrate file1 inheriting its parent's layout
$ touch dir/file1
$ getfattr -n ceph.file.layout dir/file1
# file: dir/file1
ceph.file.layout="stripe_unit=4194304 stripe_count=2 object_size=4194304 pool=cephfs_data"
# Now update the layout of the directory before creating a second file
$ setfattr -n ceph.dir.layout.stripe_count -v 4 dir
$ touch dir/file2
# Demonstrate that file1's layout is unchanged
$ getfattr -n ceph.file.layout dir/file1
# file: dir/file1
ceph.file.layout="stripe_unit=4194304 stripe_count=2 object_size=4194304 pool=cephfs_data"
# ...while file2 has the parent directory's new layout
$ getfattr -n ceph.file.layout dir/file2
# file: dir/file2
ceph.file.layout="stripe_unit=4194304 stripe_count=4 object_size=4194304 pool=cephfs_data"
如果中间目录没有设置布局,作为目录后代的文件也会继承布局:
$ getfattr -n ceph.dir.layout dir
# file: dir
ceph.dir.layout="stripe_unit=4194304 stripe_count=4 object_size=4194304 pool=cephfs_data"
$ mkdir dir/childdir
$ getfattr -n ceph.dir.layout dir/childdir
dir/childdir: ceph.dir.layout: No such attribute
$ touch dir/childdir/grandchild
$ getfattr -n ceph.file.layout dir/childdir/grandchild
# file: dir/childdir/grandchild
ceph.file.layout="stripe_unit=4194304 stripe_count=4 object_size=4194304 pool=cephfs_data"
添加数据存储池到文件系统
在您可以使用池与 CephFS 之前,必须将其添加到元数据服务器。
$ ceph fs add_data_pool cephfs cephfs_data_ssd
$ ceph fs ls # Pool should now show up
.... data pools: [cephfs_data cephfs_data_ssd ]
确保您的 cephx 密钥允许客户端访问此新池。
然后,您可以在 CephFS 中更新目录的布局以使用您添加的池:
$ mkdir /mnt/cephfs/myssddir
$ setfattr -n ceph.dir.layout.pool -v cephfs_data_ssd /mnt/cephfs/myssddir
现在在该目录中创建的所有新文件都将继承其布局并将其数据放置在您新添加的池中。
您可能会注意到,即使文件正在您添加的池中创建,您的主要数据池(传递给fs new
的那个)中的对象计数仍在继续增加。这是正常的:文件数据存储在布局指定的池中,但所有文件的一小部分元数据都保留在主要数据池中。
由 Ceph 基金会带给您
Ceph 文档是一个社区资源,由非盈利的 Ceph 基金会资助和托管Ceph Foundation. 如果您想支持这一点和我们的其他工作,请考虑加入现在加入.