dcf配置解析机制(元数据)

dcf配置解析机制(元数据)

openguass的dcf是一个分布式一致性协议的实现(基于paxos协议,类似raft),能够实现分布式一致性数据传输和存储。

dcf通过传入json字符串来传递配置数据,如:

#1. 使能dcf特性开关
enable_dcf = on  
#2. 当前节点id, 如果集群为3节点则每个节点可分别配置为1、2、3 
dcf_node_id = 1  
#3. 指定dcf数据目录
dcf_data_path = '/xxx/cluster/data1/dn1/dcf_data'  
#4. 指定dcf集群配置信息,每个节点上dcf_config内容一致,其中配置的ip/端口专用于dcf节点间通信链路,注意与所有其他已使用的ip/端口不要配置冲突 
dcf_config = '[{"stream_id":1,"node_id":1,"ip":"x.x.x.21","port":xx,"role":"LEADER"},{"stream_id":1,"node_id":2,"ip":"x.x.x.22","port":xx,"role":"FOLLOWER"},{"stream_id":1,"node_id":3,"ip":"x.x.x.23","port":xx,"role":"FOLLOWER"}]'

其中重点关注如下json字符串,

[{
	"stream_id": 1,
	"node_id": 1,
	"ip": "x.x.x.21",
	"port": 1712,
	"role": "LEADER"
}, {
	"stream_id": 1,
	"node_id": 2,
	"ip": "x.x.x.22",
	"port": 1713,
	"role": "FOLLOWER"
}, {
	"stream_id": 1,
	"node_id": 3,
	"ip": "x.x.x.23",
	"port": 1714,
	"role": "FOLLOWER"
}]

dcf解析json字符串

dcf解析json字符串的流程大致如下:

dcf_start
init_main_threads
md_init
parse_streams_cfg

在start的时候传入cfg_str,然后在parse_streams_cfg中解析到内存中。

json字符串是以json数组方式传入的,在解析前会判断是否是json数组,如果不是json数组就会报错退出。json数组里的对象就是stream,可以配置stream相关的信息,配置了多条流后会循环解析每个stream对象。

若dcf不是第一次启动,而是之前已经启动过并保留了元数据,则在执行md_init时会先读取元数据,若能读取到元数据,即使再传入json字符串也不会再解析。也就是说,只有在第一次启动dcf时才会解析json字符串,一旦启动过一次保存了元数据后就不会再解析传入的json字符串了。

对于单个stream调用parse_stream_cfg_single,解析结果保存到dcf_streams_t,其实就是放到内存里,最终放到全局变量g_metadata中。

typedef struct st_ptlist {
    pointer_t *items;
    uint32 capacity;
    uint32 count;
} ptlist_t;

typedef struct st_streams_t {
    ptlist_t stream_list;
} dcf_streams_t;

在parse_stream_cfg_single中解析时,会解析如下配置:

  • stream_id
  • node_id
  • ip
  • port
  • role
  • weight
  • group
  • priority
    除了stream_id外,其他参数都会保存到dcf_node_t里,
typedef struct st_dcf_node {
    uint32 node_id; // 节点id
    char ip[CM_MAX_IP_LEN]; // 节点监听的ip
    uint32 port; // 节点监听的端口
    dcf_role_t default_role; // 节点默认角色
    uint32 voting_weight; // 投票的权重
    uint32 group; // 分组id
    uint64 priority; // 优先级
} dcf_node_t;

都解析成功后会将这些参数添加到stream里,

add_stream_member(streams, stream_id, &node_info);

dcf最多支持64条流,在添加时会对stream_id进行校验,节点数最多支持256个,会对node_id校验,voting_weight与node_id对应,也不能超过256.

在添加流之前还会确认这条流是否存在,如果流已经存在则无法添加成功,确认流存在后还会确认节点是否已经在这条流里面了。即流已经存在并且节点已经在这条流里面了是无法添加流成功的。

    if (stream_isexists(stream_list, stream_id)) {
        if (MD_GET_STREAMS_NODE(stream_list, stream_id, node_id) != NULL) {
            return CM_TRUE;
        }
    }

最终所有的流都被保存到了全局静态变量g_metadata的streams链表里,streams前面已经列举过。

typedef struct st_dcf_meta {
    latch_t latch;
    meta_status_t status;
    uint32 current_node_id;
    dcf_node_t* all_nodes[CM_MAX_NODE_COUNT];
    dcf_streams_t* streams;
    char* buffer;
    uint32 checksum;
} dcf_meta_t;

static dcf_meta_t g_metadata;

按照当前分析来看,一个节点可以有多条流。比如json字符串配置成这样也是可以的,

[{
	"stream_id": 1,
	"node_id": 1,
	"ip": "127.0.0.1",
	"port": 1712,
	"role": "LEADER"
}, {
	"stream_id": 1,
	"node_id": 2,
	"ip": "127.0.0.1",
	"port": 1713,
	"role": "FOLLOWER"
}, {
	"stream_id": 2,
	"node_id": 3,
	"ip": "127.0.0.1",
	"port": 1714,
	"role": "FOLLOWER"
}]

到这里json字符串就被解析到dcf进程中了,这里其实就是解析到了stream的配置。

你可能感兴趣的:(集群,openguass,分布式,算法,分布式,linux)