通过讲述数据集成数据同步的原理机制,理解数据同步的过程,进而对数据同步的执行效果有判断能力,判断数据同步效果具体包括:数据同步的数据量、目标端数据实际数量等。本文将为您列举一些常见数据质量方面的场景,方便您排查是否存在符合的场景,根据对应解决方案解决数据同步质量问题。
同步原理
DataWorks数据集成采用并行处理和插件化架构,以实现高效、稳定的数据同步。
并行执行模型(Job与Task)
为最大化数据吞吐量,同步任务采用两级运行结构:
作业 (Job):一个执行中的同步任务实例。
任务 (Task):Job的最小执行单元。一个Job会被切分为多个Task,这些Task可在单机或多机上并发执行。
每个Task负责处理一个独立的数据分片。通过这种并行处理机制,可显著提升整体数据同步的效率。
插件化数据流(Reader与Writer)
每个Task内部的数据流由读Reader插件和Writer插件通过一个内存缓冲区连接而成:
Reader插件:负责连接源数据存储,读取数据并将其推送至内部缓冲区。
Writer插件:负责从缓冲区消费数据,并将其写入目标数据存储。
Reader和Writer插件严格遵循各自数据源的原生读写协议与数据约束(如数据类型、主键限制等)。因此,最终的同步效果和数据一致性行为,直接取决于源端和目标端的具体实现规则。
写入端数据一致性排查
数据集成的Writer插件用来将源端读取到的数据写入至数据目标端,每一个目标数据源类型都会有对应的Writer插件,Writer插件会根据用户配置的数据写入模式(包括冲突替换策略),使用JDBC或者对应数据源SDK最终将数据提交给目标存储。
数据实际在目标端写入效果和数据内容,写入模式、目标表约束信息有关。
如果数据同步任务执行完成后,对于数据同步质量(数据条数、数据内容)有相关疑问,在写入端可以尝试从下列常见情况对照排查:
原因 | 问题描述 | 解决方案 | |
写入模式配置不当 | Writer插件会使用选择的写入模式将源头数据在目标端执行重放,如果源头数据和目标表结构出现数据约束,会对应导致数据插入失败(脏数据)、数据插入忽略、数据插入替换等行为。 | 根据业务需求选择正确的写入模式。详情请参见附表:关系型数据库写入模式详解。 | |
脏数据阈值触发 | 因数据类型不匹配、内容超长等原因产生的脏数据超出任务配置的阈值,导致任务失败,部分数据未写入。 | 确认脏数据出现的原因,并解决脏数据问题,或者确认可否容忍忽略脏数据。 | |
数据查询时机过早 | 在同步任务完成前进行数据查询。部分数据源(如Hive、MaxCompute(可配))的数据在任务结束前可能部分或完全不可见。 | 始终在确认同步任务实例成功运行后,再对目标表进行数据查询和校验。 | |
节点依赖缺失 | 下游分析任务与上游同步任务未配置明确的DAG依赖,导致下游任务在数据同步完成前开始执行,读到不完整的数据。 | 在DataStudio中为上下游任务配置明确的父子节点依赖关系。避免使用 | |
目标表、分区有多个同步任务同时在执行,并产生了干扰 | 不合理的同步任务并发执行。
|
| |
任务配置不能幂等执行 | 任务设计不具备幂等性(即多次运行结果不同),在重跑后导致数据重复插入或错误覆盖。 | 1. 优先将任务设计为幂等(如使用 | |
分区表达式错误 | 以MaxCompute为例,大多数情况下数据表都是分区表,分区值是DataWorks调度参数如$bizdate,常见的错误:
| 检查数据同步任务的变量表达式,即调度参数配置是否符合预期,同时,查看任务实例的执行参数是否符合预期。 | |
数据类型或时区不匹配 | 源端与目标端的数据类型或时区设置不一致,导致数据在写入时被截断、转换错误,或在比对时出现差异。 |
| |
目标端数据发生变化 | 目标数据源若被其他应用并发写入,将导致其内容与源端数据不一致。 | 确保在同步窗口内,目标表不被其他进程写入。若并发写入是预期行为,则需接受数据差异。 |
附表:关系型数据库写入模式详解
协议类型 | 写入模式 | 行为描述(当数据冲突时) | 行为描述(当数据不冲突时) | 主要适用场景 |
通用/MySQL协议 |
| 写入失败,产生脏数据。 | 正常插入新数据。 | 全量或增量追加,不希望覆盖或修改现有数据。 |
| 替换旧行。先删除旧行,再插入新行。 | 正常插入新数据。 | 需要用最新数据完全覆盖旧记录的场景。 | |
| 更新旧行。保留旧行,仅用新数据更新指定字段。 | 正常插入新数据。 | 需要更新记录部分字段,同时保留其他字段(如创建时间)的场景。 | |
| 忽略新行,不写入也不报错。 | 正常插入新数据。 | 只希望插入不存在的数据,对于已存在的记录不做任何操作。 | |
PostgreSQL |
| 忽略新行,不写入也不报错。 | 正常插入新数据。 | 只希望插入不存在的数据,对于已存在的记录不做任何操作。 |
| 更新旧行。使用新数据更新冲突行中的指定字段。 | 正常插入新数据。 | 更新记录的部分字段,同时保留其他字段(如创建时间)。 | |
| 丢弃冲突行。使用高性能 | 正常批量插入新数据。 | 大批量数据的高效追加,允许跳过已存在的重复记录。 | |
| 更新冲突行。使用 | 正常批量插入新数据。 | 大批量数据的高效同步,需要用最新数据完全覆盖旧记录。 | |
- |
| 不支持。 |
读取端数据一致性排查
数据集成的Reader插件用来连接具体的源头数据存储,抽取出待同步的数据并投递给同步写端。每一个存储类型都会有对应的Reader插件,Reader插件会根据用户配置的数据抽取模式(包括数据过滤条件、表、分区、列等),使用JDBC或者对应数据源SDK最终将数据抽取出来。
数据实际读出效果和数据同步机制、源头数据是否变化、任务配置等有关。
如果数据同步任务执行完成后,对于数据同步质量(数据条数、数据内容)有相关疑问,在读取端您可以尝试从下列常见情况对照排查:
问题 | 问题描述 | 解决方案 |
源端数据并发变更 |
| 接受此行为作为高吞吐量数据同步的正常预期。多次运行任务,其结果可能因源端数据的实时变化而存在差异。 |
错误的查询检查条件 |
| 检查数据同步任务的调度变量表达式,即调度参数配置是否符合预期,调度时参数替换值是否符合预期。 |
读端脏数据 | 读取源头数据时发生解析失败。这在结构化数据库中很少见,但在半结构化数据源(如OSS/HDFS中的CSV、JSON文件)中,可能因格式错误导致部分数据无法读取。 |
|
环境信息排查
问题 | 解决方案 |
查询数据时,数据源、表、分区选择错误 |
|
依赖产出未完成 | 如果是周期产出的数据(周期的数据同步任务、周期的全增量数据融合Merge任务等),需要检查下对应的依赖的数据产出任务是否正常执行并完成。 |
通用排查在您遇到数据质量方面的疑惑时,您可以尝试多次运行任务观察比对数据同步效果,也可以尝试切换源或者对目标数据源做对比测试,通过多次对比测试可以帮助您缩小问题排查范围。