searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

CephFS元数据和数据存储设计模型

2023-09-22 08:43:43
119
0

    CephFS通过一个专门的MDS服务来管理文件系统元数据信息,MDS没有使用本地存储空间,而是将元数据存储在RADOS底座里面,元数据和数据使用不同的存储池来存储,做到元数据和数据分离。

    Client和MDS之间进行元数据和Caps交互,Client直接将文件数据存储到RADOS底座,MDS也将日志和元数据存储到RADOS底座。 

1 CephFS元数据设计

      CephFS元数据包括Inode、Dentry和Dir,在MDS代码实现里分别对应CInode、CDentry和CDir。

      Inode记录文件或目录的元数据,如文件大小、创建时间、所属存储池等信息,每个文件或目录都有一个Inode。

      Dentry记录文件或目录名,与Inode相关联,实现如硬链接等功能。

      Dir树状结构,用于链接目录下的Dentry。当单个Dir下Dentry数超过阈值,或者Dir下部分Dentry的负载超过阈值时,Dir会进行分片,产生多个Dir。

2 CephFS元数据、数据存储

    CephFS存储池包括元数据池和数据池,Inode、Dentry、Dir等元数据存储在元数据池中,文件数据存储在数据池内。具体而言元数据散落在元数据池的各个RADOS对象的KV存储内(OMAP/Xattr),数据则按照切分规则散布在数据池的各个RADOS对象的数据部分。

2.1 元数据和数据存储模型

元数据存储模型:
    目录以Inode号和Dir编号组成Dir分片对象名存储在元数据池,每个Dir分片的Dentry以OMAP形式存储在Dir分片对象的OMAP中。OMAP的每个key由目录下文件名/子目录名加上_head后缀组成,OMAP的每个key对应的value就是对应Dentry的Inode信息。

数据存储模型:
    文件数据按切分规则(默认按4MB切分)切分成N块,Inode号和分块号组成分块对象名,然后各个分块对象按照CRUSH算法分布到数据池的各个OSD上。

2.2 使用Ceph工具查看存储模型

接下来我们在CephFS里实际创建目录并写入文件来验证CephFS的存储模型。验证分析使用的CephFS存储池情况如下:

$ ceph fs ls
name: a, metadata pool: cephfs.a.meta, data pools: [cephfs.a.data ]

其中cephfs.a.meta是元数据池,cephfs.a.data是数据池。
准备工作,首先创建/testdir目录,并写入2个文件:

$ mkdir testdir
$ dd if=/dev/urandom of=testdir/testfileA bs=1M count=9
$ dd if=/dev/urandom of=testdir/testfileB bs=1M count=3

2.2.1 查看元数据存储模型

(1)查看testdir目录的Inode号,然后去元数据池找对应的Dir对象

$ ll -i
total 1
1099511629781 drwxrwxr-x 2 db db 0 May 25 16:52 testdir

testdir的Inode号是1099511629781,将它转化成16进制形式:

$ printf "%x\n" 1099511629781
100000007d5

(2)刷新CephFS journal日志,强制将修改立即应用到元数据对象上:

$ ceph daemon mds.a flush journal
{
    "message": "",
    "return_code": 0
}

(3)然后在元数据池里就可以看到testdir目录对应的RADOS对象了:

$ rados -p cephfs.a.meta ls | grep 100000007d5
100000007d5.00000000

100000007d5是testdir 16进制形式的Inode号,00000000是16进制形式的分片ID,由于testdir目录中只有2个文件没有达到目录分片的条件所以目前只有一个目录分片对象。

(4)查看testdir目录下的Dentry

$ rados -p cephfs.a.meta listomapkeys 100000007d5.00000000
testfileA_head
testfileB_head

可以看到目录对象100000007d5.00000000的OMAP key就是由我们之前创建的testfileA和testfileB加上_head后缀组成的。

(5)查看Dentry对应的Inode信息
Dentry编码格式可以查看src/mds/CDir.cc中的CDir::_encode_dentry函数。
获取testfileA_head的OMAP value:

rados -p cephfs.a.meta getomapval 100000007d5.00000000 testfileA_head ~/out/testfileA-InodeStoreBare

移除头部的8字节snapid_t和1字节'L'/'I'标记:

