数据工程与 ETL 速查
数据管道与批流概念、Kafka 使用与运维、调度编排、数仓建模、数据质量校验、CDC 同步:数据工程工作速查。
管道基础
ETL/ELT 模式、批处理与流处理概念
ETL 与 ELT 对比与选型
ETL 先转换后加载、转换在独立引擎完成;ELT 先把原始数据装进目标库再转换,转换下推到数仓算力。选型看目标库算力、数据形态与团队 SQL 能力。
批处理与流处理概念对比
批处理按批次处理有界数据,吞吐高、补数简单;流处理持续处理无界数据,端到端延迟低。多数团队批流并存:流做实时看板,批做口径复盘与补数。
投递语义:至多一次/至少一次/精确一次
三种投递语义描述故障时的重复与丢失边界:至多一次可能丢、至少一次可能重、精确一次要求端到端不丢不重,通常靠事务或幂等落库实现。
全量抽取与增量抽取
全量每次覆盖整表、逻辑简单但源端压力大;增量只取变化数据、成本低但依赖可靠的变更标识。常见组合是首次全量、后续增量、定期全量对账。
Parquet 列式文件格式
Parquet 是数据湖常用列式格式:自带 schema、按 row group 与 page 组织、每列保存统计信息,配合分区目录可大幅减少扫描量。
水位线 Watermark 与乱序容忍
水位线是事件时间已推进到某一点的标记:引擎收到水位线后才认为更早的数据基本到齐,从而触发窗口计算;允许延迟越大结果越准,输出越晚。
幂等写入与 Upsert 落库
重跑任务时结果不产生重复或错误累计,就是幂等。常见做法:按业务主键 upsert、按分区覆盖写入、写临时表后原子替换。
流处理窗口类型:滚动/滑动/会话/累计
窗口把无界流切成可聚合的片段:滚动窗口不重叠、滑动窗口按步长重叠、会话窗口按活跃间隔切分、累计窗口在同一周期内逐段累加。
流任务 Checkpoint 与状态恢复
Checkpoint 定期把算子状态与消费位点做成一致性快照存到外部存储,作业故障后从最近一次成功快照恢复,避免从头重放。
spark-submit 提交批作业
spark-submit 是 Spark 作业的统一入口:指定 master、资源、依赖与主类;client 模式 driver 在提交机、cluster 模式 driver 在集群内,日志位置不同。
事件时间与处理时间 Event/Processing Time
事件时间是数据实际发生的时间(常来自记录里的时间戳),处理时间是引擎处理到它的时刻。两者存在乱序与延迟差,流处理以事件时间语义保证结果可复现。
数据管道的组成环节
一条管道通常包含采集、传输、处理、存储、服务五个环节,另有调度、质量、监控三条支撑线。按环节拆分能快速定位延迟与故障出在哪一段。
数据倾斜的识别与处理
个别 key 数据量远超其他 key 时,单个 task 成为长尾:表现为多数 task 秒级完成、个别 task 长时间运行甚至 OOM。处理手段包括加盐两阶段聚合、广播小表、拆分热点 key。
数据去重的常见模式
重复来源:上游重发、至少一次投递、任务重跑。批侧用 ROW_NUMBER 取最新一条;流侧用去重状态或下游 upsert 收敛。
数据采集的四类模式
按来源划分:数据库(批量抽取或 CDC)、日志(Agent 采集)、API(定时拉取)、文件(批量投递)。不同来源的可靠性、重复与顺序特性差异明显。
Apache Iceberg 基础用法
Iceberg 是开放表格式:用元数据文件管理快照与清单,支持隐藏分区、schema 演进与快照级时间旅行;Spark/Flink/Trino 等多引擎可读写同一张表。
Apache Flink 核心概念
Flink 是面向流处理的分布式引擎,也支持批模式:以事件时间与状态为核心,checkpoint 保证一致性恢复;作业按并行算子拓扑常驻运行。
有界数据与无界数据 Bounded/Unbounded
有界数据有明确起止,批处理器一次读完全部即可出结果;无界数据没有终点,流处理器必须依靠窗口、水位线与增量状态持续产出结果。
增量抽取水位列与半开区间
用更新时间列做水位是最常见的增量方式:记录上一次抽取到的高水位值,下次只取大于它的数据。用「大于等于左边界、小于右边界」的半开区间避免边界重复与丢失。
分区裁剪 Partition Pruning
查询只需读取命中的分区目录,是数仓查询性能的关键前提。前提是过滤条件直接作用于分区列;对分区列做函数变换会让裁剪失效。
Flink SQL 接入 Kafka
用 Flink SQL 声明 Kafka 源表/结果表即可完成流式加工:指定 connector、topic、bootstrap servers、启动位点与数据格式,再写查询语句。
数仓转换常用 SQL 模式
日常加工大多落在几类模式上:按维度聚合、取最新一条、维表补全、窗口排名、区间累计。掌握这些模式,多数层间加工不必引入复杂框架。
迟到数据处理 Late Data
迟到数据是事件时间早于当前水位线的记录。常见处理:允许窗口内继续更新、旁路输出离线补偿、或在下游做覆盖合并。
Shuffle 原理与调优
shuffle 是宽依赖算子(group by、join、distinct、排序)跨节点重分区的过程,伴随磁盘落盘与网络传输,是批作业成本的主要来源之一。
Schema 演进与兼容性
上游加字段、改类型在数据链路里不可避免。基本原则:加带默认值的字段通常向后兼容,删字段要带默认值保证旧读兼容,改类型(除数值提升)通常不兼容。
数据湖概念与典型组成
数据湖用集中式存储(HDFS/对象存储)保存原始与加工数据,schema 在读时确定;由存储层、表格式层与计算引擎三层组合而成。
PySpark 读写与转换最小示例
PySpark 把 Spark 能力带入 Python:读列存、按列过滤聚合、写出分区表;DataFrame API 与 SQL 可以混用。
背压 Backpressure 与链路限速
当下游处理速度低于上游时,反压沿链路向上传递,最终让源端减速;持续反压说明某算子或外部写入成为瓶颈,需要定位再扩容。
流式关联:Interval Join 与维表 Lookup Join
流与流按时间区间关联用 interval join;流与维表关联用 lookup join(按需查外部库)。维表变化频繁时要考虑缓存过期与回溯。
Avro 行式序列化格式
Avro 是面向行记录的二进制格式,schema 随数据写入(writer schema),读时按 reader schema 解析,因此在 Kafka 序列化与 schema 演进场景里被广泛采用。
Hive 分区目录布局与维护
Hive 表以目录表达分区(如 dt=2026-10-11),分区列不是数据文件里的普通列;新增分区后需要同步元数据,目录与元数据不一致时用 MSCK REPAIR 修复。
小文件问题与治理
大量小文件会抬高元数据压力与扫描开销:每读一个文件都有打开、寻址与统计成本。治理思路是写入侧控制文件数量,读侧用 AQE/合并任务兜底。
湖仓一体 Lakehouse 关键能力
湖仓一体在数据湖的存储上叠加表格式的事务与元数据能力:ACID 写入、schema 演进、快照与时间旅行,让分析型查询直接用湖上数据。
Delta Lake 基础用法
Delta Lake 用事务日志(_delta_log)记录每次提交,提供 ACID、时间旅行与 MERGE 更新;Spark 上以路径或元数据表方式读写。
spark-sql 命令行与脚本执行
spark-sql 提供 SQL 交互与批脚本执行:-e 执行单条语句、-f 跑 SQL 文件,适合调度器直接拉起纯 SQL 加工任务。
Hive 外部表与托管表区别
外部表(EXTERNAL)只管理元数据,DROP 不删数据文件;托管表 DROP 默认会连同数据一起删除。共享目录与原始数据一律用外部表。
Lambda 与 Kappa 架构取舍
Lambda 同时跑批处理层与速度层,用批层修正实时结果;Kappa 只保留流处理一条链路,历史重放靠消息保留或存储回放。
列式存储与行式存储
行式存储适合按行读取与点查更新;列式存储把同列数据连续存放,分析型查询只读少量列时 IO 明显更省,且利于压缩与向量化计算。
CSV 处理的常见陷阱
CSV 看起来简单,实际布满陷阱:分隔符与引号转义、编码与 BOM、换行符、空值与 NULL 的表示、超大数字精度。入库前统一规范比事后清洗省力。
Apache Hudi 基础概念
Hudi 面向湖上增量更新:记录级 upsert、两种表类型(COW 重写文件、MOR 写日志文件)、基于主键与预合并字段决定同键保留哪条。
Trino 交互式查询基础
Trino 是分布式 SQL 查询引擎,用 catalog 连接器对接 Hive、Iceberg、MySQL 等异构数据源,适合对湖上数据做交互式分析。
dbt 转换模型基础
dbt 用 SQL + 配置管理数仓内转换:模型之间用 ref() 表达依赖,dbt 负责编译、按依赖顺序执行、跑测试与生成文档;调度仍交给外部调度器。
微批 Micro-batch 模式
微批把流按固定小间隔切成批执行,实现简单、天然幂等,代价是延迟约等于批次间隔;Spark Structured Streaming 即此模型。
谓词下推 Predicate Pushdown
把过滤条件下推到扫描层,在读数据时就跳过不满足条件的行或数据块;Parquet/ORC 依靠列统计(min/max)跳过 row group,显著减少 IO。
JSON 与 NDJSON 行式文本
JSON 数组需要整体解析、难以流式处理;NDJSON(每行一个 JSON 对象)可以逐行处理与追加,是日志与事件落地的常见形态。
对象存储作为数据落地区
数据湖常以对象存储作为落地区:S3/OSS 等提供廉价容量,Hadoop 生态通过 s3a:// 等 scheme 访问;注意其最终一致性已改善但目录操作语义与本地文件系统不同。
文件到达触发与完成标记
文件类批次的可靠触发依赖“完成标记”:要么源端先写临时文件再重命名,要么用 _SUCCESS/清单文件标记批次结束,避免读到半截文件。
ORC 列式文件格式
ORC 是 Hive 生态常用的列式格式,提供列级索引、布隆过滤与谓词下推支持;在 Hive 为主、Spark 为辅的仓库里使用广泛。
API 增量拉取与分页
第三方 API 采集要处理三件事:增量参数(时间戳或游标)、分页方式(page/offset 或 cursor)、失败重试与限流退避。
压缩算法选择:gzip/snappy/zstd 等
压缩在“压缩比、速度、可切分性”之间取舍:snappy/lz4 偏快,gzip 通用,zstd 在压缩比与速度之间较均衡;列存内部按块压缩,切分性影响较小。
数据契约 Data Contract
数据契约把上下游对表结构、字段语义、质量期望与产出时间的约定显式化:上游变更流程化,下游按契约做校验与告警,减少“悄悄改字段”事故。
ETL 转换逻辑的测试方法
转换逻辑上线前用样本数据验证:对边界值(空值、负值、重复键、超长字符串)逐条断言,比上线后靠对账发现问题成本低得多。
Kafka
主题分区、常用命令与消费组运维
kafka-topics.sh 创建主题
创建主题时显式指定分区数、副本因子与关键配置(保留、最小同步副本),避免依赖集群默认值在环境间产生差异。
消费组详情与积压定位
describe 输出每个分区当前位移、末尾位移与 LAG,并显示消费者成员;这是判断积压规模与分布(倾斜还是整体)的核心视图。
Apache Kafka 是什么
Kafka 是分布式事件流平台:以追加日志形式持久化消息,通过分区并行、多副本容错,支撑发布订阅、数据管道与实时处理三类场景。
Offset 位移概念
位移是消息在分区内的编号:生产者写入后递增的末尾位移叫 LEO,消费者记录下次要读的位置叫消费位移;两者之差就是积压(Lag)。
消费组位移重置
位移重置用于补数或跳过坏数据:把组位移改到最早、最新、指定值或时间点。要求消费组无活跃成员,默认仅演练,需加 --execute 才真正执行。
Partition 分区与顺序性
分区是 Kafka 的并行与顺序单位:同一分区内消息严格有序,跨分区不保证顺序;分区分布在多个 Broker 上以实现吞吐与容错。
kafka-topics.sh 查看主题详情
describe 输出分区分布、Leader、副本与 ISR,还可按 under-replicated/unavailable 过滤,是副本类故障排查的常用入口命令。
消费积压 Lag 排查流程
积压排查按“范围—成员—分布—集群”四步:先确认是整体还是局部,再看消费者是否在线与再均衡,然后看分区倾斜与 broker 健康,最后定位是消费慢还是生产突增。
Topic 主题与配置
Topic 是消息的逻辑分类,由分区、副本数与一批可覆盖的配置(保留时间、清理策略、消息大小上限等)构成;创建后配置仍可动态调整。
生产者 acks 与持久性
acks 控制生产者在收到多少副本确认后才算写成功:0 不等确认、1 等 Leader、all 等 ISR 全部写入。持久性要求越高,延迟与失败概率越高。
消费组 Consumer Group
消费组是一组协同消费一个主题的消费者:组内按分区均分,一个分区同时只归一个成员;不同组各读全量互不影响,这也是多下游共享一个主题的方式。
kafka-console-consumer.sh 消费查看消息
控制台消费者用于抽查消息内容与位点行为:可从头读、指定分区与起始位移、按组消费、打印 key 与时间戳。
副本与 ISR 机制
每个分区有一个 Leader 和若干 Follower:Follower 持续从 Leader 拉取并追赶,跟得上的副本构成 ISR(In-Sync Replicas);Leader 故障时优先从 ISR 中选举新 Leader。
Kafka 生产者工作流程
生产者发送一条消息经历:序列化 → 分区器选择分区 → 进入累加器等待成批 → 发送到分区 Leader → 按 acks 等待确认,失败按重试策略重发。
kafka-configs.sh 动态配置管理
kafka-configs.sh 管理主题、Broker、客户端配额等动态配置:describe 查看、alter 增加或覆盖、delete-config 恢复默认,多数配置生效无需重启。
消息保留策略与日志清理
Kafka 按时间或大小保留消息,过期以日志段(segment)为单位删除:retention.ms 控制时间、retention.bytes 控制容量,检查周期决定删除的及时性。
kafka-console-producer.sh 生产测试消息
控制台生产者用于连通性验证与小批量灌数:默认按行读取标准输入写入指定主题,可开启 key 解析与自定义生产者属性。
消费位点提交方式
位移提交决定“重启后从哪里继续”:同步提交可靠但阻塞、异步提交吞吐好但需处理失败回调;提交时机决定重复与丢失边界。
kafka-topics.sh 列出主题
列出主题时过滤内部主题,便于巡检与环境比对;自动化里可结合 --exclude-internal 避免 __consumer_offsets 等系统主题干扰。
listeners 与 advertised.listeners 配置
listeners 决定 Broker 绑定哪些地址与协议,advertised.listeners 决定它告诉客户端的连接地址。云主机/容器场景两者配错,是最常见的“连不上 Kafka”原因。
生产者批处理 linger.ms 与 batch.size
生产者把小消息合并成批发送以提升吞吐:linger.ms 控制等待时间、batch.size 控制单批字节上限;等待越久批次越大,延迟也越高。
再均衡 Rebalance
组成员变化、订阅变化或分区数变化会触发再均衡:分区在成员之间重新分配。均衡期间消费可能暂停,频繁触发是消费链路的典型故障。
Kafka 关键监控指标
Kafka 运维看四类指标:副本健康(URP/离线分区)、控制器状态、流量与延迟、消费积压。缺少其中任何一类,故障都会以“业务报延迟”的形式暴露。
kafka-topics.sh 修改分区数
主题创建后只能增加分区,不能减少;增加分区会改变 key 到分区的映射,依赖同 key 有序的链路要确认可接受再操作。
min.insync.replicas 最小同步副本
min.insync.replicas 是 acks=all 生效的底线:当 ISR 数量低于该值,生产者写入直接失败(NotEnoughReplicas),用可用性换取一致性。
KRaft 模式(无 ZooKeeper)
KRaft 用内置的 controller quorum 取代 ZooKeeper 管理元数据:Kafka 3.3 起可用于生产,4.0 起仅支持 KRaft;新集群部署直接用 KRaft。
Kafka Connect 连接器框架
Kafka Connect 用配置化连接器把外部系统与 Kafka 对接:source 把外部数据写入 Kafka,sink 把 Kafka 数据写出;worker 负责运行连接器并通过 REST 管理。
分区重分配(扩容/迁移/调整副本)
reassign 工具用于把分区副本搬到新 Broker、调整副本因子、在磁盘间迁移:先生成分配方案,再执行并持续 verify,可限速减少对业务影响。
Java 生产者代码示例
Java 生产者的最小可用骨架:配置序列化器与 acks、异步发送并处理回调、退出前 flush 与关闭。回调处理是避免“静默失败”的关键。
Java 消费者代码示例
Java 消费者骨架:关闭自动提交、poll 循环处理、按批手动提交;poll 间隔内的处理时长要控制在 max.poll.interval.ms 内。
消息 Key 与分区路由
带 key 的消息按 murmur2(key) % 分区数 选择分区,同 key 始终落同一分区从而保序;无 key 时按可用分区轮询(粘性分区会先填满一批再切换)。
日志压实 Log Compaction
压实(cleanup.policy=compact)按键保留最新一条消息,适合变更日志与状态快照;删除通过写入带 null 值的 tombstone 消息表达。
副本滞后与离线分区处理
UnderReplicatedPartitions 表示有副本落后,UnavailablePartitions 表示分区完全没有可用 Leader;两者处理顺序都是先恢复 Broker,再评估重分配,最后才考虑 unclean 选举。
自动提交 enable.auto.commit 的陷阱
开启自动提交后,消费者在后台按 auto.commit.interval.ms 周期提交“poll 到的位移”,与业务处理是否完成无关;处理崩溃时会丢这一段数据。
Kafka 事务与精确一次写入
事务型生产者把多分区写入与消费位点提交绑定为一个原子操作,实现 consume-transform-produce 场景的精确一次;读端需以 read_committed 隔离级别读取。
分区数规划方法
分区数决定并行上限与元数据成本:按目标吞吐除以单分区参考能力估算,再留冗余;分区过多会拉长选举与元数据同步时间,过少则无法扩展。
kafka-consumer-groups.sh 列出消费组
列出全部消费组用于盘点与巡检:对比组清单可以发现废弃组与错连组,配合 describe 定位积压。
kafka-log-dirs.sh 磁盘占用分析
按 Broker 与日志目录查看分区大小与位移,定位磁盘不均衡、单分区过大、迁移目标容量,是磁盘类事故排查的原始数据。
Broker 磁盘满应急处理
磁盘写满是 Kafka 高危故障:会导致副本离线甚至分区不可写。处理顺序是止血(限流与缩保留)、清空间(删过期段、迁分区)、再扩容与复盘。
Kafka 安全:SSL 与 SASL 要点
生产集群建议同时启用传输加密与认证:TLS 保护链路、SASL 校验客户端身份、ACL 控制主题级权限;三者可以组合为 SASL_SSL。
Python 客户端使用要点
Python 生态常用两个客户端:kafka-python(纯 Python,安装简单)与 confluent-kafka(基于 librdkafka,性能与特性更贴近官方实现)。选型结合吞吐与维护现状。
Schema Registry 与消息序列化治理
Schema Registry 集中管理消息结构的版本与兼容性策略:生产者注册 schema 获得 ID,消息只携带 ID,消费者按 ID 取 schema 反序列化,结构变更受兼容性检查约束。
Kafka Streams 流处理库
Kafka Streams 是客户端库:在普通 Java 应用里读写 Kafka 完成流处理,无需独立集群;以 KStream/KTable 建模,状态存于本地并可用 changelog 主题恢复。
kafka-topics.sh 删除主题
删除主题是高风险操作:配置与数据不可恢复(除非有其他副本或备份)。删除前确认无生产者写入、无消费者依赖,并评估重建的必要性。
kafka-get-offsets.sh 查询分区位移
查询各分区的最早/最新位移(或指定时间的位移),用于估算积压、计算消息量、确认保留范围,是容量与故障评估的常用工具。
消费端 fetch 与处理参数调优
消费性能由拉取参数与处理循环共同决定:fetch.min.bytes/max.wait.ms 决定批量效率,max.poll.records 与 max.poll.interval.ms 决定单次处理量与超时边界。
集群 Controller 与元数据管理
Controller 是集群的“大脑”:负责分区 Leader 选举、主题创建删除、副本状态维护。ZooKeeper 模式与 KRaft 模式的区别在于元数据的存储与选举方式。
删除消费组的主题位移
delete-offsets 只清理某个组在某主题上的位移记录:组下次启动时该主题按 auto.offset.reset 决定起点,常用于彻底重置或清理废弃订阅。
分区 Leader 选举与均衡
Leader 分布不均时可用 PREFERRED 选举把分区首领迁回首选副本;当所有 ISR 副本都不可用时,才考虑 UNCLEAN 选举,但会丢未同步数据。
生产端压测 kafka-producer-perf-test.sh
生产端压测用于评估单分区/集群写入能力与客户端配置影响:输出吞吐与延迟分位,是容量规划与参数调优的依据。
MirrorMaker 2 跨集群复制
MirrorMaker 2 基于 Kafka Connect 实现集群间数据复制:自动同步主题内容与部分元数据,支持单向与双向拓扑,常用于机房容灾与数据汇聚。
删除消费组
删除消费组会清除其位移记录:下次同组名启动时按 auto.offset.reset 从最早或最新开始,这也是常用的“重新消费”手段。
kcat(kafkacat)轻量命令行客户端
kcat 是 C 实现的轻量 Kafka 客户端:查看元数据、生产与消费消息、按分区或位移读取,适合服务器上快速验证与脚本化检查。
消息大小限制与排查
消息能否写入/读出要同时满足多层限制:生产端 max.request.size、Broker/主题 message.max.bytes、消费端 fetch 上限;任何一层过小都会报错或卡消费。
Kafka 主题命名与治理
主题名是长期契约:命名要能表达域、环境与数据用途,并预留版本演进空间;改名意味着上下游全量改动,代价高。
消费端压测 kafka-consumer-perf-test.sh
消费端压测评估拉取性能与消费者配置影响:指定消息数与组名,观察吞吐与分区间表现,用于验证扩容是否改善消费。
Kafka 集群扩容流程
扩容分三步:新节点以唯一 broker.id 加入集群;用重分配把存量分区迁移过去;验证 ISR 与负载后再取消限速。仅加机器不会自动均衡数据。
kafka-dump-log.sh 读取日志段
直接解析磁盘上的日志段文件查看消息内容、位移与时间戳,用于验证消息是否真正落盘、核对压缩前后数据、排查消费与落盘不一致。
删除分区历史消息
按分区把低水位推进到指定位移:此位移之前的消息将被删除,用于清理误灌数据或紧急释放磁盘空间,操作不可恢复。
消费组位移保留与过期
位移保存在内部主题中同样会过期:组长期无成员后位移被清理,重新启动的消费者会按 auto.offset.reset 决定位置,可能跳过或重复历史数据。
查看 Broker 支持的 API 版本
列出每个 Broker 支持的请求 API 及版本区间,用于排查客户端与服务端版本不兼容(UnsupportedVersionException)及升级前的兼容评估。
机架感知副本与就近读取
配置 broker.rack 后,Kafka 尽量把同一分区的副本分散到不同机架,降低单机架故障影响;消费者也可开启机架感知从就近副本拉取,节省跨区流量。
Kafka Web 管理界面选型要点
社区常见 Web 界面(AKHQ、Kafdrop、kafka-ui 等)提供消息浏览、消费组积压、主题管理与 ACL 查看;使用前先评估权限模型与暴露面。
客户端配额限流
配额(quota)用于限制单个用户或客户端对集群资源的占用:按字节速率限制生产/消费,或按请求比例限制 CPU 使用,防止单客户端影响集群整体。
调度与编排
任务依赖、调度工具与回填重跑
调度系统解决什么问题
调度系统负责按时间与依赖触发任务,并管理状态、重试、告警与补数:相比裸 cron 脚本,它把“任务是否成功、依赖是否满足”变成可查询、可重跑、可审计的状态。
DAG 有向无环图与依赖建模
DAG 用节点表示任务、边表示依赖,无环保证“总能排序执行完”。可视化 DAG 是排查“为什么还没跑”的常用入口:上游没完成,下游只会等待。
Airflow DAG 文件结构
DAG 定义就是一个 Python 文件,放在 $AIRFLOW_HOME/dags 目录下由调度器周期扫描解析;文件里用 with DAG(...) 声明 dag_id、调度周期、开始日期与默认参数,任务是文件中的算子实例。
cron 表达式基础与示例
cron 用五个字段描述分钟、小时、日、月、星期:调度平台大多兼容该语法,但扩展符(L、?、#)与“日+周”同时指定时的行为各平台不同。
业务日期与运行时间
业务日期(数据属于哪一天)与运行时间(任务实际几点跑)是两个概念:日批通常运行在 T+1,处理的是 T 日数据;补数时尤其要区分,否则会错位覆盖。
回填与补数流程
补数按指定日期区间重跑历史:用于上游故障补数据、口径变更重刷、修复断链。补数要限并发、先评估下游影响,并保证任务幂等。
Airflow TaskFlow API
TaskFlow 用 @task 装饰器把 Python 函数变成任务,返回值自动经 XCom 传给下游;配合 @dag 装饰器可省掉手写上下文与 xcom_pull,适合以 Python 逻辑为主的 DAG。
依赖类型:时间/任务/数据/外部
依赖不只是“上游跑完”:按时间触发最弱,按上游任务状态稍好,按数据就绪(分区/文件/表行数)最可靠;外部依赖(第三方回调、人工确认)要设置兜底超时。
catchup 补跑行为控制
catchup 决定新上线的 DAG 是否补齐 start_date 到当前的所有周期:开启会一次性生成大量历史周期任务,关闭则从当前之后开始。
Airflow Operator 常用算子
Operator 是 Airflow 里一个任务做什么的模板类:BashOperator 跑 shell、PythonOperator 调函数、SQL 类算子执行查询,各系统对接由 Provider 包提供的专用算子完成。
重跑的幂等设计
任务重跑必须产出相同结果:优先“分区覆盖写”,其次“按主键 upsert”,再次“写临时表后切换”;流水账式累加(+=、count++)是最容易出错的模式。
Airflow Sensor 等待与 reschedule 模式
Sensor 是等条件成立的任务:文件出现、上游分区就绪、时间到达等;默认 poke 模式会一直占用执行槽位,长等待建议开 reschedule 模式在轮询之间释放资源。
Airflow CLI 常用命令
airflow 命令行是排障与操作入口:列 DAG、看任务状态、单任务本地试跑、手动回填、清理历史记录;尽量用 CLI 做可复现操作而不是只在界面点按钮。
重试策略与告警分级
重试要区分错误类型:网络抖动、资源竞争适合自动重试;数据质量问题、代码缺陷重试只是延迟告警。告警要分级并带上下文(任务、业务日期、日志链接)。
Airflow XCom 跨任务传参
XCom 用于任务之间传递少量数据:push 写入、pull 读取,TaskFlow 下自动处理;底层存在元数据库中,跨任务传大对象会明显拖慢调度。
任务超时与完成时限控制
任务超时控制有两层:单个任务执行超时(execution_timeout)、整个调度批次用时上限(dagrun_timeout);再配合“产出新鲜度”监控,才覆盖按时产出这个目标。
调度平台监控与值班指标
调度监控不只盯“失败”:还要看未按时开始、运行时长异常、排队积压与补数进度。建议把任务状态与产出新鲜度一起做成值班面板。
Airflow Connections 连接管理
Connections 集中保存数据库、API 等外部系统的连接信息,DAG 里只引用 conn_id,凭据不落代码;可在界面、环境变量或 CLI 维护,生产建议接 Secrets Backend。
Airflow 执行器选型
执行器决定任务在哪里跑:SequentialExecutor 仅适合验证、LocalExecutor 单机多进程、CeleryExecutor 分布式 worker 队列、KubernetesExecutor 每任务一个 Pod;大版本升级前需通读迁移说明。
并发控制:队列、池与并行度
调度并发要分层控制:集群总并行度、单 DAG 并发、任务池(pool)槽位、worker 执行槽。给写库与重资源任务设置独立池,避免批量任务同时压垮下游。
Airflow Variables 参数化
Variables 存全局配置类小值(阈值、开关、地址),运行时用 Variable.get 读取;高频读取会打元数据库,推荐模板引用方式或在执行器侧缓存。
调度时区处理
调度时区决定 cron 表达式的解释基准:调度器按 UTC 运行而表达式按本地时间编写时,任务会整体偏移;跨时区团队要显式声明 DAG 时区。
airflow.cfg 关键参数
airflow.cfg 控制调度节拍与并发上限:parallelism(全局并行度)、max_active_tasks_per_dag、max_active_runs_per_dag、dag_dir_list_interval 等;调参前先量清任务时长与槽位占用。
Airflow 部署要点
生产部署三个基础件:元数据库(PostgreSQL)、带队列的执行器、被所有组件共享的 DAG 目录;容器化常用官方 Helm Chart,升级先在预发跑数据库迁移与 DAG 全量解析校验。
手动触发与参数覆盖
手动触发用于补单、验证与应急:触发时显式传入业务日期等参数,并在记录中留下原因;绝不能依赖默认参数直接开跑,避免覆盖当天正在跑的数据。
Airflow 动态任务映射与 TaskGroup
动态任务映射用 task.expand(...) 按运行时列表生成一批并行任务(如按分区展开);TaskGroup 做界面上的分组折叠,不改变依赖语义,两者常配合管理复杂 DAG 的图结构。
Airflow 分支与触发规则
BranchPythonOperator 按条件选择走哪条分支,未选中分支标记 skipped;trigger_rule 控制上游处于什么状态才执行本任务,如 all_success、all_done、one_failed。
Airflow 任务状态机
任务实例经历 queued 到 running 再到 success 或 failed,还有 up_for_retry、upstream_failed、skipped、deferred;排障顺序是先读状态再读日志。
调度工具选型对比
选调度先看任务画像与团队能力:Airflow 以 Python 代码编排、生态丰富;DolphinScheduler 可视化多租户、补数开箱即用;XXL-JOB 贴合 Java 应用;云上可直接用托管调度服务。
Airflow DAG 测试与 CI 校验
把 DAG 当代码测:CI 里用 DagBag 校验所有 DAG 可导入、dag_id 唯一、无循环依赖,再用 pytest 断言关键任务与依赖结构,解析失败的 DAG 不允许合并。
DolphinScheduler 核心概念
Apache DolphinScheduler 是可视化工作流调度平台:以项目隔离资源,工作流(流程定义)由任务节点与依赖关系组成,支持串行、并行、依赖、子流程等节点类型,具备多租户能力。
Airflow 数据集驱动调度
数据集(Airflow 2.4 引入的 Dataset,3.x 改名 Asset)把上游产出更新作为下游 DAG 的触发条件,替代按时间硬对齐的 cron;同一数据集被多个 DAG 更新时,下游等齐所有更新才触发。
DolphinScheduler 部署与架构
典型架构:API 服务、Master(DAG 拆解与调度)、Worker(任务执行)、注册中心(ZooKeeper)与元数据库(PostgreSQL/MySQL),另有资源中心存放脚本与文件。
跨 DAG 依赖与就绪检查
跨 DAG 依赖有两类思路:用 ExternalTaskSensor 等上游指定运行完成,或让下游直接检查上游产出(分区是否就绪、标记文件是否存在);后者更抗上下游调度频率不一致。
Airflow Secrets Backend
Secrets Backend 让 Connections/Variables 从 Vault、云密钥管理或 K8s Secret 读取,而不是存在元数据库;按前缀约定命名路径后,可实现凭据集中管理与轮换。
DolphinScheduler 定时与补数
工作流上线后设置定时(cron)与生效起止时间;补数按日期区间批量生成工作流实例,可选串行或并行执行,用于历史回填与故障重跑。
Airflow 指标导出与告警
把 Airflow 运行指标(任务成功失败数、调度延迟、DAG 解析耗时)导出到 StatsD 或 Prometheus,再在 Grafana 建面板与告警,能比只看界面更早发现调度劣化。
DolphinScheduler API 与自动化
DolphinScheduler 提供 REST API:用账号换 token 后可查询工作流、触发或停止实例、维护定时,适合接入发布系统做自动化上线与巡检。
XXL-JOB 分布式任务调度
XXL-JOB 面向 Java 应用:调度中心统一管理任务,执行器以 SDK 方式内嵌在业务应用里注册上报;支持 cron、分片广播、失败重试与 GLUE 在线编辑执行逻辑。
DAG 版本管理与发布
DAG 代码进 Git 走评审发布:保持 dag_id 与 task_id 稳定、用增量方式演进,回滚时能定位哪个版本从哪一刻生效,避免在生产目录手改文件。
数仓建模
分层架构、维度建模与指标口径
数仓分层总览(ODS/DWD/DWS/ADS/DIM)
离线数仓常见五层:ODS 贴源、DWD 明细、DIM 公共维度、DWS 轻度汇总、ADS 应用层;分层解决复用、口径统一与链路可维护问题,代价是存储与调度节点增加。
DWD 明细层设计
DWD 按业务过程组织明细:完成清洗、类型统一、字段命名规范与必要的维度退化,一行代表一次业务事件(或一天明细),是后续所有汇总的公共数据源。
ODS 贴源层设计
ODS 与源系统保持同构:字段名、类型尽量不动,只做落地与分区管理,保留原始信息便于对账与回溯;常见做法是增量抽取与周期全量快照两条链路并存。
DWS 轻度汇总层设计
DWS 按主题域对明细做轻度汇总(常见按天加用户或商品等维度粒度),目标是让多个下游共享同一份汇总结果;粒度过粗会丢维度组合,过细则收益有限。
维度建模基础(事实与维度)
维度建模把业务抽象成两类表:事实表存可度量的业务事件(数值加外键),维度表存描述性属性(谁、什么、哪里、何时);查询时事实与维度连接,结构直观、聚合友好。
ADS 应用层设计
ADS 面向具体消费场景(报表、看板、接口、导出),把多张 DWS/DWD 组装成结果表;指标口径、过滤条件、排序都在这一层显式写清楚,方便核对与回溯。
星型模型
星型模型:一张事实表直接连接若干维度表,维度保持反规范化(层级字段落在同一张维表里);查询连接少、易理解,代价是维度存在冗余。
维度建模四步法
Kimball 四步法:① 选业务过程 ② 声明粒度 ③ 确定维度 ④ 确定事实(度量)。四步里粒度最关键,粒度定错后续所有汇总都要返工。
缓慢变化维 Type 2:版本化保留历史
Type 2 在属性变化时关闭当前版本、插入新版本行,用生效起止区间区分;事实表引用当时的代理键,因此历史指标可以按当时口径复现,是数仓常用的历史保留方式。
事实表类型总览
事实表按业务形态分四类:事务事实表(一次事件一行)、周期快照(固定周期状态)、累积快照(流程多阶段一行)、无事实事实表(只记录关系);选型由要回答什么问题决定。
缓慢变化维总览(SCD)
缓慢变化维解决维度属性随时间改变的存储问题:Type 1 直接覆盖、Type 2 新增版本行保留历史、Type 3 增加列存前值;选哪种取决于是否需要用历史属性还原当时口径。
事务事实表
事务事实表记录每次业务事件,只追加不修改,是粒度最细、用途最广的事实表;可加度量(金额、数量)在这里定义,留存、复购等分析都由它派生。
维度表设计
维度表承载描述属性与层级:主键(代理键)、业务键、名称与分类层级、生效状态;宽而扁平、一行一实体,是 BI 切片筛选的主要入口。
拉链表设计与使用
拉链表是 SCD Type 2 的常见落地形态:一行等于实体某段状态区间,用 start_date 与 end_date 表示有效范围,end_date 为极限日期表示当前有效;按天增量维护、只存变化。
指标体系搭建
指标体系把零散指标整理成分层结构:原子指标(业务过程加度量加聚合)、派生指标(原子指标加时间周期与限定)、衍生指标(在派生指标上再做比率或复合计算),并明确主题域归属与责任人。
分层边界与加工下沉判断
判断加工写在哪一层的实用标准:涉及业务规则(枚举映射、金额口径)放 DWD;多需求共用的聚合放 DWS;一次性或强业务定制放 ADS。放反会造成重复计算或口径分裂。
周期快照事实表
周期快照按固定周期(常见每天)记录状态与存量:库存量、账户余额、会员等级分布;粒度是周期 × 实体,通常以覆盖写入当日分区的方式生成。
粒度声明与唯一键校验
粒度声明回答一行代表什么,并以主键或唯一键固化:订单明细用订单号加明细序号,日快照用日期加实体键;没有唯一键的表几乎必然产生重复数据。
雪花模型
雪花模型把维度进一步规范化:省掉冗余、结构更接近源系统;缺点是查询要穿过更多连接,BI 使用与变更维护更繁琐,适合维度层级复杂且变更频繁的场景。
代理键与自然键
代理键是数仓生成的无业务含义整数键(自增或序列),用于事实表关联维度并支撑缓慢变化维的多版本;自然键(业务键)用于与源系统对齐、识别同一实体。
指标口径管理
口径管理把每个指标的定义写清楚:统计范围、过滤条件、时间口径、去重键、归属层级与责任人;统一收口在指标字典,变更走评审,报表与接口都以字典为准。
数仓命名规范
命名规范用固定结构表达层次、主题、粒度与更新频率:层级前缀加主题域加业务描述加周期后缀(1d/1h/nd/di/df),一个名字就能读出属于哪一层、什么数据、多久更新。
数仓表分区与分桶设计
分区按日期(dt/ds)切分便于增量覆盖与裁剪,分桶按高基数列散列便于采样与连接优化;分区字段要能用等值或范围条件过滤,否则起不到裁剪作用。
累积快照事实表
累积快照在一个流程实例(如订单)上记录各里程碑时间戳与当前状态,随流程推进被更新;用于计算阶段耗时、流转率与超时监控。
一致性维度与一致性事实
一致性维度指多个事实表共用同一套维度键与属性定义(如全公司统一的日期、商品、用户维度),是跨主题拼接分析的前提;一致性事实指同名指标在不同报表中口径一致。
拉链表增量维护 SQL
拉链维护三步:找出变化实体(与最新快照比对)、关闭旧链、插入新链;每日增量执行,首次用全量快照初始化。
宽表设计
宽表把常用维度属性与度量拼到一张表里,减少查询连接、提升交付效率;代价是更新耦合与存储放大,适合变化频率低、复用度高的核心主题,不适合承载所有临时字段。
时间维度表设计
时间维度表把日期展开为多列属性:年月日、周、季度、是否节假日、是否工作日等,供报表按任意时间层级切片;一次构建长期复用,节假日与调休需要人工维护。
退化维度
退化维度是没有独立维度表的业务标识符(订单号、流水号、发票号),直接存进事实表;既能唯一定位业务事件,又免去为高基数字段单独建维度。
角色扮演维度
同一个维度在事实表中扮演多个角色:日期维度同时作为下单日期、支付日期、发货日期;建模时复用同一张维度表并通过不同别名或视图使用,避免复制多份。
缓慢变化维 Type 1:直接覆盖
Type 1 用最新值覆盖旧值,不保留历史;实现简单、维度表不膨胀,但历史指标失去当时口径,适合纠错类变更或本身无分析价值的属性。
总线矩阵与实施路线
总线矩阵用行表示业务过程、列表示一致性维度,单元格标记该过程是否涉及该维度;它把企业级建模拆成可分批交付的迭代路线,每批都围绕公共维度对齐。
原子指标与聚合方式
原子指标是不能再拆分的业务度量:业务过程、度量字段、聚合方式三者固定;金额类用 SUM、次数类用 COUNT、去重主体用 COUNT DISTINCT,聚合方式确定后不应随报表变化。
派生指标与衍生指标
派生指标等于原子指标加修饰词(统计周期、业务限定、维度),如近 7 天新客支付金额;衍生指标在多个派生指标之间计算,如比率、同比、占比,分子分母口径必须一致。
留存分析模型
留存模型按首日分组加后续活跃天数组织:先取用户首日行为日期作为 cohort,再统计第 N 日或第 N 周是否活跃;输出明细留存表或透视结果,供看板展示留存曲线。
数据仓库与数据湖的关系
数据仓库面向结构化、强治理、口径稳定的分析;数据湖面向前置存储多形态原始数据、schema 后置;湖仓一体在对象存储上叠加表格式(Iceberg/Hudi/Delta)与 SQL 引擎,兼顾两者。
无事实事实表
无事实事实表不存数值度量,只记录发生过或满足条件的关系:活动参与、内容浏览、覆盖清单;统计时对行数计数即可,常用于覆盖率与去重用户分析。
OLAP 引擎与模型选择
分析引擎按建模方式分 ROLAP(关系表实时计算)、MOLAP(预计算多维立方体)、HOLAP(混合);工程上更常按“预聚合还是即席查询”取舍,前者空间换时间,后者时间换空间。
漏斗分析模型
漏斗模型按步骤统计各环节到达人数与转化率:步骤定义、时间窗口、去重主体三者固定;常见落地为用户乘步骤的宽表或每步一张指标表,支持整体与分渠道查看。
数据地图与元数据
数据地图(元数据平台)登记表结构、字段含义、负责人、更新频率、分区信息与血缘,是找数、认责与影响分析的基础设施;元数据可从引擎与调度系统自动采集,再补充业务说明。
物化视图与预聚合加速
物化视图把预聚合结果物化存储,由引擎按需改写查询;也可用普通汇总表加调度刷新实现。关键点是刷新策略(全量或增量)、数据新鲜度与失败回退。
杂项维度
杂项维度把事实表中若干低基数、彼此无关的标志位(是否新客、是否加急、来源渠道标记)合并成一张维度表,用组合编码压缩事实表宽度,避免为每个标志单独建维度。
桥接表处理多值维度
当一条事实对应多个维度取值(一笔订单多张优惠券、一个客户多个标签)时,事实与维度是多对多关系;桥接表存两者中间关系并按需加权,避免事实行被复制放大。
数据集市与主题集市
数据集市面向单一主题域(交易、流量、财务)的定制化数据集合,可来自数仓公共层,也可独立建设;独立集市容易形成口径孤岛,推荐在公共层之上做轻量集市。
主题域划分
主题域按业务对象与分析视角切分(交易、用户、商品、流量、财务、物流等),是数仓目录、权限与责任分工的基本单位;划分标准要稳定、能覆盖需求、边界不重叠。
数仓表生命周期与归档
生命周期策略决定明细保留多久、汇总保留多久:热数据留近 N 天、冷数据转低频存储或归档,删除前先确认血缘与合规要求;常用手段是按分区批量清理。
OneData 方法论要点
OneData 强调一致性:统一命名与口径、统一维度与指标定义,按 ODS 到 ADS 分层建设公共层,指标以原子指标加修饰词的方式沉淀,减少重复加工与口径分裂。
数据血缘与影响分析
血缘刻画表与字段之间的上下游依赖,通常来自 SQL 解析与调度依赖;实用价值是变更前评估影响面、故障时定位受损范围、找数时看清来源链路。
缓慢变化维 Type 3:保留前值列
Type 3 在维度表增加上一版本列(如 current_level 与 previous_level),只保留有限的变更历史;结构简单、查询不用处理区间,但可记录的版本数固定。
Data Vault 建模要点
Data Vault 用三类表表达企业数据:Hub 存业务键、Link 存实体间关系、Satellite 存描述属性与变更历史;结构可扩展、加载可并行,代价是查询组装复杂,通常再叠加一层星型集市对外服务。
建模评审与上线检查
新表上线前过评审:确认主题域与分层归属、粒度与主键、命名规范、分区策略、口径一致性、血缘与负责人;团队规模小时可用检查清单替代正式评审会。
数仓存储与计算成本治理
成本治理从三处入手:存储(生命周期与压缩格式)、计算(避免全表扫描与重复加工)、调度(错峰与资源队列);结合用量账单按表与任务排名,优先处理高消耗长尾。
数据质量
校验规则、稽核与问题定位
数据质量六维度
数据质量通常按六个维度衡量:完整性(该有的有没有)、唯一性(是否重复)、一致性(跨表跨系统是否对得上)、及时性(是否按时产出)、准确性(是否与事实相符)、有效性(是否符合格式与取值约束)。
完整性校验
完整性校验关注缺失:字段空值率、分区是否存在、主体集合是否齐全(例如当日应出现的门店是否都有数据);按业务键比对白名单是实用性较高的完整性问题发现方式。
唯一性校验
唯一性校验确认业务键在目标粒度上不重复:按主键分组计数大于 1 即为重复;重复主要来自上游重跑叠加、关联放大与去重键选错。
一致性校验
一致性校验确认同一事实在不同表、不同系统或不同层级之间口径一致:订单金额与明细汇总一致、数仓与源库账单一致、指标在 DWS 与 ADS 一致;差异要能解释。
行数比对与波动检查
行数比对是最基础的稽核:源与目标同口径计数比对、当日与近 7 日基线比对;差异超阈值即告警,是发现抽取断流、过滤条件误改的快速手段。
及时性校验
及时性校验关注数据是否按时可用:分区产出时间与承诺时间(SLA)比较、最新分区滞后天数、下游开始时间是否早于上游完成时间;及时性问题通常要治调度而不是治数据。
空值检测 SQL 模板
空值检测按字段批量输出空值行数与空值率,并按表汇总成稽核结果,便于趋势对比;关键字段(主键、金额、时间)建议设严格阈值。
数据质量问题定位四步法
定位流程:① 复现现象(确认时间范围与影响面)② 缩小范围(按分区、维度、单条键下钻)③ 沿血缘找变更(上游任务、DDL、参数、数据源)④ 修复并加校验防复发。
准确性校验
准确性校验确认数值与事实相符,较难完全自动化:常用方法是与权威来源核对(源系统账单、第三方对账单)、采样人工复核,以及业务规则校验(单价乘数量等于金额)。
有效性校验
有效性校验检查取值是否合法:枚举是否有字典外值、数值是否在合理范围、格式是否符合(手机号、日期字符串、编码位数);常用于在 DWD 层拦截脏数据。
金额勾稽与总分核对
金额勾稽用总账到分账的两级核对:先核对总额,再逐维度核对分类合计,最后定位到单据;差异按绝对值和比例双阈值判定,退款与优惠等业务规则要先对齐。
枚举与数值范围校验规则
枚举校验维护一份字典(状态、渠道、币种),范围校验按业务定义上下限(金额非负、折扣在 0 到 1、年龄 0 到 150);规则可配置化,字典更新后有评审记录。
跨表一致性稽核
跨表稽核把同一事实在两张表的汇总值比对:主表与明细、DWD 与 DWS、DWS 与 ADS;差异按业务维度下钻定位,避免只看总数掩盖局部偏差。
dbt 数据测试(schema 测试)
dbt 在模型 YAML 中声明通用测试:unique、not_null、accepted_values、relationships;dbt test 执行后失败即返回非零退出码,天然适合接入调度与 CI 做质量卡点。
数据 SLA 与承诺时间
SLA 把什么时候必须可用变成可度量的承诺:按表设定承诺时间与依赖条件,统计达成率与超时原因分布;SLA 是调度资源分配与升级机制的依据,不只是对外承诺。
跨系统对账体系
跨系统对账按三层建立:明细级对账(单据逐笔)、汇总级对账(按日与维度)、差异跟踪(差异原因分类与闭环);对账频率与容差需与业务、财务共同确认。
主键重复定位 SQL
定位重复不止要计数,还要看清重复行内容:把重复组与明细行一起打印,比较加载时间、来源标记等字段,能快速判断是重跑叠加还是关联放大。
数据质量规则引擎
规则引擎把校验规则从代码变成配置:规则名、目标表、过滤条件、校验类型、阈值、告警级别、责任人;调度平台按表与周期批量执行并汇总结果,新增规则不用改任务代码。
Great Expectations 数据校验入门
Great Expectations(GX)用“期望”(Expectation)描述数据应满足的条件,对批次数据跑校验并生成可读报告;核心对象是数据源、批次、校验器与 Expectation Suite,适合在管道中做可复用校验。
dbt 自定义测试与严重级别
除通用测试外,dbt 支持在 tests 目录写单条 SQL 作为自定义测试:查询返回任何行即失败;结合 config 的 severity 与 warn_if、error_if 阈值,可把不同严重度的校验分开处理。
质量看板与质量分
质量看板按表、规则、维度汇总通过率:单规则通过率、表级质量分、链路覆盖情况;质量分多按规则加权计算,突降即触发排查,同时暴露长期未执行的规则。
波动监控与基线告警
基线告警用历史分布判断当前值是否异常:与近 7 天或近 4 周同星期均值比较、用分位数设区间,并叠加业务日历(大促、节假日)修正;比固定阈值更抗业务波动。
数据新鲜度监控
新鲜度监控跟踪每张关键表最新分区的更新时间与业务时间差,按承诺时间分级告警;它回答的是现在能不能用的问题,是值班看板的常用首屏指标。
质量问题分级与告警策略
把质量问题按影响面与紧迫度分级:P1 影响对客交付或资金口径、P2 影响内部报表、P3 提示类;不同级别对应不同通知渠道与响应时限,避免所有告警都走同一条路径。
稽核结果表设计
稽核结果表统一存储每次校验结果:规则、对象、分区、检查维度、样本量、失败量、是否通过、耗时与明细;它是看板、告警与复盘的数据基础,字段设计要支持按时间与对象下钻。
血缘辅助问题定位
血缘把数据不对转成哪个任务、哪次变更导致的:从出问题的表出发看上游任务与最近代码变更,再看下游受影响清单;配合任务运行记录可快速圈定变更时间窗。
数据质量事故复盘
数据质量事故在止血之后要做复盘:还原时间线(何时出错、何时告警、何时恢复)、界定影响面(哪些表与下游、影响哪些业务日期)、定位根因(代码 / 数据 / 流程 / 工具)、产出可验收的改进项并跟踪闭环。
Amazon Deequ 数据质量库
Deequ 是构建在 Spark 之上的数据质量库:对 DataFrame 定义约束(完整性、唯一性、合规性等),一次扫描计算多项指标,支持结果导出与约束建议;适合已有 Spark 链路的团队在写入前做批量校验。
常用 Expectation 速查
常用期望覆盖行数、唯一性、取值范围、枚举集合、正则格式与统计量:表行数在区间内、主键唯一、金额非负、状态在集合内、手机号匹配正则,组合成 Suite 后可批量执行。
上线质量卡点(CI 集成)
把数据校验接进发布流程:模型与调度变更后先跑集成测试与质量规则,通过才允许发布到生产;卡点要区分阻断级(键完整、金额勾稽)与提示级(波动类)。
Spark 聚合式质量校验
不引入额外框架时,用一个 Spark SQL 聚合作业即可一次扫描产出多项质量指标:行数、空值数、负值数、重复数;结果写入稽核表并按天与基线对比,比单一绝对阈值更早发现异常。
数据回刷后的复检清单
回刷完成后要复检而不是直接宣布修复:核对回刷分区的行数、主键、金额与源端一致;确认下游依赖任务已重跑或已通知;确认增量任务从正确位点继续;把回刷范围与原因写入变更记录。
抽样校验设计
全量逐行校验成本高时用抽样:按业务维度分层(渠道、门店、金额段)随机取样,样本量按可容忍误差估算;抽样适合准确性人工复核与超大表初筛,但主键唯一、金额勾稽等关键校验仍建议全量执行。
质量规则优先级与收敛
规则不可能一次做全:按“影响面 × 发现能力 × 实现成本”排优先级——先覆盖核心链路的关键字段(主键、金额、时间、状态),再补提示类规则;定期清理长期未命中的规则,避免规则膨胀后告警无人处理。
脏数据处理策略:拦截/隔离/放行/降级
脏数据有四种处置策略:拦截(阻断下游并告警)、隔离(转隔离区,主流程继续)、放行并标注(容忍小比例错误但打质量标记)、降级(用上一日数据兜底)。策略按字段重要性与下游用途选择,并写入数据字典。
指标双算对账
指标双算用两条相互独立的路径计算同一指标后比对:例如 GMV 既从支付流水汇总、也从订单明细汇总,按天比对,差异超容差即排查;双算路径不能共用同一段清洗逻辑,否则错误会被两条路径同步复制。
源头治理与数据契约
数据质量的根因常在源头:与上游约定字段非空、枚举、更新时效等约束(数据契约),在入库前做格式与范围校验,把问题挡在入口;上游的结构与口径变更纳入通知与评审流程,避免下游被动发现。
实时链路的数据质量校验
流式链路的校验在管道内完成:对每条记录做轻量检查(主键非空、金额非负、枚举合法),错误记录写入死信队列;重校验(跨表关联、全量比对)放到旁路批作业,避免拖慢实时链路。
脱敏数据的质量校验
脱敏前后要校验三件事:脱敏后字段仍符合格式规则、业务键的稳定映射保持(同一明文得到同一脱敏值可关联)、统计分布不被破坏(均值与分位数在容忍范围内);用固定样本比对脱敏前后可比指标。
分区空洞与空分区检查
分区检查覆盖三类问题:应有分区缺失、分区存在但行数为 0、行数远低于基线的“小分区”;分别对应调度失败、上游确实无数据、过滤条件误伤等原因,检查结果按链路汇总到值班看板。
增量空洞检测
增量同步的空洞检测用主键集合做差集:昨日存在、今日消失的主键(排除正常删除),以及状态回退的记录;CDC 断链重放或任务漏跑都会在主键集合上留下痕迹,按日快照主键集合是发现空洞的直接方法。
质量误报治理
误报治理决定质量体系能否长久运行:对高频误报规则先复盘阈值依据(基线区间、业务日历、季节性),再调阈值、加白名单或改用相对波动判断;长期无法收敛的规则要明确下线并说明原因,保持规则集可信。
稽核任务并行度与资源控制
稽核任务本身消耗集群资源:按表与分区拆分并行、限制并发度、错峰到核心链路产出之后运行;大表校验优先分区级扫描与增量窗口,避免与核心 ETL 抢资源,也避免全表扫描的浪费。
隔离表(quarantine)设计
隔离表集中存放校验失败的行:原始字段、失败规则、失败时间、来源分区,供人工修复与重放;按天分区、设保留策略,并配“隔离量趋势”监控,隔离量突然升高通常意味着上游发生了变化。
空值与默认值陷阱
空值与默认值是两件事:默认值会掩盖缺失(空串、0、1970 时间戳),把“没有数据”伪装成“有数据”;校验要同时查 NULL 与可疑默认值,并统一指标计算中 NULL 的处理方式(COUNT 忽略 NULL、AVG 忽略 NULL)。
时区与跨天边界校验
跨时区系统的日期边界是事故高发点:源库 UTC 与数仓本地时区混用会把当日数据切到前一天;校验关注时间字段的时区标注、跨天边界样本(23 时到 1 时附近的记录)与整点分布,统一在入口做时区归一。
质量规则的自测
质量规则本身也要测试:用构造数据(全空列、重复主键、越界枚举、边界值)跑一遍,确认该失败的能失败、该通过的不误报;规则上线前用历史分区回放,评估误报率与命中量。
跨库类型与精度校验
跨库同步的类型映射要逐字段核对:decimal 精度、float 近似、char 定长补空格、字符集(utf8mb4 与 gbk)、时间精度(秒与毫秒);类型不匹配会以“值被截断、科学计数、比较不等”的形式制造难查的差异。
质量规则的版本管理
质量规则是配置也是资产:用代码或平台版本化规则(谁改的、改了什么、为什么改),变更走评审与回放验证;避免直接在生产调整阈值不留记录,否则告警行为与指标口径都无法追溯。
表级质量标签
给表打质量标签,让下游选表有依据:标签维度包括是否按时产出、最近是否有失败规则、是否存在已知问题(挂账);标签由平台自动更新并在数据目录展示,重要消费方接入前先看标签再看数据。
CDC 与同步
变更数据捕获原理与同步工具要点
MySQL binlog 二进制日志基础
binlog(二进制日志)是 MySQL Server 层记录的变更日志,按事件顺序追加数据修改与 DDL,是主从复制与 CDC 增量捕获的基础。用于 CDC 需要开启 log_bin、使用 ROW 格式,并为实例配置集群内唯一的 server_id。
Debezium:Kafka Connect 上的 CDC
Debezium 是开源的 CDC 平台,以 Kafka Connect 连接器形式读取 MySQL、PostgreSQL、Oracle、SQL Server、MongoDB 等数据源的日志,把行级变更输出为结构化事件(before/after、op、来源位点)发送到 Kafka;也提供 Debezium Server 形态直接投递到 Kinesis 等目标。
CDC 变更数据捕获:概念与实现方式
CDC(Change Data Capture,变更数据捕获)指持续从数据库日志(binlog/redo/WAL)等来源抽出增量变更,与全量重拉相比只搬运变化的数据,适合数仓实时同步、缓存失效、搜索索引更新与微服务数据复制,通常与初始快照配合完成开荒。
Flink CDC:把 CDC 做成 Flink 连接器
Flink CDC 将 CDC 数据源封装为 Flink 连接器(mysql-cdc、postgres-cdc、oracle-cdc、mongo-cdc 等),用 SQL 或 DataStream 直接消费增量并流式加工;2.x 的增量快照算法支持并发快照与断点续读,3.x 提供 YAML 管道做多表整库同步。
Debezium MySQL 连接器配置
Debezium MySQL 连接器以 JSON 提交到 Kafka Connect REST 接口(POST /connectors)。关键项:connector.class、topic.prefix(2.x 起替代 database.server.name)、database.server.id、库表过滤清单与 schema 历史主题,以及快照模式。
binlog 三种格式:ROW/STATEMENT/MIXED
MySQL binlog 支持三种格式:STATEMENT 记 SQL 语句、ROW 记每行前后镜像、MIXED 按语句自动选择。CDC 必须使用 ROW,只有行级镜像才能稳定还原增删改数据;语句级日志里 NOW()、UUID() 等非确定函数会导致回放与解析不一致。
Canal:伪装从库的增量订阅
Canal 是阿里开源的 MySQL binlog 增量订阅组件(Java 实现):把自己伪装成从库,向主库发送 dump 协议请求,收到 binlog 后解析成结构化 Entry(含 RowChange),再投递给客户端或消息队列。在 Debezium/Flink CDC 普及前,它是国内使用较多的 CDC 方案。
DataX:批式数据同步与 job.json
DataX 是阿里开源的离线数据同步工具(Java),用 job.json 描述 reader 到 writer 的搬运,插件覆盖 MySQL、Oracle、Hive、HDFS、Kafka、ClickHouse 等数据源;channel 控制并发,适用于数仓开荒导入与临时取数,但它是批式抽取,不具备日志型 CDC 的实时与删除捕获能力。
Debezium 事件结构与 op 字段
Debezium 事件用 op 区分变更类型:c=INSERT、u=UPDATE、d=DELETE、r=快照读取。事件包含 before/after 行镜像、source 元数据(库表、binlog 文件与位点、GTID)与 ts_ms 时间戳;消费侧通常按 op 决定 upsert 或 delete,Kafka key 默认是表主键。
Flink SQL 声明 MySQL CDC 源表
connector=mysql-cdc 的源表需要 hostname/port/username/password/database-name/table-name 六项基础配置,主键必须声明为 PRIMARY KEY NOT ENFORCED(增量阶段依赖它做 upsert 与去重);server-time-zone 与源库一致可避免时间列整体偏移。
binlog_row_image:行镜像粒度
binlog_row_image 控制 ROW 格式每行事件记录哪些列:FULL 记录前后镜像的全部列(默认),MINIMAL 只记被修改列与定位行的键列,NOBLOB 类似 FULL 但不重复记录未变更的 BLOB/TEXT。CDC 与审计类消费依赖完整镜像,一般要求 FULL。
开启 binlog:my.cnf 配置要点
开启 binlog 需要在 my.cnf 的 [mysqld] 段配置 log_bin、server_id 与 binlog_format;log_bin 属只读参数,修改后需重启 mysqld 生效(MySQL 8.0 默认已开启)。云数据库由控制台参数组管理,开启前确认对备份与复制链路的影响。
Debezium snapshot.mode 快照模式
snapshot.mode 控制连接器启动时的快照行为:initial 先全量快照再转增量(默认);schema_only(旧名 no_data)只记录结构不导数据;initial_only 只做快照不继续增量;schema_only_recovery 用于修复 schema 历史主题后的重启。模式选错会漏数或重复初始化。
SHOW MASTER STATUS:查看 binlog 位点
SHOW MASTER STATUS 显示当前正在写的 binlog 文件(File)、写入偏移(Position)与已执行的 GTID 集合,是记录 CDC 启动位点与估算延迟的常用视图;MySQL 8.4 起该语句的新名称为 SHOW BINARY LOG STATUS。
mysqlbinlog:解析与导出 binlog
mysqlbinlog 把 binlog 文件解析成可读文本,用于事后恢复与问题定位。ROW 格式必须加 --base64-output=DECODE-ROWS -vv 才能看到伪 SQL;支持按时间、位点、库过滤,也能用 --read-from-remote-server 从运行中的实例拉取日志。
GTID:全局事务标识符
GTID 形如 server_uuid:序号,为每个已提交事务生成全局唯一编号,让复制与断点续传不再依赖文件名和偏移。开启需 gtid_mode=ON 且 enforce_gtid_consistency=ON,切换要按 OFF → OFF_PERMISSIVE → ON_PERMISSIVE → ON 四步过渡。
PURGE BINARY LOGS:清理 binlog
手动清理 binlog 用 PURGE BINARY LOGS TO(删除到指定文件之前)或 BEFORE(删除指定时间点之前),需要 BINLOG_ADMIN 或 SUPER 权限。清理前必须确认从库与 CDC 消费位点都不在待删区间内,否则只能重建链路。
CDC 账号权限清单
日志型 CDC 需要专门的只读账号:读数据要 SELECT,拉取 binlog 要 REPLICATION SLAVE 与 REPLICATION CLIENT,做一致性快照的部分工具还需要 RELOAD 与 SHOW DATABASES。按需授权、不授予写权限,并把账号来源收敛到部署机网段。
Debezium schema 历史主题
Debezium 用 schema 历史主题记录数据源的 DDL 演进(建表、加列、改列),解析 binlog 时按历史结构还原行的字段布局。该主题(schema.history.internal.kafka.topic)必须可持久化并采用 compacted 清理策略;丢失后 DDL 之后的解析会错位。
flink-cdc scan.startup.mode 启动模式
scan.startup.mode 决定 CDC 源从何处开始消费:initial(默认,先快照全量再跟增量)、earliest-offset、latest-offset、specific-offset、timestamp。无状态作业从 latest-offset 起会跳过历史,有状态作业通常用 initial 或直接依赖状态恢复。
幂等落库:主键 upsert
增量同步最常见的幂等写法是主键 upsert:MySQL 用 INSERT ... ON DUPLICATE KEY UPDATE,PostgreSQL 用 INSERT ... ON CONFLICT,Hive/Spark/Iceberg/Delta 用 MERGE。同一主键重复消费只会覆盖成相同结果,天然容忍重放;delete 事件要另行按主键删除或标记。
binlog 保留期与 binlog_expire_logs_seconds
自动过期由 binlog_expire_logs_seconds 控制(MySQL 8.0 默认 2592000 秒即 30 天),旧参数 expire_logs_days 已弃用。保留期需要覆盖“同步故障被发现的时间 + 修复时间”,CDC 链路的位点滞后决定了安全下限。
CDC 断链:找不到 binlog 文件
CDC/复制断链的典型报错是找不到所需 binlog 文件(如 Could not find first log file name in binary log index file),根因多为保留期太短、消费位点落后于清理点,或有人手工清理了日志。先核对文件是否仍存在,再选择补位点或重建快照。
Kafka Connect worker 配置要点
用 Debezium 就绕不开 Kafka Connect 的运行配置:worker 需要 bootstrap.servers、group.id(集群名)、offset/config/status 三个内部主题与序列化转换器;开发用 standalone,生产用 distributed 并通过 REST 接口管理连接器。
Flink CDC 与 checkpoint 位点提交
Flink CDC 的增量位点随 checkpoint 提交:源算子把 binlog 位点写进检查点,故障恢复从最近成功检查点续读(可能少量重复,靠下游幂等兜底);没开 checkpoint 的作业重启只能按启动模式重来。
全量与增量衔接方案
开荒同步的关键是全量与增量的衔接点:常见方案有停写窗口、锁表拿位点、从库做快照,以及工具内置的“快照 + 位点衔接”(Debezium initial 快照、Flink CDC 增量快照)。自研方案必须固定位点在前、全量导出在后,再从该位点追平。
CDC 快照一致性:位点与导出衔接
初始快照必须与增量衔接:先在源端取得位点(或 GTID),再导出数据,随后从该位点继续消费,中间不能丢窗口。常用做法有一致性事务导出(mysqldump --single-transaction)、短暂锁表、在从库执行快照;Debezium 等工具内置了快照与位点的衔接逻辑。
Canal 部署与 instance 配置
Canal Server 部署三步:解压发布包、编辑 conf/canal.properties(serverMode 与 destinations)、编辑 conf/<destination>/instance.properties(数据源与过滤规则)。实例配置里 master 地址、账号、slaveId、filter.regex 是需要按环境调整的项,启动后看 logs 目录日志确认连接成功。
Debezium 位点存储与重置
Debezium 的消费位点存在 Kafka Connect 的 offset 存储主题(connect-offsets)里,包含 binlog 文件名与位点或 GTID,连接器重启后从该点继续;位点按源端实例标识区分,换 server.id 会被当作新环境触发重新快照。
CDC 与源端 DDL 变更处理
源端 DDL 是 CDC 链路的高频事故源:加列通常影响小,删列/改类型/改主键会让下游解析或写入失败;RENAME 与 TRUNCATE 在 binlog 中表现为 QUERY 事件而非行事件。落地要有“先下游兼容、再执行变更”的发布流程,工具侧只能缓解、不能替代流程。
同步积压排查路径
同步延迟排查按链路分段:源端位点是否推进、工具消费位点是否推进、中间队列是否有积压、目标端写入是否变慢(锁等待、批量大小、主键冲突、大事务阻塞)。逐段对比“生产速率与消费速率”,比反复调参数更快找到瓶颈。
SHOW BINARY LOGS:日志文件清单
SHOW BINARY LOGS 列出实例上的 binlog 文件、大小与加密状态,用于评估磁盘占用、确认保留时长,以及在 CDC 报“所需 binlog 不存在”时核对目标文件是否已被清理。
Flink CDC YAML 管道:整库同步
Flink CDC 3.x 提供 YAML 管道:用 source/sink/pipeline 三段声明数据流,bin/flink-cdc.sh 提交,适合把整库或一批表同步到消息队列、湖仓等目标,并可做库表改名路由,减少逐表写 SQL 的重复工作。
Sqoop 增量导入与退出维护
Sqoop 是 Hadoop 生态的 RDBMS 导入导出工具:import 把表搬进 HDFS/Hive,支持 --incremental append(按自增列)与 lastmodified(按时间列)做增量。项目已进入 Apache Attic 停止演进,新项目多改用 DataX、Spark 或 Flink 作业替代。
源目标对账校验方法
同步校验常用三层:行数对账(分片统计)、主键集合比对(找缺失与多余)、按主键分桶的校验和/哈希比对。校验要按业务主键口径而非物理行数(软删除、重复行会干扰),大表分桶并行、缩窗比对,差异要能定位到主键范围。
回补与重放的设计要点
回补(backfill)是同步链路的常规操作:故障或口径调整后需要把某时间段数据重算或在目标端重放。设计要点是幂等(重放结果与执行一次一致)、限速(不压垮源与目标)、可观测(进度与差异可核对)、可中断续跑(大回补拆批并记录进度)。
binlog 事件类型速查
binlog 由事件流组成:WRITE_ROWS/UPDATE_ROWS/DELETE_ROWS 承载行级增删改,QUERY 事件承载 DDL 与 BEGIN,XID 标记事务提交,GTID 事件标记事务归属,另有 FORMAT_DESCRIPTION、ROTATE 等辅助事件。读懂事件类型才能理解 CDC 工具的输出。
GTID 与位点方式对比
位点方式(文件名 + 偏移)记录精确但耦合具体文件,binlog 清理或主库切换后容易失效;GTID 以集合表达“已执行哪些事务”,切换与续传更稳。CDC 工具两种都支持,但灾备演练与工具选型要统一口径,避免一边按位点、一边按 GTID。
Canal 投递 Kafka 配置
Canal 支持把解析结果直接投递到消息队列:在 canal.properties 设置 canal.serverMode=kafka、kafka.bootstrap.servers 与主题,配合 canal.mq.partitionHash 按主键分区。投递后由下游作业消费,业务方不必再直连 Canal Server。
DataX 限流与错误控制
DataX 的并发与限流在 job.setting.speed:channel 控制并发通道数、byte 限制每秒字节数(-1 不限)、record 限制每秒记录数;errorLimit 控制允许的错误记录数与比例,超出即失败。这些设置是保护源库与目标库的关键闸门。
CDC 落 Kafka 的主题设计
CDC 落到 Kafka 常按一表一主题(Debezium 默认命名为 <topic.prefix>.<库>.<表>),消息 key 用主键保证同键分区有序;表多时可路由合并主题,高变更量表按峰值吞吐规划分区数,需要“每键最新值”语义的主题可评估 compact 清理策略。
CDC 落湖仓:主键 merge 与乱序处理
数据湖表格式让增量落湖具备主键能力:Hudi 提供 upsert(COW/MOR),Iceberg 支持行级删除与 MERGE INTO,Delta Lake 提供 MERGE。CDC 数据通常按主键 merge 到湖表,用事件时间排序处理乱序,删除按墓碑行或直接删除。
CDC 与同步工具选型对照
选型先看三件事:源端数据库类型与版本、团队是否已有 Kafka/流计算运维栈、需要的是实时增量还是批量搬运。Canal 适合 MySQL 增量订阅,Debezium 贴合 Kafka 生态,Flink CDC 适合要直接做流加工的链路,Maxwell 轻量,DataX 面向批式全量/限范围抽取。
CDC 进数仓的落地方式
CDC 进数仓有两条常见路径:ODS 建 append-only 变更日志表(保留全部变更,可重放、可审计),或直接 upsert 成贴源镜像表;之后由 DWD 负责去重、清洗与维度关联。直投 DWD 省存储但丢失变更全历史,补数只能依赖源端重放,要按追溯需求权衡。
PostgreSQL 逻辑复制与复制槽
PostgreSQL 变更捕获基于 WAL 逻辑解码:wal_level=logical 后可用发布/订阅(CREATE PUBLICATION / CREATE SUBSCRIPTION)或逻辑解码插件(pgoutput、wal2json)输出变更;复制槽记录消费位点,槽长时间不消费会导致 WAL 持续堆积占用磁盘。
Debezium 监控指标
Debezium 通过 Kafka Connect 暴露指标:MilliSecondsBehindSource 反映事件时间与处理时间的滞后,TotalNumberOfEventsSeen 统计事件总量,另有过滤与队列类指标。配合 JMX 或指标采集系统,对滞后持续上升、事件速率骤降设告警。
Maxwell:轻量 binlog JSON 输出
Maxwell 是 Java 实现的轻量 MySQL binlog 解析器,把变更输出为 JSON,支持标准输出与 Kafka/Redis 等生产者;配置精简(连接信息 + producer + 主题),适合快速给下游喂增量 JSON 的场景,位点保存在自身 schema 的数据表中用于重启续传。
重放去重:至少一次语义兜底
CDC 链路多为至少一次投递:作业重放、位点回退、消费者重平衡都会重复送同一变更。去重可在目标端(主键 upsert 最省事)、加工层(按主键与位点去重,状态存最近窗口)或消息层(Kafka 事务/幂等生产者,只覆盖链路段)实现。
删除语义:物理删除与逻辑删除同步
同步删除有两种口径:物理删除(目标端按主键 DELETE,与源端一致)与逻辑删除(保留行、置 is_deleted 标记)。若源端本身是 UPDATE is_deleted=1 式逻辑删除,CDC 看到的是 update 而非 delete,需要在加工层显式转换为删除语义,否则目标端会当成普通更新保留。
位点滞后监控设计
位点滞后比“延迟秒数”更可靠:定期采集源端当前位点与工具消费位点,换算成落后字节数与时间,并记录源写入速率与消费速率两条曲线;位点长时间不推进或 binlog 保留余量不足时提前告警。
Oracle CDC:LogMiner 与补充日志
Oracle 的日志型 CDC 依赖 redo 日志解析:常用路径是数据库内置的 LogMiner 与商业产品 GoldenGate,Debezium、Flink CDC 的 Oracle 连接器也多以 LogMiner 为基础。前置条件是开启归档与补充日志(supplemental logging),并按需授予采集账号相关权限。
Canal HA:ZooKeeper 主备
Canal 高可用依赖 ZooKeeper:多个 Canal Server 向 ZK 注册同一 destination,同一时刻只有一个 Active 提供服务,故障时 Standby 接管并从持久化位点继续。客户端通过 ZK 感知当前 Active 地址,切换期间要处理连接重建与位点确认。
Canal client 拉取与位点确认
Canal 客户端以批次为单位拉取并回执位点:getWithoutAck 拉取、业务处理成功后 ack 提交、处理失败 rollback 让位点回退。ack 时机决定消息语义——先处理再 ack 是至少一次投递,先 ack 后处理则可能丢消息;批大小与处理耗时决定吞吐和重投规模。