本文系统性梳理了大数据技术栈的7个核心层级及其组件协作关系:
数据流向分层架构
- 数据采集层(Canal/DataX):实现数据库增量监听与批量搬运
- 消息队列层(Kafka):作为流量缓冲池
- 存储层(HDFS):分布式文件存储基地
- 计算引擎层(Spark/Flink):批流处理的"烹饪系统"
- SQL层(Hive/SparkSQL):查询翻译中枢
- 数据湖表格式(Iceberg):数据版本控制系统
- OLAP层(StarRocks):实时分析展示终端
关键技术组件协作
- 通过银行实时营销案例,详解Canal→Kafka→Flink→StarRocks的全链路配合
- 对比批处理场景中DataX→HDFS→SparkSQL→GBase8a的离线处理流程
- 提供组件连接方式速查表(含协议/配置关键参数)
核心概念解析
- 元数据与数据分离存储原理
- DAG在分布式计算中的调度价值
- 批处理脚本的标准三段式结构(读-算-写)
生产实践模板
- 提供DataX同步脚本JSON示例
- 展示DolphinScheduler工作流定义规范
- 详解调度系统与执行引擎的协同机制
全文通过技术架构图、流程示意图和速查表,构建了理解大数据开发生态的系统性框架,特别强调各层级组件的定位差异与协作边界。
数据流向(从产生到展示)把技术栈分成 7 个层级,并附上 “防混淆指南”
📊 大数据技术栈“全家福”速查表
| 层级(按数据流向) | 组件 | 作用 | 最容易和谁搞混? |
|---|---|---|---|
| ① 数据源与采集 | Canal、Debezium、DataX、Sqoop、Flume | “窃听器”与“搬运工”。 Canal/Debezium偷听数据库的变化(Binlog); DataX/Sqoop是定时批量搬表; Flume专门搬日志文件。 | Canal(实时监听) vs DataX(离线批量):一个像监控摄像头(时刻盯着),一个像每天一趟的班车。 |
| ② 消息队列(缓冲) | Kafka、Pulsar、RocketMQ | “超级蓄水池”。 前端数据太快,怕系统扛不住,先扔进这里让下游慢慢消费。 | Kafka(大数据标配) vs RabbitMQ(业务系统标配):Kafka能存海量历史数据(几天),RabbitMQ主要是即时转发,存不住。 |
| ③ 分布式文件存储 | HDFS、OSS/S3(云上) | “中央大冷库”。 所有原始文件(日志、图片)分块存在多台机器的硬盘上,存得住、丢不了。 | HDFS(存文件) vs HBase(存表):HDFS像仓库堆麻袋,HBase像带索引的档案柜(能随机查)。 |
| ④ 计算引擎(核心肌肉) | Spark、Flink、MapReduce | “大厨/流水线”。 MR是慢炖老厨师(已淘汰); Spark是爆炒大厨(离线/快批); Flink是流水线宗师(实时/流式)。 | Spark(微批/快) vs Flink(真流/实时):Spark像电梯(到点了批量上人),Flink像扶梯(随来随走)。 |
| ⑤ SQL转换层(翻译官) | Hive、Spark SQL、Flink SQL、Presto/Trino | “点菜单转厨师指令”。 你写一句SQL,它翻译给底层的计算引擎去跑。 | Hive(转MR/Spark) vs Presto(联邦查询):Hive是跑批(慢但能处理巨量数据),Presto是即席查询(快但只查不存结果)。 |
| ⑥ 数据湖/表格式(新宠) | Iceberg、Hudi、Delta Lake | “数据版本管理器(Git)”。
在HDFS冷库上加一层“账本”,让数据能像代码一样回溯历史、实时更新。 | 它(表格式) vs HDFS(文件系统):HDFS是手机相册,它是相册里的“照片修改记录”(知道老照片长啥样)。 |
| ⑦ 实时OLAP数据库(终点站) | StarRocks、Doris、ClickHouse、HBase | “极速展示柜”。 清洗完的热数据存这里,供老板看实时大屏,秒级出结果。 | ClickHouse(单表快) vs Doris/StarRocks(多表Join强+实时更新好):一个偏科,一个是全能尖子生。 |
🧠 有了这张表,怎么快速分清“组合”?
平时大家聊项目,说的都是组合套餐。我拿银行举两个固定搭配,你套进表里看:
-
银行离线数仓(看昨天):① DataX(凌晨把MySQL整表搬进) → ③ HDFS(存着) → ⑤ Hive/Spark SQL(④ Spark引擎计算昨天总交易额) → ⑦ Doris(供今天上班查报表)。
-
银行实时反欺诈(看此刻):① Canal(盯着MySQL流水表) → ② Kafka(数据流进来) → ④ Flink(⑤ Flink SQL写规则,1秒内算3笔) → ⑦ StarRocks(展示预警名单)。
💡 总结
记住:Hadoop(HDFS)是硬盘,Spark/Flink是CPU,Hive/Spark SQL是方言,Kafka是传送带。
要搞清楚这些组件具体是怎么协作的,最好的方法就是跟着一条数据,走一遍完整的实时营销全链路。
下面这个流程,就是银行实时营销场景下的数据处理管道:当客户产生行为后,系统如何在秒级内做出反应,为其推荐产品。
🗺️ 全链路总览:从客户行为到精准推荐

