1. 指标
通过底层零碎数据的拉通,数据治理对立数据口径,实现控制塔 KPI 体系的线上数字化存储计算和灵便展示,撑持我的项目的顺利落地。
2. 方案设计
2.1 支流 ETL 工具调研
维度 \ 产品 | DataPipeline | kettle | Oracle Gaodengate | Informatica | talend | Datax | |
---|---|---|---|---|---|---|---|
性能 | 实用场景 | 次要用于各类数据交融、数据交换场景,专为超大数据量、高度简单的数据链路设计的灵便、可扩大的数据交换平台 | 面向数据仓库建模传统 ETL 工具 | 次要用于数据备份、容灾 | 面向数据仓库建模传统 ETL 工具 | 面向数据仓库建模传统 ETL 工具 | 面向数据仓库建模传统 ETL 工具 |
应用形式 | 全流程图形化界面,利用端采纳 B / S 架构,Cloud Native 为云而生,所有操作在浏览器内就能够实现,不须要额定的开发和生产公布 | C/ S 客户端模式,开发和生产环境须要独立部署,工作的编写、调试、批改都在本地,须要公布到生产环境,线上生产环境没有界面,须要通过日志来调试、debug,效率低,费时费力 | 没有图形化的界面,操作皆为命令行形式,可配置能力差 | C/ S 客户端模式,开发和生产环境须要独立部署,工作的编写、调试、批改都在本地,须要公布到生产环境;学习老本较高,个别须要受过专业培训的工程师能力应用; | C/ S 客户端模式,开发和生产环境须要独立部署,工作的编写、调试、批改都在本地,须要公布到生产环境; | DataX 是以脚本的形式执行工作的,须要齐全吃透源码才能够调用,学习老本高,没有图形开发化界面和监控界面,运维老本绝对高。 | |
底层架构 | 分布式集群高可用架构,能够程度扩大到多节点反对超大数据量,架构容错性高,能够主动调节工作在节点之间调配,实用于大数据场景 | 主从构造非高可用,扩展性差,架构容错性低,不实用大数据场景 | 可做集群部署,躲避单点故障,依赖于外部环境,如 Oracle RAC 等; | schema mapping 非主动;可复制性比拟差;更新换代不是很强 | 反对分布式部署 | 反对单机部署和集群部署两种形式 | |
CDC 机制 | 基于日志、基于工夫戳和自增序列等多种形式可选 | 基于工夫戳、触发器等 | 次要是基于日志 | 基于日志、基于工夫戳和自增序列等多种形式可选 | 基于触发器、基于工夫戳和自增序列等多种形式可选 | 离线批处理 | |
对数据库的影响 | 基于日志的采集形式对数据库无侵入性 | 对数据库表构造有要求,存在肯定侵入性 | 源端数据库须要预留额定的缓存空间 | 基于日志的采集形式对数据库无侵入性 | 有侵入性 | 通过 sql select 采集数据,对数据源没有侵入性 | |
主动断点续传 | 反对 | 不反对 | 反对 | 不反对,依赖 ETL 设计的合理性(例如 T -1),指定续读某个工夫点的数据,非主动 | 不反对,依赖 ETL 设计的合理性(例如 T -1),指定续读某个工夫点的数据,非主动 | 不反对 | |
监控预警 | 可视化的过程监控,提供多样化的图表,辅助运维,故障问题可实时预警 | 依赖日志定位故障问题,往往只能是后处理的形式,短少过程预警 | 无图形化的界面预警 | monitor 能够看到报错信息,信息绝对抽象,定位问题仍需依赖剖析日志 | 有问题预警,定位问题仍需依赖日志 | 依赖工具日志定位故障问题,没有图形化运维界面和预警机制,须要自定义开发。 | |
数据荡涤 | 围绕数据品质做轻量荡涤 | 围绕数据仓库的数据需要进行建模计算,荡涤性能绝对简单,须要手动编程 | 轻量荡涤 | 反对简单逻辑的荡涤和转化 | 反对简单逻辑的荡涤和转化 | 须要依据本身清晰规定编写荡涤脚本,进行调用(DataX3.0 提供的性能)。 | |
数据转换 | 自动化的 schema mapping | 手动配置 schema mapping | 需手动配置异构数据间的映射 | 手动配置 schema mapping | 手动配置 schema mapping | 通过编写 json 脚本进行 schema mapping 映射 | |
特色 | 数据实时性 | 实时 | 非实时 | 实时 | 反对实时,然而支流利用都是基于工夫戳等形式做批量解决,实时同步效率未知 | 实时 | 定时 |
利用难度 | 低 | 高 | 中 | 高 | 中 | 高 | |
是否须要开发 | 否 | 是 | 是 | 是 | 是 | 是 | |
易用性 | 高 | 低 | 中 | 低 | 低 | 低 | |
稳定性 | 高 | 低 | 高 | 中 | 中 | 中 | |
其余 | 施行及售后服务 | 原厂施行和售后服务 | 开源软件,需自客户自行施行、保护 | 原厂和第三方的施行和售后服务 | 次要为第三方的施行和售后服务 | 分为开源版和企业版,企业版可提供相应服务 | 阿里开源代码,须要客户主动施行、开发、保护 |
2.2 kettle 应用体验
根据上述调研,抉择了最风行且收费的 kettle 作为体验对象。
- 长处:
- 无需开发,通过界面操作,即可实现数据 ETL 流程(对非开发人员敌对)。
- 毛病:
- 对开发人员来说,新增同步时,界面操作的效率,不肯定比本人实现的效率高。
- 简单的计算逻辑依然须要写代码,并且是在工具的界面上,按工具要求的标准来写。
根据上述体验后果,联合以后业务“有大量的计算字段”的特点,最终抉择了自主开发计划。
2.3 自主开发计划
- 数据同步计划
- ETL 繁难流程
3. 计划实现
3.1 设计准则
宽表同步 & 计算有以下特点:
- 须要从多个业务表中同步数据,每个表都要执行“查问数据“和”映射字段值到宽表中 ”,同时后续可能会新增映射字段(包含新加原始业务表)。
- 除了已有的业务字段外,宽表还有依据以后字段计算出来的“计算结果”字段,并且后续也可能会 继续新增 此类字段。
- 流程环节可能会新增,也可能会删除。
以上都是可预感的会扩大、批改比拟频繁的点,依据 开闭准则
(对扩大凋谢,对批改敞开),将业务表的数据查问和映射剥离进去,提供形象对象来反对扩大;“计算结果”字段也是一样; 将每个流程环节独立成一个类
,多个类按程序串成一个链,新增 / 删除的时候就在链中插入 / 删除节点。
3.2 具体流程
3.3 JAVA 类图
3.4 重点类介绍
3.4.1 通用对象:
- BaseMerger:封装了流程通用的“启动流程前”、“执行流程”、“流程失常执行实现(失常执行实现时进入)”、“流程异样解决(异样时进入)”、“流程执行实现(不论是否异样都会进入本办法)”办法,同时提供扩大办法“流程名称”,由子类实现,用于获取子类须要的流程节点列表(从所有的 FlowNode 列表中筛选出属于该流程的列表)。
- MergeContext:上下文对象,用于在各个节点中传递数据。
- BaseFlowNode:流程节点父类,封装了每个节点执行时通用的办法,如日志记录,子类只须要实现外围的“doExecute”办法即可。
-
BaseLoopFlowNode:可循环的流程节点父类,当流程判断(以后节点为 BaseLoopFlowNode 子类,且上下文中“循环次数”> 1 时),会开始进入循环状态,直到(下一个节点不是 BaseLoopFlowNode,且循环次数达到最大次数)时,才会跳出循环。
protected void executeFlow(MergeContext<T> context) {BaseFlowNode<T> currentNode = flowNodes.get(0); BaseFlowNode<T> beginLoopNode = null; do {if (!context.isRunning()) {break;} currentNode.execute(context); int totalLoopTimes = context.getTotalLoopTimes(); // 循环节点,且须要循环 if (currentNode instanceof BaseLoopFlowNode && totalLoopTimes > 0) { // 启动循环 if (beginLoopNode == null) {beginLoopNode = currentNode;} BaseFlowNode<T> nextFlowNode = currentNode.getNext(); // 最初一个节点 if (nextFlowNode == null) { // 然而还未达到最大循环次数 if (context.getCurrentLoopTimes() < totalLoopTimes - 1) { // 重头开始循环 currentNode = beginLoopNode; // 循环次数加 1 context.setCurrentLoopTimes(context.getCurrentLoopTimes() + 1); } else { // 完结循环 ((BaseLoopFlowNode) currentNode).resetLoop(context); beginLoopNode = null; currentNode = nextFlowNode; } } else {if (nextFlowNode instanceof BaseLoopFlowNode) { // 下一个节点也是循环中的一部分 currentNode = nextFlowNode; } else if (context.getCurrentLoopTimes() < totalLoopTimes - 1) { // 还未达到最大循环次数 // 重头开始循环 currentNode = beginLoopNode; // 循环次数加 1 context.setCurrentLoopTimes(context.getCurrentLoopTimes() + 1); } else { // 完结循环 ((BaseLoopFlowNode) currentNode).resetLoop(context); beginLoopNode = null; currentNode = nextFlowNode; } } } else { // 循环完结、或者还没开始、或者不须要循环 currentNode = currentNode.getNext();} } while (currentNode != null); }
3.4.2 具体流程对象
- LqPrDetailMergeConvertor:依据“开闭准则”拆出来的对象,当读取到的业务表数据须要映射到宽表对象时,在此类做批改。
- BaseDataExtractor:依据“开闭准则”拆出来的形象对象,须要从业务表中“读取数据”、“过滤数据”时,增加此类的实现类即可。
- BaseCalculator:依据“开闭准则”拆出来的形象对象,须要对宽表的某个字段做计算或者调整时,增加此类的实现类即可。
参考
六种 支流 ETL 工具的比拟