$ dd if=testfileA-InodeStoreBare  of=testfileA-InodeStoreBare.skip bs=9 skip=1

使用ceph-dencoder来导出InodeStoreBare信息:

可以看到testilfeA的Inode号1099511629783以及文件大小9437184,都和通过文件系统标准命令ls -li看到的一样。

$ ls -li
total 12288
1099511629783 -rw-rw-r-- 1 db db 9437184 May 25 19:06 testfileA
1099511629784 -rw-rw-r-- 1 db db 3145728 May 25 19:06 testfileB

2.2.2查看数据存储模型

(1)将ls -li命令看到的testfileA和testfileB的十进制Inode号转化成16进制

$ printf "%x\n" 1099511629783
100000007d7
$ printf "%x\n" 1099511629784
100000007d8

(2)在数据池中查看以16进制Inode号和分块号组成分块对象名

$ rados -p cephfs.a.data ls | sort
100000007d7.00000000
100000007d7.00000001
100000007d7.00000002
100000007d8.00000000

可以看到9MB的testfileA有3个数据对象,3MB的testfileB有1个数据对象。
查看每个RADOS对象大小,可以看到9MB的testfileA由2个4MB的对象文件和1个1MB的对象文件组成;3MB的testfileB由1个3MB的对象文件组成。

$ rados -p cephfs.a.data stat 100000007d7.00000000
cephfs.a.data/100000007d7.00000000 mtime 2021-05-25 19:06:36.000000, size 4194304
$ rados -p cephfs.a.data stat 100000007d7.00000001
cephfs.a.data/100000007d7.00000001 mtime 2021-05-25 19:06:20.000000, size 4194304
$ rados -p cephfs.a.data stat 100000007d7.00000002
cephfs.a.data/100000007d7.00000002 mtime 2021-05-25 19:06:20.000000, size 1048576

$ rados -p cephfs.a.data stat 100000007d8.00000000
cephfs.a.data/100000007d8.00000000 mtime 2021-05-25 19:06:36.000000, size 3145728
0条评论
作者已关闭评论
sky
4文章数
0粉丝数
sky
4 文章 | 0 粉丝
原创

CephFS元数据和数据存储设计模型

2023-09-22 08:43:43
119
0

    CephFS通过一个专门的MDS服务来管理文件系统元数据信息,MDS没有使用本地存储空间,而是将元数据存储在RADOS底座里面,元数据和数据使用不同的存储池来存储,做到元数据和数据分离。

    Client和MDS之间进行元数据和Caps交互,Client直接将文件数据存储到RADOS底座,MDS也将日志和元数据存储到RADOS底座。 

1 CephFS元数据设计

      CephFS元数据包括Inode、Dentry和Dir,在MDS代码实现里分别对应CInode、CDentry和CDir。

      Inode记录文件或目录的元数据,如文件大小、创建时间、所属存储池等信息,每个文件或目录都有一个Inode。

      Dentry记录文件或目录名,与Inode相关联,实现如硬链接等功能。

      Dir树状结构,用于链接目录下的Dentry。当单个Dir下Dentry数超过阈值,或者Dir下部分Dentry的负载超过阈值时,Dir会进行分片,产生多个Dir。

2 CephFS元数据、数据存储

    CephFS存储池包括元数据池和数据池,Inode、Dentry、Dir等元数据存储在元数据池中,文件数据存储在数据池内。具体而言元数据散落在元数据池的各个RADOS对象的KV存储内(OMAP/Xattr),数据则按照切分规则散布在数据池的各个RADOS对象的数据部分。

2.1 元数据和数据存储模型

元数据存储模型:
    目录以Inode号和Dir编号组成Dir分片对象名存储在元数据池,每个Dir分片的Dentry以OMAP形式存储在Dir分片对象的OMAP中。OMAP的每个key由目录下文件名/子目录名加上_head后缀组成,OMAP的每个key对应的value就是对应Dentry的Inode信息。

数据存储模型:
    文件数据按切分规则(默认按4MB切分)切分成N块,Inode号和分块号组成分块对象名,然后各个分块对象按照CRUSH算法分布到数据池的各个OSD上。

2.2 使用Ceph工具查看存储模型

