一、先说人话:别盯着服务器的绿灯
集群里最常见的那种"监控"是这样的:CPU 不高、磁盘没满、进程都活着,一屏全绿。这屏绿只说明一件事——管子没爆。它一个字都没说水对不对。
业务真正怕的不是管子爆,是水压低了一点点:报表还能打开、页面还能点、数就是错的。没人报错、没人喊,等到有人拿这个数去开会,才发现已经错了三天。
所以这一页的监控只干一件事:把"数不对"翻译成"哪一段漏了、漏的是什么"。原文那条链路的说法很干脆,就是四段:源到贴源、入湖任务、湖仓 ETL 调度、湖到仓到页面。一段一块表,谁也不替谁。
整页只用三个词,不换:
- 表——看通不通。任务跑没跑完、同步断没断,都是压力表。
- 单——看干不干净。源端和湖里的行数、字段、数值对不对得上,都是化验单。
- 铃——负责喊人。表响了没人管,等于没装表;所以每块表后面必须挂一个责任人。
二、拆开看:表、单、铃三个零件
先认脸。三个零件各管一段话,认完再看它们在一根管子上怎么排。
像什么:水管上那个圆盘表,指针在绿区就是通,掉到红区就是没水。
其实是什么:调度系统里每个节点、每次同步的运行状态。它只回答"这段程序跑完了没有",不回答"数对不对"。
- 真名
status(任务状态);入湖节点CDM/DataX,出湖节点SeaTunnel- 在哪看
- 海豚工作流实例、SeaTunnel 概览页、Doris 监控面板
搞错了会怎样:把"指针在绿区"当成"水是好的"——这就是本页第六节那个反常识。
像什么:水厂每天抽一瓶水去化验:浑不浑、有没有泥沙、几项指标超没超。
其实是什么:源端和贴源层之间的差异记录——行数差多少、指标差多少、维度差多少。原文说这块"前期完成",也就是最早做的那一层。
- 表这一层
data_quality_monitor_table_dim:源端条数source_rows_nums对 hudi 端条数hudi_rows_nums,差在rows_diff- 字段这一层
data_quality_monitor_field_dim:字段类型差异,加前一天的均值 / 方差 / 最大最小 / 空值比例对比
搞错了会怎样:只比总行数、不比字段。字段类型从字符悄悄变成数字,行数一行不差,取数时整列变成空值——行数表全绿,页面全空。
像什么:门口那个铃。管子一漏就响,而且响在值班室,不是响在机房角落。
其实是什么:把表和单的结果按"页面 → 指标 → 表 → 任务 → 责任人"串成一行,出问题时推给那个该动手的人。
- 真名
- 表级监控模型那 14 个字段(第四节逐条过),其中
job_owner决定这声铃响给谁 - 在哪
- 全链路监控看板 + 明细页
搞错了会怎样:铃响在一个没人看的群里。第二天同一个地方照旧漏。
四段各自挂什么表
这张表是本页的骨架,四行就是四个段位。看的时候只记一件事:这一段挂的是表还是单,它替你回答什么问题。
| 段 · 挂什么表 | 它替你回答什么 |
|---|---|
| ①源→贴源 化验单:数据差异(行数、指标、维度) | 进厂的水,跟河里的是不是同一批、同一个量 |
| ②入湖 压力表:任务状态(CDM / DataX) | 这一车水到底运进来没有 |
| ③湖仓调度 压力表:任务状态 + 下游影响(海豚) | 这一段停了,会拖垮哪几张下游表 |
| ④湖→仓→页面 同步状态 + 表级血缘到帆软 | 仓里的水和龙头出的水,是不是同一批 |
这四段各自会冒出哪些异常,第三节一张一张拆开。先记一句话:①是化验单,②③是压力表,④是出口的同步状态加血缘。四块表不重叠,这也是排错快的原因——看到哪种异常,就知道该去哪个段。
第一段,源到贴源。这是进水口的表,也是最容易被跳过的一段。它不比"任务成功没成功",只比两边的东西对不对得上:源端删掉的行,湖里是不是还留着;源端新增的行,湖里有没有跟上来。这一段的监控前期就做完了,原因很简单——它最便宜,一次行数比对就能抓住大问题。
第二段,入湖任务。CDM 或 DataX 的任务状态。这段的意义原文写得很直白:入湖任务状态异常,会影响后续 ETL 的数据流转,最后导致前端数据异常。换句话说,②掉了,③④都白搭。
第三段,湖仓 ETL 调度。海豚里的加工任务。这段的表不只报自己坏了,还要报"坏了会拖垮哪些下游表、对应影响帆软的哪个场景模块"。这一段是四段里唯一需要血缘才说得清的一段——没有血缘,你只知道一个任务红了,不知道哪张报表今天别看了。
第四段,湖到仓到页面。SeaTunnel 把湖里的表同步进 Doris,页面再连 Doris。这一段断了,页面不会报错,只会一直显示昨天、前天的数。原文的结论一句话:同步任务状态异常,同样会影响帆软展示数据的准确性。
三、别只会说"失败了"
监控里最没用的一句话就是"任务失败"。它对齐不了动作:源端网络断了要去找源系统 IT,集群没资源要找运维,上游还没跑完只能等——三句话对应三类人,干的三件事完全不同。
所以原文把异常按组拆开,标签给机器看,含义给人看。三组,逐条来。
1)数据质量异常:化验单上说水不对
| 标签 | 原文含义 · 人话 |
|---|---|
source_delete | 源端删除。源系统把这行删了,湖里还留着。行数差 rows_diff 是正数:hudi 比源端多。 |
source_add | 源端新增,增量时间字段未生效。源端加了新数据,但增量抽取靠时间字段过滤,那个字段没更新——新行压根抽不进来。行数差是负数。 |
table_columns | 入湖表与源端字段差异。两边字段对不上:少一列、多一列、或者类型不一样。行数可能一行不差,字段已经错位。 |
这三个标签的区别很关键:前两个是"行数对不上",第三个是"行数对得上、字段对不上"。只看行数的人,永远抓不到 table_columns。
2)入湖 / 同步任务:压力表掉针
| 标签 | 原文含义 · 人话 |
|---|---|
failed | 任务失败,源端网络问题 / 集群资源问题。要么源库那边连不上,要么湖这边没资源给它跑。这是"真失败"。 |
stopped | 任务停止,任务超时问题。跑太久,被强制停下来了。不是它自己报错退出。 |
running | 任务持续运行中。还挂着没结束。跑十分钟正常,挂一整天就是问题。 |
这一组标签是两段共用的:cdm 入湖有这三个状态,cdm 同步到 dws 也是同样三项。所以看到 failed 第一件事不是去修,是看它属于入湖那段还是出湖那段——修反了白忙。
3)调度任务:海豚里的那段
| 标签 | 原文含义 · 人话 |
|---|---|
Failed | 集群资源问题 / 上游依赖任务失败。两种可能:自己没资源跑,或者前面那段根本没跑完。先看上游,再看资源。 |
Waiting | 上游依赖任务 running / 上游依赖任务 waiting。在排队等上游。不是它坏了,是还没轮到它。 |
Failed 是小写的 failed 之外的另一套:前者是海豚调度任务,后者是入湖/同步任务。看板里混着出现,靠 abnormal_label 那一列区分,别看错组。Waiting 不是故障,是排队。但排队时长能看出真问题:单个项目 756 个任务分布在 10 台 worker 上,其中 10.160.10.26 一台承接 218 个、排队 3.8 分钟,其余 9 台基本空闲。这不是任务慢,是活儿没分匀。看到一片 Waiting,先看资源分配,再看代码。
四、表级监控模型:14 个字段把整条链缝成一行
前面四段是分段看的。真正能干活的是表级这张表:一行不是"一个任务",是"一张表某一天的健康记录",从页面一路缝到源头。
原文给的字段一共 14 个。下面逐条过,每个字段后面那句人话,就是它在一条告警里替你回答的问题。
| 字段 | 原文含义 · 它替你回答什么 |
|---|---|
finereport_name | 场景到页面。哪个业务场景的哪个页面(帆软那边的叫法) |
finereport_widget | 场景控件。页面上的哪一块:一张图、一列表、还是一个筛选器 |
report_level | 指标 / 控件。这行说的是整块控件,还是控件里那一个数字 |
finereport_text | 对应指标。页面上那行文字的原文——截图给业务看时,他一眼认得出 |
dws_table | 相关 dws 表。这个指标的数从哪张汇总表取的 |
job_id | 调度任务 id。具体是哪一次实例(机器认编号) |
job_name | 调度任务名。这个任务叫什么(人认名字)——排查时先搜名字 |
status | 任务状态。这次跑到哪一步了:成功、失败、还是还在跑 |
abnormal_label | 异常问题类别。属于哪一类异常——就是上一节那些标签 |
error_message | 报错信息。具体报的什么错,比如心跳超时 |
hudi_schema | 源头 schema。源头落在哪个库 / schema |
hudi_table | 源头表名。源头是哪张表——顺着它才能找到入湖那一段 |
execute_time | 任务执行时间。什么时候跑的,用来分清"没更新"和"更新了但错" |
job_owner | 任务责任人。这行该喊谁。铃响给谁,就看这一列 |
从上往下读这张表,就是一条链:哪个页面 → 哪个控件 → 哪个指标 → 哪张汇总表 → 哪个任务 → 什么状态 → 报的什么错 → 源头哪张表 → 谁负责。这也是它敢叫"全链路"的原因——一行就把两头挂上了,中间不留空档。
一条告警摊开长这样
拿原文里那条真实的同步配置举例:湖里 dm_gk_hudi.ads_log_inv_kpi_wide 同步到仓里 dm_gk_dws.ads_log_inv_kpi_wide(原文那份配置是 SIT 环境,源端写的是 dm_gk_hudi_sit)。假设今天这次同步失败了,这一行会填成:
| 字段 | 这一行填什么 |
|---|---|
finereport_name | 用到这张表的那张帆软页面(页面名原文没给,实际值现场核) |
finereport_widget | 页面上对应的那个图表 / 数字块 |
report_level | 指标 |
finereport_text | 页面上那行指标文字的原文 |
dws_table | dm_gk_dws.ads_log_inv_kpi_wide |
job_id | 海豚里那条 SeaTunnel 同步节点的实例号(机器认它) |
job_name | 同一个节点的名字(人认它,排查时先搜名字) |
status | 失败 |
abnormal_label | failed |
error_message | OperationTimeoutException(Hazelcast operation-heartbeat-timeout) |
hudi_schema | 源头库 dm_gk_hudi |
hudi_table | 源头表 ads_log_inv_kpi_wide |
execute_time | 当天那次调度的时间 |
job_owner | 这个同步任务的责任人(实际值现场核) |
error_message 这一栏不是把"失败"复述一遍,是留真报错:原文里这一类失败根因就是 SeaTunnel 心跳超时。这类失败有个好处——重跑就好,所以兜底是两层的:DS 节点自己重试,下游再挂一个 retry_to_doris 补跑。
反过来看,如果 error_message 里只有"失败"两个字,这条告警基本等于没报——修的人还得从头查一遍。
五、三层仪表:集群、任务、数据,各看各的
看板不止一块。原文分三层,对应三种人操心的事:机器够不够、任务稳不稳、数对不对。混着看就会得出错误的结论。
| 层 | 挂什么表 · 具体看什么 |
|---|---|
| 集群侧 | Prometheus + Grafana。Doris 生产集群面板 http://10.160.4.111:8182/d/1fFiWJ4mz/doris-prod-cluster,看 BE / tablet 状态、查询延迟、导入失败 |
| 任务侧 | 海豚实例 + 失败率。近 8 天 45,571 成功 / 296 失败 / 529 被杀,失败率 0.65%;根因集中在 SeaTunnel 心跳超时,retry_to_doris 自动重跑后全部成功 |
| 数据侧 | 表维度监控 data_quality_monitor_table_dim、表字段维度监控 data_quality_monitor_field_dim、一致性检查自动调度。看源端 ↔ 贴源的行数差 rows_diff、字段类型差、入湖前后数值稳定性;湖 ↔ 仓的差异由一致性检查自动巡检 |
三层是个漏斗:集群侧亮绿灯只说明"有电有水",任务侧成功率高只说明"泵都在转",只有数据侧对得上,才敢说"龙头里的水是对的"。
0.65% 这个数要会读。它好看,是因为分母大。但它不回答"页面那个数是今天的还是上周的"——296 次失败的根因集中在 SeaTunnel 心跳超时,retry_to_doris 自动重跑后恢复,说明链路是稳的;可如果某张表压根没进监控,失败率再漂亮也照不到它。
数据侧还有一块容易被忘:表字段维度监控不只是比字段名。它把前一天和今天的均值、方差、最大最小值、空值比例都存下来,还检查日期字段的合法性(有没有未来日期、有没有公司成立以前的日期)。这类"数还在、但整体飘了"的问题,行数对比永远发现不了。
六、一个反常识:SUCCESS 只说明程序没报错
SUCCESS,意思是这段程序跑完了、退出码是 0。它不回答数对不对。三种情况全都能是绿的:源端新增了数据但增量时间字段没生效(source_add)——任务成功,新数据一行没进来;同一张表的日增脚本被放在两个已调度的作业里、又没设空跑——一天跑两遍;依赖检查只认"上次成功",上游 10-03 已经下线,08:00:05 照样放行,天天搬旧数据。最后这条是原文里的真实事故。所以要验数,不能只看状态,得三方对:
- 湖:
dm_gk_hudi里那张源表的行数、字段类型、数值分布——看两张监控表(表维度 + 字段维度)。 - 仓:
dm_gk_dws里同步过去的那张表,行数、总额、最大日期是不是跟湖里一致。 - 页面:帆软页面上那个控件的显示文字,跟仓里同一个口径算出来的数对一遍。
三方都对上,才叫"数对"。三方对不上时,这一页的用处才真正显出来:差在湖和仓之间 → 是 SeaTunnel 那段;差在仓和页面之间 → 是帆软取数或缓存那段;湖本身就比源端少 → 是入湖那段。不用拆整根管子,看差在哪个接口就够了。
SUCCESS 降级成一个中间信号:表是绿的,也要有三方对账的结果,才敢把这个数拿去开会。七、搞错了会怎样
四种坏法,按严重程度排。后两种不是假设,是原文记录里真发生过的事。
finereport_name 和 job_owner 不是装饰,是让铃响在对的人头上。八、一句话记住
回头看这四段:源到贴源挂化验单,入湖挂压力表,湖仓调度挂压力表,湖到仓到页面挂同步状态加血缘。四块表合起来只服务一句话——哪一段漏了、漏的是什么、谁来修。
所以别把监控当成"再买一块大屏"。大屏只解决"能看见";那 14 个字段的表解决的是"看得懂、找得到人"。这两件事差着一整条链路的维修时间。