连接点详解:组件间如何“握手”
① MySQL → Canal:监听数据变更
-
Canal 的角色:伪装成 MySQL 的一个从库(Slave)。
-
连接方式:Canal 启动后,会向 MySQL 主库发送
DUMP协议请求。 -
数据内容:MySQL 将二进制日志(Binlog) 持续推送给 Canal。Canal 解析这些日志,获取每一行数据的变更(增、删、改)。
② Canal → Kafka:分发变更事件
-
Canal Adapter 的角色:Canal 生态中的适配器组件,负责将数据从 Canal Server 转发出去。
-
连接方式:Canal Server 通过 TCP 协议将数据暴露给 Adapter;Adapter 作为 Kafka 的生产者(Producer),将数据发送到 Kafka 集群。
-
数据内容:结构化的数据变更事件(如
{"data":[{"id":"1","name":"张三"}], "type":"UPDATE"})。
③ Kafka → Flink:消费数据流
-
Flink Kafka Source 的角色:Flink 内置的消费者(Consumer) 算子。
-
连接方式:通过
Flink Kafka Connector连接。在代码中设置 Kafka 的bootstrap.servers地址、topic名称和消费组(group.id)。 -
数据内容:从 Kafka 拉取数据,转换为 Flink 内部的
DataStream数据流。
④ Flink → StarRocks:写入计算结果
-
Flink StarRocks Sink 的角色:Flink 的输出(Sink) 算子。
-
连接方式:通过
Flink StarRocks Connector连接。在 Flink SQL 中创建 StarRocks 表时,通过 WITH 参数指定连接器为starrocks-connector,并提供 JDBC URL 和认证信息。 -
数据内容:Flink 将计算好的推荐结果,以流式方式持续写入 StarRocks 的表中。
📊 技术组件“协作关系”速查表
| 协作环节 | 依赖/连接器 | 关键配置/方法 | 数据格式/协议 | 通用性说明 |
|---|---|---|---|---|
| MySQL → Canal | Canal Server | canal.instance.master.address | MySQL Binlog 协议 | 专用(与MySQL Binlog强绑定) |
| Canal → Kafka | Canal Adapter | canal.conf.mode: tcp | Protobuf | 通用(Adapter支持多种目标) |
| Kafka → Flink | flink-connector-kafka | setBootstrapServers() | 字节流/序列化后数据 | 通用(Flink标准数据源) |
| Flink → StarRocks | flink-connector-starrocks | 'connector' = 'starrocks' | SQL Row 数据 | 专用(与StarRocks绑定) |
| Flink → Doris | Flink Doris Connector | 'connector' = 'doris' | SQL Row 数据 | 专用(与Doris绑定) |
| Flink → HDFS | Hadoop 相关依赖 | 文件系统连接器 | 各种文件格式 | 通用(Flink标准文件Sink) |
希望这张“协作全景图”能帮你清晰地看到每个组件在链路中的精确位置,以及它们之间是如何具体“握手”的。以后再听到这些技术名词,就可以在脑子里把这张图调出来,不再是一团乱麻了。
理解这些技术组件如何像积木一样拆分、组合,正是看清大数据开发全貌的关键。
🧩 先理清“积木”逻辑:谁是可拆分的,谁是可组合的?
一个常见的误区是把“Hadoop”当成一个 monolithic(巨石)的应用。实际上,它是一套生态系统的总称,核心组件可以独立拆分、自由组合。
-
HDFS (Hadoop Distributed File System):“分布式硬盘”。负责存储,可以被任何需要海量存储的计算框架使用。
-
YARN (Yet Another Resource Negotiator):“资源管家”。负责管理集群的CPU和内存资源。它是一个通用的资源管理层,不是Hadoop MapReduce的专属品。Spark和Flink都可以跑在YARN上。
-
MapReduce:“一种计算模型”。它是Hadoop自带的批处理引擎,但现在更常被Spark或Flink替代。
理解了这种拆分逻辑,就能看懂各种“On”的用法了:
-
“Flink on YARN” 或 “Spark on YARN”:表示Flink/Spark 这个计算框架,跑在 YARN 这个资源管理器之上。YARN负责分配资源(给多少CPU/内存),Flink/Spark负责用这些资源进行计算。
-
“Hive on Spark”:表示Hive 这个SQL翻译官,把翻译后的执行任务,交给了 Spark 这个计算引擎去跑,而不是Hadoop自带的MapReduce。
🏦 项目一:实时营销(客户行为实时推荐)
这个场景的核心是 “快” ,客户动作刚发生,系统就要在秒级内响应。