接下来我们在CephFS里实际创建目录并写入文件来验证CephFS的存储模型。验证分析使用的CephFS存储池情况如下:

$ ceph fs ls
name: a, metadata pool: cephfs.a.meta, data pools: [cephfs.a.data ]

其中cephfs.a.meta是元数据池,cephfs.a.data是数据池。
准备工作,首先创建/testdir目录,并写入2个文件:

$ mkdir testdir
$ dd if=/dev/urandom of=testdir/testfileA bs=1M count=9
$ dd if=/dev/urandom of=testdir/testfileB bs=1M count=3

2.2.1 查看元数据存储模型

(1)查看testdir目录的Inode号,然后去元数据池找对应的Dir对象

$ ll -i
total 1
1099511629781 drwxrwxr-x 2 db db 0 May 25 16:52 testdir

testdir的Inode号是1099511629781,将它转化成16进制形式:

$ printf "%x\n" 1099511629781
100000007d5

(2)刷新CephFS journal日志,强制将修改立即应用到元数据对象上:

$ ceph daemon mds.a flush journal
{
    "message": "",
    "return_code": 0
}

(3)然后在元数据池里就可以看到testdir目录对应的RADOS对象了:

$ rados -p cephfs.a.meta ls | grep 100000007d5
100000007d5.00000000

100000007d5是testdir 16进制形式的Inode号,00000000是16进制形式的分片ID,由于testdir目录中只有2个文件没有达到目录分片的条件所以目前只有一个目录分片对象。

(4)查看testdir目录下的Dentry

$ rados -p cephfs.a.meta listomapkeys 100000007d5.00000000
testfileA_head
testfileB_head

可以看到目录对象100000007d5.00000000的OMAP key就是由我们之前创建的testfileA和testfileB加上_head后缀组成的。

(5)查看Dentry对应的Inode信息
Dentry编码格式可以查看src/mds/CDir.cc中的CDir::_encode_dentry函数。
获取testfileA_head的OMAP value:

rados -p cephfs.a.meta getomapval 100000007d5.00000000 testfileA_head ~/out/testfileA-InodeStoreBare

移除头部的8字节snapid_t和1字节'L'/'I'标记:

$ dd if=testfileA-InodeStoreBare  of=testfileA-InodeStoreBare.skip bs=9 skip=1

使用ceph-dencoder来导出InodeStoreBare信息:

可以看到testilfeA的Inode号1099511629783以及文件大小9437184,都和通过文件系统标准命令ls -li看到的一样。

$ ls -li
total 12288
1099511629783 -rw-rw-r-- 1 db db 9437184 May 25 19:06 testfileA
1099511629784 -rw-rw-r-- 1 db db 3145728 May 25 19:06 testfileB

2.2.2查看数据存储模型

(1)将ls -li命令看到的testfileA和testfileB的十进制Inode号转化成16进制

$ printf "%x\n" 1099511629783
100000007d7
$ printf "%x\n" 1099511629784
100000007d8

(2)在数据池中查看以16进制Inode号和分块号组成分块对象名

$ rados -p cephfs.a.data ls | sort
100000007d7.00000000
100000007d7.00000001
100000007d7.00000002
100000007d8.00000000

可以看到9MB的testfileA有3个数据对象,3MB的testfileB有1个数据对象。
查看每个RADOS对象大小,可以看到9MB的testfileA由2个4MB的对象文件和1个1MB的对象文件组成;3MB的testfileB由1个3MB的对象文件组成。

$ rados -p cephfs.a.data stat 100000007d7.00000000
cephfs.a.data/100000007d7.00000000 mtime 2021-05-25 19:06:36.000000, size 4194304
$ rados -p cephfs.a.data stat 100000007d7.00000001
cephfs.a.data/100000007d7.00000001 mtime 2021-05-25 19:06:20.000000, size 4194304
$ rados -p cephfs.a.data stat 100000007d7.00000002
cephfs.a.data/100000007d7.00000002 mtime 2021-05-25 19:06:20.000000, size 1048576

$ rados -p cephfs.a.data stat 100000007d8.00000000
cephfs.a.data/100000007d8.00000000 mtime 2021-05-25 19:06:36.000000, size 3145728
文章来自个人专栏
流直存
3 文章 | 1 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0