Ceph 学习——CRUSH算法及源码分析(二)

前一章介绍CRUSH算法的基本原理和一些基本的数据结构,这一节将介CRUSH的源码实现,主要是一些对算法实现的具体函数的介绍。
回顾 Ceph 学习——CRUSH算法及源码分析(一)
CRUSH 相关源代码 位于源码文件的 ceph/src/crush中 这个编辑器不能上传附件的吗?知道的朋友教下新手小白 怎么上传附件

相关数据结构

CRUSH 算法相关的数据结构主要有几个 分别是 crush_map、crush_bucket、crush_rule。数据结构的定义主要是在文件 Crush.h、Crush.c中,它们的内容是定义了crush_map 相关的数据结构,还有相关的destory方法(如crush_destroy()、crush_destroy_rule()、crush_destroy_bucket()等方法)。这部分代码实现不多,主要看看相关数据结构的定义即可。打开Crush.h

crush_map

首先看看crush_map的结构体定义

struct crush_map {
        /*! An array of crush_bucket pointers of size __max_buckets__.
         * An element of the array may be NULL if the bucket was removed with
         * crush_remove_bucket(). The buckets must be added with crush_add_bucket().
         * The bucket found at __buckets[i]__ must have a crush_bucket.id == -1-i.
         */
    struct crush_bucket **buckets;//动态二维数组,保存所有的bucket结构
        /*! An array of crush_rule pointers of size __max_rules__.
         * An element of the array may be NULL if the rule was removed (there is
         * no API to do so but there may be one in the future). The rules must be added
         * with crush_add_rule().
         */
    struct crush_rule **rules;//保存所有的Crush_rule 

    __s32 max_buckets; /*!< the size of __buckets__ */
    __u32 max_rules; /*!< the size of __rules__ */
        /*! The value of the highest item stored in the crush_map + 1
         */
    __s32 max_devices;
    ...
    ...
    ...

};

crush_bucket

首先看看crush_bucket的结构体定义

struct crush_bucket {
    __s32 id;        /*!< bucket identifier, < 0 and unique within a crush_map ### crush_bucket的ID,唯一且为负数 */
    __u16 type;      /*!< > 0 bucket type, defined by the caller ### 类型 ,0表示为OSD设备 */
    __u8 alg;        /*!< the item selection ::crush_algorithm ### bucket的选择算法*/
        /*! @cond INTERNAL */
    __u8 hash;       /* which hash function to use, CRUSH_HASH_* ### bucket的hash函数*/
    /*! @endcond */
    __u32 weight;    /*!< 16.16 fixed point cumulated children weight ### 权重*/
    __u32 size;      /*!< size of the __items__ array ### 该bucket下的item数量*/
    __s32 *items;    /*!< array of children: < 0 are buckets, >= 0 items ### 子item (bucket or osd)在buckets(存crush_bucket的数组)中的下标*/
};

crush_rule

enum crush_opcodes {
        /*! do nothing  定义操作码
         */
    CRUSH_RULE_NOOP = 0,
    CRUSH_RULE_TAKE = 1,          /* arg1 = value to start with */
    CRUSH_RULE_CHOOSE_FIRSTN = 2, /* arg1 = num items to pick */
                      /* arg2 = type */
    CRUSH_RULE_CHOOSE_INDEP = 3,  /* same */
    CRUSH_RULE_EMIT = 4,          /* no args */
    CRUSH_RULE_CHOOSELEAF_FIRSTN = 6,
    CRUSH_RULE_CHOOSELEAF_INDEP = 7,

    CRUSH_RULE_SET_CHOOSE_TRIES = 8, /* override choose_total_tries */
    CRUSH_RULE_SET_CHOOSELEAF_TRIES = 9, /* override chooseleaf_descend_once */
    CRUSH_RULE_SET_CHOOSE_LOCAL_TRIES = 10,
    CRUSH_RULE_SET_CHOOSE_LOCAL_FALLBACK_TRIES = 11,
    CRUSH_RULE_SET_CHOOSELEAF_VARY_R = 12,
    CRUSH_RULE_SET_CHOOSELEAF_STABLE = 13
};

 /*
 * CRUSH uses user-defined "rules" to describe how inputs should be
 * mapped to devices.  A rule consists of sequence of steps to perform
 * to generate the set of output devices.
 */
struct crush_rule_step {
    __u32 op;//对应操作步的操作码
    __s32 arg1;//若step为take 则为要选择的bucket的ID,step是select则为选择数量
    __s32 arg2;//step是select则为选择bucket的类型
};

