乐趣区

关于ceph:Cephfs数据池数据对象命名规则解析

家喻户晓,cephfs 的数据和元数据是拆散的,处于不同的 pool 池外头,而无论是 rgw、cephfs、rbd 底层的数据池的存储都是基于 RADOS(Reliable Autonomic Distributed Object Store),Ceph 存储集群的根底,RADOS 层的一切都是以对象的模式存储着的,无论下层是文件、对象还是块。

次要说说 cephfs 的文件在数据池中是如何散布的,上面以 cephfs 的内核客户端为例进行剖析。

以下图文件为例,先找到这个文件的 inode 号 1099511627776,转换为 16 进制为 10000000000,从数据池中找到这个对象,对象的名称为文件的 inode 号. 编号(数据地位 / 对象大小 object_size(默认 4M),从 0 开始编号)

Cephfs 读数据转换 osd 申请

struct ceph_file_layout {
    /* file -> object mapping */
    u32 stripe_unit;   /* stripe unit, in bytes */
    u32 stripe_count;  /* over this many objects */
    u32 object_size;   /* until objects are this big */
    s64 pool_id;        /* rados pool id */
    struct ceph_string __rcu *pool_ns; /* rados pool namespace */
};

文件的 layout 的属性,位于每个文件的 inode 属性中,是用来计算文件理论对象散布的条件。

客户端(linux 内核客户端)位于文件的扩大属性 xattr 当中,通过 set_xattr 流程(客户端入口函数__ceph_setxattr 和服务端 mds 入口函数为 Server::handle_client_setxattr)进行批改。

能够应用 getxattr 命令查看默认值,命令和回显如下:

getfattr -n ceph.file.layout ceph-debuginfo-Lakestor_v2.1.0.18-0.el7.x86_64.rpm

ceph.file.layout="stripe_unit=4194304 stripe_count=1 object_size=4194304 pool=cephfs-data”

读流程从 linux 内核客户端向 osd 服务端发动申请:
入口函数为
|__ceph_read_iter
|____ceph_get_caps(获取文件的 cap,如果 cap 不满足条件就发送 getattr 的 req 向 mds 服务端去获取最新的 inode 元数据,服务端解决实现回申请时客户端应用 handle_reply 最终 fill_inode, 将最新的元数据信息填写到客户端 inode 缓存里)
|______ceph_direct_read_write(如果客户端 dcache 没有对应地位缓存,就向 osd 发申请获取)

|__ceph_direct_read_write:
|____ceph_osdc_new_request(calc_layout-|______ceph_calc_file_object_mapping[ceph_oid_printf(&req->r_base_oid, “%llx.%08llx”, vino.ino, objnum);])
|________ceph_osdc_start_request

|__ceph_osdc_new_request:
|____calc_layout(layout, off, plen, &objnum, &objoff, &objlen):
|______ceph_calc_file_object_mapping
重要入参:1,inode 中的 layout 构造,2, 要写的偏移地位 off 和 3, 要写的长度 plen。
出参:1,要写的对象编号 objnum,2,对象内的偏移 objoff,。
|________ceph_oid_printf(&req->r_base_oid, “%llx.%08llx”, vino.ino, objnum);(将 inode 号. 对象编号拼接起来造成要写的对象名)

退出移动版