dcf运行机制


难度 中等

dcf通过stream的概念来运行分布式协议,每个stream是一个完整的分布式实例。
每个stream可以由多个节点组成。

外部应用启动接口

dcf在初次启动后,会将传入的配置文件信息写入到metadata里,也就是说dcf为了设计成一个通用的库,是不需要配置文件的。
整个运行启动都是通过传参的方式来启动,这样就可以把参数配置放在外部应用程序内。

应用通过json字符串数组传入参数,在初次传入时dcf会将元信息持久化到文件中,默认在应用执行目录下面,并按照节点id命名目录存储。
当应用再次启动时,就会直接读取持久化到文件的信息,而不会再读取传入的json字符串。
其中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内部从dcf_start开启启动,dcf_start需要每个节点都运行,并且需要传入节点id和集群配置json字符串。

int dcf_start(unsigned int node_id, const char *cfg_str);

dcf内部采用的是多线程模型,在启动后需要初始化各个线程。具体包括如下几个方面:

  • metadata(元数据,简称md)
  • network(消息通信,简称mec)
  • log store(日志持久化存储,简称stg)
  • election(投票,简称elc)
  • replication(流复制,简称rep)

metadata

若元数据目录已存在,直接从文件中读取元数据。若元数据目录不存在,则根据传入的json字符串解析元数据信息并写入文件。
同时会将流的相关配置信息加载到内存中,后续会根据这些配置进行初始化。

network

mec模块主要是负责网络通信的,采用自己管理内存的方式申请分配内存,因而需要先初始化内存池,并且采用伙伴算法进行内存分配。
网络模块有一个全局实例g_mec,用于保存mec相关的数据结构。

typedef struct st_mec_instance {
    mec_profile_t      profile; ///< mec主要信息
    mq_context_t       send_mq; ///< 发送队列
    mq_context_t       recv_mq; ///< 接收队列
    mec_context_t      mec_ctx; ///< mec上下文
    fragment_ctx_t     fragment_ctx; ///< 分片上下文
    thread_t           daemon_thread;///< 守护线程id
    reactor_pool_t     reactor_pool[PRIV_CEIL]; ///< epoll反应堆数组
    agent_pool_t       agent_pool[PRIV_CEIL]; ///< 代理池
    ssl_ctx_t         *ssl_acceptor_fd; ///< ssl接受器
    ssl_ctx_t         *ssl_connector_fd;///< ssl连接器
} mec_instance_t;
static mec_instance_t *g_mec = NULL;

mec模块会初始化g_mec,首先是需要设置其配置,也就是profile,其中profile需要设置如下信息:

typedef struct st_mec_profile {
    spinlock_t           lock; ///< 自旋锁
    uint16               inst_id; ///< mec实例id
    volatile uint16      inst_count; ///< mec实例个数
    mec_addr_t           inst_arr[CM_MAX_NODE_COUNT]; ///< mec地址数组
    int16                maps[CM_MAX_NODE_COUNT];     ///< 节点数组
    uint8                pipe_type; ///< 管道类型
    uint8                reserved;  ///< 预留
    uint16               channel_num; ///< 通道数
    uint64               msg_pool_size; ///< 消息池大小
    uint32               frag_size; ///< 分片大小
    uint32               batch_size; ///< 批量包大小
    uint32               agent_num; ///< 代理数量
    uint32               reactor_num; ///< 反应堆数量
    compress_algorithm_t algorithm; ///< 压缩算法
    uint32               level;  
    int32                connect_timeout;  // ms
    int32                socket_timeout;   // ms
} mec_profile_t;

mec通信层面使用reactor模型,并将其分为agent和reactor,agent+reactor=mec,同时mec又分为高优先级和低优先级。
而agent和reactor的个数则由上面提到的配置传入。agent和reacor都是线程池,有任务来的时候就会attach到对应的线程上去执行。

log store

election

replication


文章作者: growdu
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 growdu !
  目录
分类导航
随笔2 AI27 算法1 计算机基础13 博客搭建7 ChatGPT2 集群63 计算机通信1 数据库34 数据库深入80 DPDK26 Docker11 Elasticsearch4 编辑工具4 FAQ1 Go Web1 hometown2 编程语言16 网络9 OPC1 Linux38 openGauss4 页面12 PostgreSQL54 程序员自我修养1 协议11 成长之路1 stock1 存储5 工具20 VPP18 视频作品1 Vue13 Web1 代码示例11 数据库15 BenchmarkSQL1 PostgreSQL 源码修炼之路14
最热文章
1
13 逻辑复制深入
数据库深入🔥 1570
2
0 Postgresql存储、索引及系统优化、主备切换
PostgreSQL🔥 1495
3
一文读懂openguass dcf网络模块
集群🔥 1420
4
逻辑复制源码分析
数据库深入🔥 1327
5
PostgreSQL 分区表:从一行 `PARTITION BY` 到路由热路径的全链路拆解
数据库🔥 1094
6
applyparallelworker.c 之 LA 端源码深度解析:Leader Apply Worker 的指挥中枢
数据库深入🔥 1082
7
PostgreSQL Background Worker 全解:从 `RegisterBackgroundWorker` 到逻辑复制 4 类 worker 的全生命周期
数据库🔥 1078
8
PostgreSQL的后台进程walsender分析 - 关系型数据库 - 亿速云
PostgreSQL🔥 1033
9
PostgreSQL 逻辑复制的监控:六张视图 + 一组可执行 SQL,把 publisher/subscriber 的速率与健康度彻底看透
数据库🔥 1032
10
PostgreSQL 逻辑复制支持 DDL 之后:DDL 与 DML 的时序难题(重点:分区表)
数据库🔥 999
11
reorderbuffer.c 源码深度解析:PostgreSQL 逻辑复制的"事务重组引擎
数据库深入🔥 953
12
PostgreSQL 内核开发:读取一张表的 9 步标准流程与缓存全景
数据库🔥 938
13
从 `postgres` 二进制到生产级守护 —— PostgreSQL 最外层模块与启动全流程拆解
数据库🔥 936
14
支持逻辑复制同步 DDL 适配 SQL Server 方案
数据库深入🔥 934
15
PostgreSQL 逻辑复制的 ReorderBuffer 与事务机制:从一行 WAL 到一致性变更流的全链路绑定
数据库🔥 913
16
DDL同步架构(美化版)
数据库深入🔥 908
17
PostgreSQL Latch 机制详解:从一行 SetLatch 到 epoll 的内核之旅
数据库🔥 871
18
pgbench 源码全解:一个 C 文件如何撑起 PostgreSQL 官方压测工具
数据库🔥 860
19
PostgreSQL libpq 机制与缓冲区详解
数据库🔥 850
20
PostgreSQL 逻辑复制 spill 文件深度剖析:从 `xid-*.spill` 到 TPC-C 的增长方程
数据库🔥 845