/*
 * The rule mask is used to describe what the rule is intended for.
 * Given a ruleset and size of output set, we search through the
 * rule list for a matching rule_mask.
 */
struct crush_rule_mask {
    __u8 ruleset;//ruleset的编号
    __u8 type;//类型
    __u8 min_size;
    __u8 max_size;
};

struct crush_rule {
    __u32 len;//steps数组的长度
    struct crush_rule_mask mask;//ruleset的相关配置参数
    struct crush_rule_step steps[0];//操作步
};

相关数据结构的构造(生成实例)

这一部分主要在源代码的builder.c 和 builder.h中,在这主要是将上面的额数据结构生成对应的实例(填充数据)。
这一块不详细介绍,同样看看.h文件了解有哪些函数即可。

/** @ingroup API
 *
 * Allocate a crush_map with __malloc(3)__ and initialize it. The
 * caller is responsible for deallocating the crush_map with
 * crush_destroy().
 *
 * The content of the allocated crush_map is set with
 * set_optimal_crush_map(). The caller is responsible for setting each
 * tunable in the __crush_map__ for backward compatibility or mapping
 * stability.
 *
 * @returns a pointer to the newly created crush_map or NULL
 */
extern struct crush_map *crush_create();


/* rules */
/** @ingroup API
 *
 * If __malloc(3)__ fails, return NULL.
 *
 * @param len number of steps in the rule
 * @param ruleset user defined value
 * @param type user defined value
 * @param minsize minimum number of items the rule can map
 * @param maxsize maximum number of items the rule can map
 *
 * @returns a pointer to the newly created rule or NULL
 */
extern struct crush_rule *crush_make_rule(int len, int ruleset, int type, int minsize, int maxsize);
/** @ingroup API

 * @param rule the rule in which the step is inserted
 * @param pos the zero based step index
 * @param op one of __CRUSH_RULE_NOOP__, __CRUSH_RULE_TAKE__, __CRUSH_RULE_CHOOSE_FIRSTN__, __CRUSH_RULE_CHOOSE_INDEP__, __CRUSH_RULE_CHOOSELEAF_FIRSTN__, __CRUSH_RULE_CHOOSELEAF_INDEP__, __CRUSH_RULE_SET_CHOOSE_TRIES__, __CRUSH_RULE_SET_CHOOSELEAF_TRIES__ or __CRUSH_RULE_EMIT__
 * @param arg1 first argument for __op__
 * @param arg2 second argument for __op__
 */
extern void crush_rule_set_step(struct crush_rule *rule, int pos, int op, int arg1, int arg2);
/** &
Ceph是一个分布式存储系统,包括多个组件,其中包括Librbd块存储库。在Ceph中,Librbd提供了一种将RBD(块设备)映射到客户端的方法,并使客户端能够读写这些设备。在本文中,我们将分析Librbd块存储库的源代码以及RBD的读写过程。 1. Librbd源码分析 Librbd块存储库的源代码位于src/librbd目录下。其中,包括librbd.cc、ImageCtx.cc、ImageWatcher.cc、Journal.cc等多个源代码文件。这些源代码文件组成了Librbd块存储库的核心。 其中,librbd.cc是Librbd块存储库的主要源代码文件。在这个文件中,包括了Librbd的初始化、映射、卸载等方法。ImageCtx.cc则是Image上下文,用于管理Image的状态、锁定、映射等信息。ImageWatcher.cc用于监控Image的状态变化,Journal.cc则是Librbd的Journal日志管理。 2. RBD读写流程源码分析Ceph中,RBD由client和server两个部分组成。client在客户端上运行,提供了将RBD映射到客户端的方法。server在存储集群中运行,提供了RBD的存储和管理。 RBD的读写流程如下: 1)客户端向Ceph Monitor请求RBD映射信息,Monitor返回Image ID和Image特性; 2)客户端向Ceph OSD请求RBD数据块,OSD返回数据块内容; 3)客户端将数据写入或读取到本地块设备; 4)客户端向Ceph OSD写入或读取数据块,OSD返回操作结果; 5)客户端向Ceph Monitor请求解除RBD映射,Monitor返回解除结果。 在上述过程中,涉及到的源代码文件有:librbd.cc、ImageCtx.cc、ImageWatcher.cc、Journal.cc等。 总结 Librbd块存储库和RBD读写流程是Ceph存储系统的核心组件之一,通过分析源代码可以更加深入地了解Ceph存储系统的实现原理。同时,对于开发者来说,也有助于在Ceph存储系统上构建更加高效、稳定的存储应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值