lustre的环境
- 版本: lustre 2.14.0
[client ~]$ lfs --version
lfs 2.14.0
- 组件:1个mds,mgs和mds共享一个磁盘,后端采用ldiskfs.2个ost
[client ~]$ lctl dl |grep -v "cli"
0 UP mgc MGC10.211.55.12@tcp 668ebd57-05d7-4faf-b5af-66e997972911 4
3 UP mdc bigfs-MDT0000-mdc-ffff929ffb511000 2762b3a8-0210-4c9f-b5ab-25b059d23afd 4
4 UP osc bigfs-OST0000-osc-ffff929ffb511000 2762b3a8-0210-4c9f-b5ab-25b059d23afd 4
5 UP osc bigfs-OST0001-osc-ffff929ffb511000 2762b3a8-0210-4c9f-b5ab-25b059d23afd 4
lustre中文件数据分片模式
- 默认模式 :默认lustre集群中文件的stripe_count=1,stripe_size=1M,也就是说所有文件的数据只会落到一个ost上,数据的是被分片为多个stripe_size大小的块,存储在一个ost上,不会分不到多个ost上。默认模式,会减少文件执行
stat/unlink
的开销,stripe_count>1会导致更多的lock和网络的开销。其次是默认的模式即使出现某个ost换掉,也仅仅影响某个ost的上的数据,对于其他的ost上,数据并未做分片,也没影响。
// lustre默认的stripe_count和stripe_size
[client ~]$ lfs getstripe /mnt/lustre
/mnt/lustre
stripe_count: 1 stripe_size: 1048576 pattern: 0 stripe_offset: -1
// 这里准备15M的数据写入到集群,查看数据分布模式
[client ~]$ ls -l -1h
total 16M
-rw-r--r--. 1 root root 15M Jan 16 21:54 1.data
// 数据写入到集群
[client ~]$ cp 1.data /mnt/lustre
// 从客户端视角查看刚刚写入的数据
[client ~]$ ls -l -1h /mnt/lustre
total 12M
-rw-r--r--. 1 root root 15M Jan 16 21:56 1.data
// 1.data的的确是写入到了一个ost,这个obdidx =1 是代表了ost index=1的那个ost上
[client ~]$ lfs getstripe /mnt/lustre/1.data
/mnt/lustre/1.data
lmm_stripe_count: 1
lmm_stripe_size: 1048576
lmm_pattern: raid0
lmm_layout_gen: 0
lmm_stripe_offset: 1
obdidx objid objid group
1 34 0x22 0
- stripe模式 : 当设置文件或者目录的stripe_count>1时候,文件会被stripe到多个ost.在lustre中最佳的stripe_count应该是ost的个数。在stripe模式中,当单个ost容量不足以支撑某个文件时候,设置stripe_count>1可以让这个文件分散的存储在多个ost上。如果做了stripe_count>1的设置,某个ost换掉,那么这个文件的数据就会出现确实,存在这样的一个风险。
// 数据准备
[client ~]$ cp ../go.tar.gz ./2.data
[client ~]$ ls -l -1h
-rw-r--r--. 1 root root 3.6M Jan 16 22:00 2.data
// 准备做stripe分片的目录
[client ~]$ mkdir /mnt/lustre/stripe_dir
// 获取默认的stripe属性,模式是不分片的,继承根的挂载目录属性
[client ~]$ lfs getstripe /mnt/lustre/stripe_dir/
/mnt/lustre/stripe_dir/
stripe_count: 1 stripe_size: 1048576 pattern: 0 stripe_offset: -1
// 设置这个目录超过stripe_size的数据大小的分片个数
[client ~]$ lfs setstripe /mnt/lustre/stripe_dir -c 3
// 获取stripe_dir目录的的stripe的属性,目前是设置为3个分片
[root@CentOS-Lustre-Client ~/temp_data]$ lfs getstripe /mnt/lustre/stripe_dir/
/mnt/lustre/stripe_dir/
stripe_count: 3 stripe_size: 1048576 pattern: raid0 stripe_offset: -1
// 写入2.data到stripe_dir目录
[client ~]$ cp 2.data /mnt/lustre/stripe_dir/
// 获取2.data的stripe的信息,目前整个环境
[client ~]$ lfs getstripe /mnt/lustre/stripe_dir/2.data
/mnt/lustre/stripe_dir/2.data
lmm_stripe_count: 2
lmm_stripe_size: 1048576
lmm_pattern: raid0
lmm_layout_gen: 0
lmm_stripe_offset: 1
obdidx objid objid group
1 35 0x23 0
0 3 0x3 0
lustre中stripe属性确定文件位置
文件数据在ost上位置分析
- 当执行
lfs getstripe {mount目录}/{xx文件}
获取了文件的stripe属性,其中的obdidx objid objid group
包含了文件stripe的基本信息。obdidx是后端ost的index(当前集群有2个ost,index分别是0和1),objid代表后端ost文件系统中O/{group的值}
目录。后面两列的objid
分别代表了O/{group的值}/d{第一个objid}
的目录和O/{group的值}/d{第一个objid}/{第二个objid}
的子目录。比如下面列子中2.data文件,lmm_stripe_count是2(stripe_count=2),分别是在ost index=0和ost index=1的后端的ost上,文件的第一个分片是在ost index=0在ost index=0后端挂载对应的文件是O/0/d5/5
;而ost index=1后端挂载对应的文件是O/0/d26/38
,这个目录在后端的ost index=1中是不存在的,在O/0
下面只有,O/0/d{0~31}
32个目录,d26中不存在文件2.data的分片38.而在d6下面存在38这个文件分片,因此在lustre 2.14中当objid超过32时候,分片的目录对应的是O/0/d{objid2}/objid
. - lfs getstripe命令输出文件的布局信息,
obdidx objid objid group
,从右往左的第二个objid如果超过后端ost的目录中O/0/d{0~31}
这个的目录范围(比如d34),那么文件真是分片的的所在后端的ost目录则需要根据第二个objid重新计算,从试验的情况确认了计算规则(O/{group}/d{第二个objid2}/{第二个objid}
);如果没有超过(通常是ost index=0)的情况,ost后端的文件分片则位于O/{group}/d{第一个objid}/{第二个objid}
/************************客户端写入数据*****************/
// 准备数据
[client ~]$ ls -l -1h
-rw-r--r--. 1 root root 3.6M Jan 16 22:00 2.data
// 重新创建目录的stripe
[client ~]$ mkdir /mnt/lustre/stripe_dir
// 设置目录的stripe
[client ~]$ lfs setstripe -c 2 /mnt/lustre/stripe_dir/
// 写入数据
[client ~]$ cp 2.data /mnt/lustre/stripe_dir/
// 查看对应的对象分片的信息
[client ~]$ lfs getstripe /mnt/lustre/stripe_dir/2.data
/mnt/lustre/stripe_dir/2.data
lmm_stripe_count: 2
lmm_stripe_size: 1048576
lmm_pattern: raid0
lmm_layout_gen: 0
lmm_stripe_offset: 0
obdidx objid objid group
0 5 0x5 0
1 38 0x26 0
代码语言:javascript复制/***************ost index=0 显示后端的2.data的数据分片***********/
[ost /mnt/ost0/O/0/d5]$ ls -l -1h
total 2.0M
-rw-rw-rw- 1 root root 2.0M Jan 16 2022 5
/***************ost index=1 显示后端的2.data的数据分片***********/
[ost /mnt/ost2/O/0/d6]$ ls -l -1h
total 1.6M
-rw-rw-rw- 1 root root 1.6M Jan 16 2022 38
客户端视角查看lustre文件的inode
- 客户端的视角查看的文件inode是从fid计算出来的,fid的是有
seq、objid、version
进行计算的。具体是是通过fid_flatten
函数实现。
// lustre中的fid的定义
struct lu_fid {
// seq序号
__u64 f_seq;
// object id
__u32 f_oid;
// 版本号
__u32 f_ver;
} __attribute__((packed));
// 从fid中获取客户端查看的inode
static inline __u64 fid_flatten(const struct lu_fid *fid)
{
__u64 ino;
__u64 seq;
if (fid_is_igif(fid)) {
ino = lu_igif_ino(fid);
return ino;
}
seq = fid_seq(fid);
ino = (seq << 24) ((seq >> 24) & 0xffffff0000ULL) fid_oid(fid);
return ino ?: fid_oid(fid);
}
为了方便起见,自己写了lfs_tool工具来获取文件的fid和文件的stripe信息,整合后以json的形式dump出来,列出文件的stripe信息,包括文件的数据的所在ost的位置
代码语言:javascript复制// 查看2.data客户端视角中的文件inode信息
[client ~]$ ls -li /mnt/lustre/stripe_dir/2.data
144115205272502281 -rw-r--r--. 1 root root 3687735 Jan 16 23:14 /mnt/lustre/stripe_dir/2.data
// lfs_tool解析文件的fid,获取文件的综合信息,列举出来文件的所在ost的位置
[client ~]$ ./lfs_tool -f /mnt/lustre/stripe_dir/2.data
summary:
{
"fid_seq": 8589935617,
"fid_objid": 9,
"fid_version": 0,
"inode": 144115205272502281,
"stripe_count": 2,
"stripe_size": 1048576,
"pattern": "raid0",
"file": "/mnt/lustre/stripe_dir/2.data",
"ost_list": [
{
"index": "0",
"data_location": "O/0/d5/5"
},
{
"index": "1",
"data_location": "O/0/d6/38"
}
]
}