-
数据源 (GoldenDB):银行的业务数据库,记录客户交易等行为。
-
增量采集 (Canal):Canal 监听 GoldenDB 的 Binlog,实时捕获数据变更。
-
消息队列 (Kafka):作为数据缓冲层,避免流量高峰压垮下游。
-
核心计算 (Flink on YARN):Flink 从 Kafka 消费数据,执行营销规则匹配,更新用户画像。任务跑在 YARN 上,由 YARN 统一分配资源。
-
实时分析存储 (StarRocks / GBase 8a):Flink 将计算结果写入 StarRocks 或 GBase 8a。这里GBase 8a作为高性能OLAP数据库,承担结果数据的存储和快速查询。
-
数据服务:推荐系统直接查询 StarRocks/GBase 8a,秒级获取推荐结果推送给客户。
🏦 项目二:1104 监管报送(T+1 批量报表)
这个场景的核心是 “准”和“稳” ,需要在规定时间(如T+1日)前,准确无误地生成大批量报表。

-
数据源 (GoldenDB):存放客户、账户、交易等业务数据的数据库。
-
数据同步 (DataX):每天凌晨,用 DataX 将 GoldenDB 中的业务数据批量同步到 HDFS。
-
数据湖/仓底座 (HDFS):作为统一的、低成本的海量数据存储中心。
-
ETL与计算 (Hive on Spark / Spark SQL):在 HDFS 数据上执行复杂的清洗、转换和计算逻辑。计算引擎用的是 Spark。
-
监管数据集市 (GBase 8a):将加工好的报表数据写入 GBase 8a。GBase 8a 的列式存储和压缩技术非常适合这种批量、复杂的分析查询。
-
调度与编排 (DolphinScheduler / DataWorks):DolphinScheduler 是开源的任务调度工具,DataWorks 是阿里云的全链路大数据开发治理平台,用来编排整个ETL流程,实现自动化。
-
报表生成 (1104 报送平台):最终生成符合监管要求的报表并报送。
📊 组件协作依赖关系速查表
| 协作环节 | 依赖/连接器 | 关键配置/方法 | 说明 |
|---|---|---|---|
| MySQL/GoldenDB → Canal | Canal Server | canal.instance.master.address | Canal 伪装成从库,接收 Binlog |
| Canal → Kafka | Canal Adapter | canal.conf.mode: tcp | 将变更事件转发到 Kafka |
| Kafka → Flink | flink-connector-kafka | setBootstrapServers() | Flink 的标准数据源连接器 |
| Flink → StarRocks | flink-connector-starrocks | 'connector' = 'starrocks' | 专用连接器,将流数据写入 StarRocks |
| Flink → GBase 8a | JDBC Connector | 'connector' = 'jdbc' | 通过标准 JDBC 接口写入 |
| MySQL/GoldenDB → HDFS | DataX | reader / writer 配置 | 离线批量数据同步工具 |
| Spark ↔ Hive | Hive Metastore | enableHiveSupport() | Spark 通过 Metastore 访问 Hive 表 |
| Spark/Flink ↔ YARN | YARN Client | --master yarn | 任务提交时指定 YARN 作为资源管理器 |
| 任务调度 | DolphinScheduler / DataWorks | API / Shell | 编排、调度和监控任务流 |
希望这次的梳理能帮你更好地理解这些组件之间是如何灵活组合与协作的。
Sqoop 它是 “Hadoop生态(HDFS/Hive/HBase) 与 关系型数据库(SQL库)之间的双向桥梁”。
你可以把 Sqoop 理解为两个方向的大巴车:
-
导入(Import):SQL库 → Hadoop。把 Oracle/MySQL/GoldenDB 的数据,整张表拉到 HDFS 文件里,或者直接生成 Hive 表。这是你们做离线数仓最常用的步骤(把业务库数据搬进 HDFS)。
-
导出(Export):Hadoop → SQL库。把 HDFS 上的计算结果(比如汇总报表),回写到业务库或 GBase 8a 供查询。
💡 为什么容易搞混?怎么区分?
因为你提到的 DataX 和 Sqoop 功能几乎完全一样!都是做离线批量同步的。
-
Sqoop:Apache 的开源项目,是 Hadoop 时代的“标配”,现在用的人变少了。
-
DataX:阿里巴巴开源的,功能更强,支持异构数据源(比如 CSV、MongoDB)。在你的技术栈里,DataWorks 默认集成的就是 DataX,所以如果你的项目用阿里云(DataWorks),基本就不太需要 Sqoop 了。
简单总结:Sqoop 是连接 SQL 和 HDFS 的车,不只是 Hive 的专车。 以后如果你要写 1104 报送的脚本,把 GBase 8a 的数据拉到 HDFS,这动作就叫 “Sqoop Import” 或 “DataX Reader”。
Spoon 是 Kettle(现名 Pentaho Data Integration)这款 ETL 工具的图形化桌面客户端。
它的作用就是让你通过拖拽图标、画流程图的方式,来设计数据同步和转换任务,而不用手写代码或 JSON 配置。
一句话总结:如果你觉得写 DataX 的 JSON 脚本太麻烦,Spoon 就相当于一个可视化的“DataX 画图板”,用于设计“从哪搬到哪、怎么转”的数据管道。
但它更适合传统数仓或中小规模数据量,在阿里或互联网大厂的大数据场景中,已逐渐被 DataX 或 DolphinScheduler 替代。
总结对比 DataX 、 Sqoop 、Spoon、DolphinScheduler
从工具类型、核心功能、操作方式、适用场景、大厂现状五个维度做了个对比表。建议先看最关键的 “工具类型”和 “大厂现状”,那是区分它们的第一道分水岭:
| 对比维度 | DataX | Sqoop | Spoon (Kettle) | DolphinScheduler |
|---|---|---|---|---|
| 工具类型 | 离线数据同步工具(专注于搬数据) | 离线数据同步工具(专注于搬数据) | ETL 设计工具(数据抽取转换加载) | 工作流调度平台(任务编排与监控) |
| 核心功能 | 异构数据源离线批量同步,如 MySQL ↔ HDFS、Hive ↔ Oracle | Hadoop与关系型数据库间的离线批量导入导出,如 Oracle → HDFS | 可视化设计ETL过程,包括数据抽取、清洗、转换、加载 | 任务编排与调度,把多个任务(Shell、Spark、DataX等)组成DAG并定时触发 |
| 操作方式 | 编写 JSON 配置文件,通过命令行执行 | 命令行执行,通过参数指定源、目标、表名等 | 图形化拖拽(Spoon客户端),通过画流程图设计转换和作业 | Web 界面拖拽(DolphinScheduler UI),定义工作流DAG并配置定时 |
| 核心技术 | 阿里开源,采用 插件式架构(Reader/Writer) | Apache 开源,专为 Hadoop 生态设计,基于 MapReduce 并行 | 基于 Java 的 ETL 工具,PDI(Pentaho Data Integration)社区版核心组件 | Apache 开源,基于 DAG 的工作流调度系统,支持分布式去中心化架构 |
| 适用场景 | DataWorks 离线同步、大厂内部异构数据源同步 | 传统 Hadoop 离线数仓(如 Hive 与 Oracle 对拷) | 传统数据仓库/中小型企业 的可视化 ETL 开发 | 离线数仓任务编排(如 1104 报送)、替代 Oozie/Azkaban 的现代调度方案 |
| 在大厂现状 | 主流选择。阿里云 DataWorks 默认集成,社区活跃,持续迭代 | 使用较少。功能单一(只支持 RDBMS ↔ Hadoop),新项目已很少选用 | 边缘化。不适合 PB 级大数据量,大厂基本不用,多见于传统行业 | 主流选择。现代离线数仓标配,社区活跃,已成为调度层事实标准 |
📌 怎么理解它们的分工?
这四者其实是一条数据生产线上的不同岗位:
-
DataX / Sqoop:是 “搬运工”,只负责把数据从 A 点搬到 B 点,不关心流程何时触发。
-
Spoon (Kettle):是 “可视化手工坊”,适合小规模团队用画图的方式做 ETL,但处理大数据量时力不从心。
-
DolphinScheduler:是 “总调度室”,负责把搬运工(DataX)、计算工(Spark SQL)、检查工(数据质量脚本)都协调起来,按时间和依赖关系自动运行。
一句话总结:在实时营销和1104报送项目中,DataX(搬数据) + DolphinScheduler(管流程) 是目前大厂最主流的离线搭配,而 Sqoop 和 Spoon 正逐渐淡出这一技术栈。
Hive的元数据和数据文件为什么要分开存储,不一起存在hdfs上面
分开存储的核心原因是:数据是“货”,元数据是“货架标签和索引”,两者性质完全不同,硬塞在一起反而会出问题。
我把它们分开存放的具体分工和原因拆解给你看:
1. 它们各自存了什么?
-
数据文件:存在 HDFS 上。就是你 INSERT 进去的那些实际的行、列、字段值,以文本、Parquet、ORC 等文件格式躺在硬盘上。
-
元数据(Metadata):存在 关系型数据库(如 MySQL)里。它存的是“表长什么样”的描述信息,比如:表名叫什么、有哪些列、列是什么类型(INT/STRING)、数据文件在 HDFS 的哪个目录路径(Location)、表的分区字段是谁。
2. 为什么要分开存?(核心原因)
原因一:读写性能天差地别(最根本原因)
-
元数据是“高频小读写”:执行一条
SELECT * FROM table,Hive 要先查“这个表存在吗?列名叫什么?文件在哪儿?”——这些都是毫秒级的随机查询,关系型数据库(MySQL)处理这种请求极其高效。 -
数据文件是“海量大吞吐”:真正的
SELECT和INSERT是GB/TB级的数据流式读写,必须由 HDFS 提供高吞吐的批量存储能力。
如果强行把元数据也存成 HDFS 文件,每次查表结构都要去 HDFS 上打开一个大文件扫描一遍,性能会慢到无法接受(延迟从毫秒级变成秒级)。
原因二:架构解耦,灵活切换
-
Hive 的计算引擎(Spark/Flink/MapReduce)和存储(HDFS)都可以换,但元数据必须保持稳定。
-
比如你用
Hive on Spark跑任务,Spark 引擎直接读 HDFS 上的数据文件,但同时需要连上同一个 MySQL 元数据库,知道表结构才能正确解析文件。 -
这种设计让 Hive 的元数据成了整个数据仓库的“目录中心”,即使你不用 Hive 执行引擎(比如直接用 Spark SQL),只要指向同一个元数据库,就能访问同一套表。
原因三:支持多客户端并发访问
-
多个用户或工具(Hive CLI、Spark SQL、Presto)可以同时通过元数据库查询表结构,而数据文件在 HDFS 上被多个任务并发读取,互不干扰。
3. 用一个仓库管理员来比喻
-
HDFS 上的数据文件 = 仓库里堆满的货物纸箱。
-
MySQL 里的元数据 = 管理员手中的仓库台账本。台账本上写着:“A区第3排:2024年销售数据,ORC格式,文件路径 /data/sales”。
-
当你想查数据时,先翻台账本(查元数据),知道箱子在哪、怎么打开,再去仓库搬货(读 HDFS 文件)。
-
如果把台账本也扔进仓库堆在货物里,每次查信息都要先翻遍所有箱子,效率会极其低下。
4. 补充:特殊情况
有一种看似“存在 HDFS 上”的元数据,叫 Hive Metastore Server 的 Derby 内嵌数据库,那是给单机测试用的(默认配置),文件确实会生成在本地磁盘,但生产环境绝不会用,因为无法支持多用户并发。生产环境必须用独立的 MySQL 或 PostgreSQL 来存储元数据。
总结一句:元数据是“索引目录”,数据是“正文内容”。目录必须放在书桌边(MySQL),方便快速翻阅;正文内容才放在书架上(HDFS),按需搬运。分开存储,各司其职,才是这个架构高效的关键。如果你对 Hive 的 Metastore 服务或表结构定义还有想深入了解的地方,可以继续问我。
什么是有向无环图
这个概念在Spark、Flink、MapReduce这些计算引擎里几乎天天见。理解它,你就能明白“为什么大数据任务要这么编排”。
有向无环图(DAG),拆开看就是三个词:
-
图(Graph):由一堆节点(点)和连接节点的边(线)组成的网络。
-
有向(Directed):边是有方向的,只能顺着箭头走,不能逆行。
-
无环(Acyclic):图中没有环路,你顺着箭头走,绝对走不到起点,不会死循环。
用“流水线工厂”理解
想象一条汽车组装流水线:
-
节点:每个工位(冲压钢板 → 焊接车身 → 喷漆 → 总装)。
-
有向边:零件必须从上一个工位流向下一个工位,不能倒流。
-
无环:流程绝对不会绕回来重复喷漆,最终一定能组装完开下生产线。
如果把“喷漆”和“总装”之间的流程倒过来,或者流程自己绕了个圈(喷漆完了又回冲压),就形成了“环”,那这辆车永远下不了线,这就是DAG不允许的。
为什么大数据计算非用DAG不可?
任何一个复杂的SQL(比如多表JOIN + GROUP BY),Spark和Flink在真正执行之前,都会先解析成一个DAG。
-
节点:代表一个计算步骤(读数据、过滤、聚合、写出)。
-
有向边:代表数据依赖关系(只有上游算完了,下游才能开始)。
DAG最大的好处:引擎能一眼看透整个任务,知道哪个步骤可以并行(比如两个没有依赖关系的节点可以同时算),哪个步骤必须等待。有了DAG,调度器就能把任务切分成最优的流水线,把集群资源榨干,最大程度缩短计算时间。
看一眼真正的DAG(图示)
比如一个简单的Word Count(单词统计)任务:

从A到E一路箭头到底,没走回头路,这就是一个最简单的DAG。
怎么区分?重点在这里
虽然都叫DAG,但生成DAG的时机完全不同:
-
Spark:你写代码时,程序一启动,就把整个任务逻辑一次性构建好一个大DAG,然后统一调度执行(这叫懒加载)。
-
Flink:从Kafka读数据开始,每个算子(节点)一启动就连成一条流水线DAG,数据是持续流动的,DAG也一直活着,不像Spark那样算完就销毁。
如果你下次在Spark UI里看到一堆蓝色方块连成的网络,或者在Flink UI里看到一个横向流动的管道图,心里就会默念:“哦,这就是它们的DAG。”
批处理脚本示例
批处理脚本在不同的语境下意思完全不一样。为了让你拿到手就能用,我按大数据开发和日常运维两个最常见的工作场景,各给你一个标准示例。
场景一:大数据离线调度脚本(你最需要的)
在数据仓库中,这个脚本通常由 DolphinScheduler 或 DataWorks 调度系统定时触发。它的作用是封装一天(或一小时)的数据处理逻辑,确保任务失败时能重试,并且把关键信息记录下来。
以下是一个典型的 Hive/Spark SQL 批处理 Shell 脚本:
bash
#!/bin/bash
# =====================================================
# 脚本名称: etl_trade_daily.sh
# 用途: 处理 T-1 日交易数据,用于 1104 监管报送
# 调度: DolphinScheduler 每日凌晨 02:00 触发
# =====================================================
# 1. 定义环境变量和日期
export HADOOP_USER_NAME=hadoop
APP_NAME="ETL_Trade_Daily"
# 获取业务日期(T-1)
if [ -n "$1" ]; then
BIZ_DATE=$1
else
BIZ_DATE=$(date -d "1 day ago" +%Y%m%d)
fi
echo "==================== 开始执行批处理 ===================="
echo "业务日期: ${BIZ_DATE}"
echo "开始时间: $(date '+%Y-%m-%d %H:%M:%S')"
# 2. 执行核心 SQL (利用 Hive 元数据,Spark 引擎计算)
# 这里直接执行一段复杂的 ETL 逻辑
spark-sql \
--master yarn \
--deploy-mode cluster \
--name "${APP_NAME}" \
--conf spark.sql.shuffle.partitions=200 \
--conf spark.dynamicAllocation.enabled=true \
-e "
-- 插入或覆盖目标表
INSERT OVERWRITE TABLE dwd.dwd_trade_order_di PARTITION(dt='${BIZ_DATE}')
SELECT
order_id,
user_id,
product_id,
order_amount,
pay_time
FROM ods.ods_mysql_trade_orders
WHERE dt='${BIZ_DATE}'
AND order_status = 'SUCCESS';
"
# 3. 检查执行状态
if [ $? -eq 0 ]; then
echo "批处理执行成功!"
# 可以在这里调用数据质量检查脚本
exit 0
else
echo "批处理执行失败!请查看日志。"
# 发送告警通知(如调用企业微信机器人)
exit 1
fi
脚本关键点解读:
-
它通过
spark-sql命令直接执行 Hive SQL。 -
BIZ_DATE变量让脚本具备“可重跑性”。 -
--master yarn表示任务提交给 YARN 资源管理器。 -
脚本里包含了成功/失败退出码,调度系统(如 DolphinScheduler)会据此判断任务状态。
场景二:简单文件数据处理(Python版)
如果你的数据不是很大(比如几个GB的CSV),只想用程序一次性跑完,不想起 Hadoop 集群,可以用 Python 写一个轻量级批处理脚本。
python
# -*- coding: utf-8 -*-
# batch_process.py
import pandas as pd
import logging
from datetime import datetime, timedelta
# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def process_yesterday_data():
"""处理昨日的用户行为日志"""
# 1. 获取昨天日期(用于读取对应文件)
yesterday = (datetime.now() - timedelta(days=1)).strftime('%Y%m%d')
input_file = f"/data/raw/user_behavior_{yesterday}.csv"
output_file = f"/data/processed/active_users_{yesterday}.parquet"
logging.info(f"开始读取文件: {input_file}")
try:
# 2. 读取数据 (批处理第一步: 读)
df = pd.read_csv(input_file)
logging.info(f"读取到 {len(df)} 条原始记录")
# 3. 业务逻辑处理 (批处理第二步: 算)
# 过滤出活跃用户 (比如浏览页数>5)
df_active = df[df['page_views'] > 5]
# 聚合: 计算每个用户的停留总时长
result = df_active.groupby('user_id').agg({
'duration': 'sum',
'page_views': 'sum'
}).reset_index()
# 4. 写出结果 (批处理第三步: 写)
result.to_parquet(output_file, index=False)
logging.info(f"批处理完成,结果已保存至: {output_file}")
logging.info(f"共处理用户数: {len(result)}")
except FileNotFoundError:
logging.error(f"错误: 找不到文件 {input_file},请检查路径。")
raise
except Exception as e:
logging.error(f"数据处理过程中发生未知错误: {e}")
raise
if __name__ == "__main__":
process_yesterday_data()
总结一句:什么是“批处理脚本”?
批处理脚本就是一个不会跟人实时交互的自动化程序。
它通常有三个固定步骤:
-
读:从某个地方(HDFS、MySQL、本地文件)批量加载数据。
-
算:执行固定的业务逻辑(过滤、聚合、关联)。
-
写:将结果批量存回目标位置。
前面的 Shell 示例 是企业级数仓的标准写法;
后面的 Python 示例 适合一次性数据处理。
DataX 同步脚本 或 DolphinScheduler 工作流定义文件
DataX 同步脚本和 DolphinScheduler 工作流定义文件,就是你刚才看到的批处理脚本在企业级生产环境中的具体落地形态。
它们之间的关系可以这样理解:
-
DataX 脚本:定义了“数据怎么搬”这个具体动作。
-
DolphinScheduler 工作流:定义了“什么时候、按什么顺序、用什么脚本(比如DataX或Spark SQL)来干活”这个完整的任务蓝图。
📦 DataX 同步脚本:JSON 格式的“搬运指令”
DataX 的核心工作模式是:通过一个 JSON 配置文件,告诉 DataX 从哪读数据(Reader)、写到哪去(Writer)。你执行 python datax.py job.json 时,它就会按照这个配置开始干活。
这是一个从 MySQL 同步数据到另一套 MySQL 的 mysqlToMySQL.json 示例:
json
{
"job": {
"content": [
{
"reader": { // 👈 定义从哪里读
"name": "mysqlreader",
"parameter": {
"username": "root",
"password": "123456",
"connection": [
{
"jdbcUrl": ["jdbc:mysql://源IP:3306/source_db"],
"table": ["source_table"]
}
],
"column": ["id", "name", "age"], // 要同步的列
"splitPk": "id" // 用于并发读取的分片字段
}
},
"writer": { // 👈 定义写到哪里
"name": "mysqlwriter",
"parameter": {
"username": "root",
"password": "123456",
"writeMode": "insert", // 写入模式
"connection": [
{
"jdbcUrl": "jdbc:mysql://目标IP:3306/target_db",
"table": ["target_table"]
}
],
"column": ["id", "name", "age"]
}
}
}
],
"setting": {
"speed": {
"channel": 5 // 并发通道数,控制同步速度
}
}
}
}
关键点:
-
Reader/Writer插件:DataX通过不同的
name(如mysqlreader,hdfsreader,doriswriter)来支持各种异构数据源。 -
执行命令:写好配置后,通过
python {DataX_Home}/bin/datax.py mysqlToMySQL.json执行。
🗓️ DolphinScheduler 工作流定义:DAG 形式的“任务施工图”
在实际生产中,你不会手动去一条条执行 DataX 脚本。
DolphinScheduler 的作用,就是把这些脚本和任务(比如 Spark SQL、Shell 脚本)用 DAG(有向无环图)的形式组织起来,统一调度和监控。
它核心的设计理念是 “定义与实例分离” :
-
工作流定义 (Workflow / ProcessDefinition):这是你画出来的蓝图。描述了“流程里有哪些任务(节点),任务之间依赖关系是怎样的(谁先谁后)”。
-
工作流实例 (Workflow Instance / ProcessInstance):这是蓝图被实际触发运行的那一次。所有你看到的运行状态、开始结束时间、日志,都挂在这个实例上。
工作流定义的“灵魂”:DAG
在 DolphinScheduler 的 Web UI 上,你拖拽任务节点并连线,本质就是在创建一张 DAG。调度器的核心职责,就是根据这张图来判断“某个任务的上游依赖是否全部完成,是的话就可以调度它了”。
在 DolphinScheduler 中配置 DataX 任务
在 DolphinScheduler 里跑 DataX 任务,最直接的方式是通过 DataX 任务节点。你可以选择两种方式:
-
可视化方式 (推荐):在 UI 上直接选择数据源、填写 SQL 和目标表,系统自动生成 DataX 的 JSON 配置。这种方式无需接触服务器和 JSON 文件,对运维友好。
-
自定义JSON方式:在任务参数里,直接粘贴或上传你写好的完整 DataX JSON 配置,适合需要高度定制化同步的场景。
在 DolphinScheduler 的底层 API 或调用时,一个 DataX 任务节点的定义(processDefinitionJson)核心部分长这样:
json
{
"tasks": [{
"type": "DATAX", // 👈 节点类型是 DataX
"id": "datax-100",
"name": "同步用户表",
"params": {
"customConfig": 1, // 1 表示使用自定义 JSON
"json": "{ \"job\": { \"content\": [...] } }", // 👈 这里就是上面那个完整的 DataX JSON 配置,但需要转义成字符串
"xms": "1g",
"xmx": "1g"
},
"preTasks": ["前置任务ID"] // 👈 依赖的上游任务
}]
}
💎 总结
-
DataX脚本:是干活的,用一个 JSON 文件定义好“从哪搬到哪”。
-
DolphinScheduler工作流定义:是排兵布阵的,用一个包含了任务节点、依赖关系和调度时间的 DAG 蓝图,来统筹管理所有的 DataX、Spark SQL 等脚本任务。
理解了这两者的内容和关系,你就能明白一条完整的离线数据同步链路(比如 1104 报送的数据从 GoldenDB 到 GBase 8a),是如何通过“脚本”和“调度”两大块协作完成的了。
及其组件协作关系,Spark 和 Flink 在真正执行之前,都会先解析成一个DAG(有向无环图)&spm=1001.2101.3001.5002&articleId=162313097&d=1&t=3&u=d0e6942e133b483e8badcdef6a28cece)
763

被折叠的 条评论
为什么被折叠?



