DM 源码阅读系列文章(二)整体架构介绍
2019独角兽企业重金招聘Python工程师标准>>>
作者:张学程
本文为 DM 源码阅读系列文章的第二篇,第一篇文章 简单介绍了 DM 源码阅读的目的和规划,以及 DM 的源码结构以及工具链。从本篇文章开始,我们会正式开始阅读 DM 的源码。
本篇文章主要介绍 DM 的整体架构,包括 DM 有哪些组件、各组件分别实现什么功能、组件之间交互的数据模型和 RPC 实现。
整体架构
通过上面的 DM 架构图,我们可以看出,除上下游数据库及 Prometheus 监控组件外,DM 自身有 DM-master、DM-worker 及 dmctl 这 3 个组件。其中,DM-master 负责管理和调度数据同步任务的各项操作,DM-worker 负责执行具体的数据同步任务,dmctl 提供用于管理 DM 集群与数据同步任务的各项命令。
DM-master
DM-master 的入口代码在 cmd/dm-master/main.go
,其中主要操作包括:
调用
cfg.Parse
解析命令行参数与参数配置文件调用
log.SetLevelByString
设置进程的 log 输出级别调用
signal.Notify
注册系统 signal 通知,用于接受到指定信号时退出进程等调用
server.Start
启动 RPC server,用于响应来自 dmctl 与 DM-worker 的请求
在上面的操作中,可以看出其中最关键的是步骤 4,其对应的实现代码在 dm/master/server.go
中,其核心为 Server
这个 struct,其中的主要 fields 包括:
rootLis, svr
:监听网络连接,分发 RPC 请求给对应的 handler。workerClients
:维护集群各 DM-worker ID 到对应的 RPC client 的映射关系。taskWorkers
:维护用于执行各同步(子)任务的 DM-worker ID 列表。lockKeeper
:管理在协调处理 sharding DDL 时的 lock 信息。sqlOperatorHolder
:管理手动 skip/replace 指定 sharding DDL 时的 SQL operator 信息。
在本篇文章中,我们暂时不会关注 lockKeeper
与 sqlOperatorHolder
,其具体的功能与代码实现会在后续相关文章中进行介绍。
在 DM-master Server 的入口方法 Start
中:
通过
net.Listen
初始化rootLis
并用于监听 TCP 连接(借助 soheilhy/cmux,我们在同一个 port 同时提供 gRPC 与 HTTP 服务)。根据读取的配置信息(
DeployMap
),初始化用于连接到各 DM-worker 的 RPC client 并保存在workerClients
中。通过
pb.RegisterMasterServer
注册 gRPC server(svr
),并将该Server
作为各 services 的 implementation。调用
m.Serve
开始提供服务。
DM-master 提供的 RPC 服务包括 DM 集群管理、同步任务管理等,对应的 service 以 Protocol Buffers 格式定义在 dm/proto/dmmaster.proto
中,对应的 generated 代码在 dm/pb/dmmaster.pb.go
中。各 service 的具体实现在 dm/master/server.go
中(*Server
)。
DM-worker
DM-worker 的结构与 DM-master 类似,其入口代码在 cmd/dm-worker/main.go
中。各 RPC services 的 Protocol Buffers 格式定义在 dm/proto/dmworker.proto
中,对应的 generated 代码在 dm/pb/dmworker.pb.go
中,对应的实现代码在 dm/worker/server.go
中(*Server
)。DM-worker 的启动流程与 DM-master 类似,在此不再额外说明。
Server
这个 struct 的主要 fields 除用于处理 RPC 的 rootLis
与 svr
外,另一个是用于管理同步任务与 relay log 的 worker
(相关代码在 dm/worker/worker.go
中)。
在 Worker
这个 struct 中,主要 fields 包括:
subTasks
:维护该 DM-worker 上的所有同步子任务信息。relayHolder
:对 relay 处理单元相关操作进行简单封装,转发相关操作请求给 relay 处理单元,获取 relay 处理单元的状态信息。relayPurger
:根据用户配置及相关策略,尝试定期对 relay log 进行 purge 操作。
数据同步子任务管理的代码实现主要在 dm/worker/subtask.go
中, relay 处理单元管理的代码实现主要在 dm/worker/relay.go
中,对 relay log 进行 purge 操作的代码实现主要在 relay/purger
pkg 中。在本篇文章中,我们暂时只关注 DM 架构相关的实现,上述各功能的具体实现将在后续的相关文章中展开介绍。
Worker
的入口方法为 Start
,其中的主要操作包括:
通过
w.relayHolder.Start
启动 relay 处理单元,开始从上游拉取 binlog。通过
w.relayPurger.Start
启动后台 purge 线程,尝试对 relay log 进行定期 purge。
其他的操作主要还包括处理 Server
转发而来的同步任务管理、relay 处理单元管理、状态信息查询等。
dmctl
dmctl 的入口代码在 cmd/dm-ctl/main.go
,其操作除参数解析与 signal 处理外,主要为调用 loop
进入命令处理循环、等待用户输入操作命令。
在 loop
中,我们借助 chzyer/readline 提供命令行交互环境,读取用户输入的命令并输出命令执行结果。一个命令的处理流程为:
调用
l.Readline
读取用户输入的命令判断是否需要退出命令行交互环境(exit 命令)或需要进行处理
调用
ctl.Start
进行命令分发与处理
dmctl 的具体命令处理实现在 dm/ctl
pkg 中,入口为 dm/ctl/ctl.go
中的 Start
方法,命令的分发与参数解析借助于 spf13/cobra。命令的具体功能实现在相应的子 pkg 中:
master
:dmctl 与 DM-master 交互的命令,是当前 DM 推荐的命令交互方式。worker
:dmctl 与 DM-worker 交互的命令,主要用于开发过程中进行 debug,当前并没有实现所有 DM-worker 支持的命令,未来可能废弃。common
:多个命令依赖的通用操作及 dmctl 依赖的配置信息等。
每个 dmctl 命令,其主要对应的实现包括 3 个部分:
在各命令对应的实现源文件中,通过
New***Cmd
形式的方法创建cobra.Command
对象。在
dm/ctl/ctl.go
中通过调用rootCmd.AddCommand
添加该命令。在各命令对应的实现源文件中,通过
***Func
形式的方法实现参数验证、RPC 调用等具体功能。
任务管理调用链示例
让我们用一个启动数据同步任务的操作示例来说明 DM 中的组件交互与 RPC 调用流程。
用户在 dmctl 命令行交互环境中输入 start-task 命令及相应参数。
dmctl 在
dm/ctl/ctl.go
的Start
方法中进行命令分发,请求dm/ctl/master/start_task.go
中的startTaskFunc
处理命令。startTaskFunc
通过cli.StartTask
调用 DM-master 上的 RPC 方法。DM-master 中的
Server.StartTask
方法(dm/master/server.go
)响应来自 dmctl 的 RPC 请求。Server.Start
从workerClients
中获取任务对应 DM-worker 的 RPC client,并通过cli.StartSubTask
调用 DM-worker 上的 RPC 方法。DM-worker 中的
Server.StartSubTask
方法(dm/worker/server.go
)响应来自 DM-master 的 RPC 请求。Server.StartSubTask
中将任务管理请求转发给Worker.StartSubTask
(dm/worker/worker.go
),并将处理结果通过 RPC 返回给 DM-master。DM-master 将 DM-worker 返回的 RPC 响应重新封装后通过 RPC 返回给 dmctl。
dmctl 通过
common.PrettyPrintResponse
输出命令操作的 RPC 响应。
小结
在本篇文章中,我们主要介绍了 DM 的各个组件的入口函数,最后以 dmctl 的 start-task 为例介绍了交互的调用流程细节。下一篇文章我们会开始介绍 DM-worker 组件内各数据同步处理单元(relay-unit, dump-unit, load-unit, sync-unit)的设计原理与具体实现。
转载于:https://my.oschina.net/zhaiyuan/blog/3027804
DM 源码阅读系列文章(二)整体架构介绍相关推荐
- DM 源码阅读系列文章(四)dump/load 全量同步的实现
作者:杨非 本文为 DM 源码阅读系列文章的第四篇,上篇文章 介绍了数据同步处理单元实现的功能,数据同步流程的运行逻辑以及数据同步处理单元的 interface 设计.本篇文章在此基础上展开,详细介绍 ...
- TiDB 源码阅读系列文章(十九)tikv-client(下)
上篇文章 中,我们介绍了数据读写过程中 tikv-client 需要解决的几个具体问题,本文将继续介绍 tikv-client 里的两个主要的模块--负责处理分布式计算的 copIterator 和执 ...
- TiDB 源码阅读系列文章(五)TiDB SQL Parser 的实现
本文为 TiDB 源码阅读系列文章的第五篇,主要对 SQL Parser 功能的实现进行了讲解,内容来自社区小伙伴--马震(GitHub ID:mz1999 )的投稿. TiDB 源码阅读系列文章的撰 ...
- TiDB 源码阅读系列文章(六)Select 语句概览
在先前的 TiDB 源码阅读系列文章(四) 中,我们介绍了 Insert 语句,想必大家已经了解了 TiDB 是如何写入数据,本篇文章介绍一下 Select 语句是如何执行.相比 Insert,Sel ...
- TiDB 源码阅读系列文章(十五)Sort Merge Join
2019独角兽企业重金招聘Python工程师标准>>> 什么是 Sort Merge Join 在开始阅读源码之前, 我们来看看什么是 Sort Merge Join (SMJ),定 ...
- TiDB 源码阅读系列文章(十六)INSERT 语句详解
在之前的一篇文章 <TiDB 源码阅读系列文章(四)INSERT 语句概览> 中,我们已经介绍了 INSERT 语句的大体流程.为什么需要为 INSERT 单独再写一篇?因为在 TiDB ...
- TiDB 源码阅读系列文章(六)Select 语句概览 1
在先前的 TiDB 源码阅读系列文章(四) 中,我们介绍了 Insert 语句,想必大家已经了解了 TiDB 是如何写入数据,本篇文章介绍一下 Select 语句是如何执行.相比 Insert,Sel ...
- JDK1.8源码阅读系列之二:LinkedList
本篇随笔主要描述的是我阅读 LinkedList 源码期间的对于 LinkedList 的一些实现上的个人理解,有不对的地方,请指出- 先来看一下 LinkedList 的继承图: 由于 Abstra ...
- Spring源码阅读笔记(一):整体架构与核心技术
本篇的主要是根据Spring的官方文档加以整理,旨在理解Spring的整体架构与核心技术的基本概念,建立Spring的基本模型. 1. Spring整体架构 Spring框架是一种分层架构,它包含了一 ...
最新文章
- mysql dba系统学习(6)二进制日志binlog之二
- BZOJ 1443 二分图博弈 网络流
- python 生成html文件浏览器_Handout库:能将python脚本转化为html展示文件
- [转载] 弄懂JDK、JRE和JVM到底是什么
- 微信分享接口调用(自测通过可以用)
- MapInfo地图查询的简单实现
- 源码 | 幽灵交易者策略
- 使用u盘安装linux操作系统原理
- 苹果电脑操作系统的演变历程
- 如何用photoshop做24色环_PS色相环制作方法和教程
- pdf打印去掉页眉页脚(兼容ie)
- Ubuntu的一些高(sao)效(cao)率(zuo)工具
- 吃白菜一样用micropython玩esp32(三)—— 触摸按键、ADC
- Google文档初学者指南
- Qt Creator5.7添加qwt绘图插件之成功案例解析
- 存储历史(从古老的绳子记忆到如今)
- 笔记本计算机屏幕亮度暗,笔记本屏幕暗,详细教您怎么解决
- 学会记录生活的每件小事
- 使用Wordpress搭建个人博客网站
- Win11 msconfig修改后无法使用系统解决方法
热门文章
- CSS 基础知识(一)
- Leaflet中使用Leaflet.Spin插件实现地图加载等待效果
- MyBatis中提示:Invalid Bound statemnet(not found )com.
- ASP.NET中新建Web网站并部署到IIS上(详细图文教程)
- Winform中简单使用MD5加密用户登录密码
- Winform中使用控件的Dock属性设计窗体布局,使不随窗体缩放而改变
- C#中使用Process调取Windows中的进程(应用程序)
- SSM中向后端传递的属性为多个对象的实现方法
- SpringBoot中整合Mail实现发送带附件的邮件
- linux双机热备 oracle,oracle for linux双机热备实战