4. 元数据模型设计

在 Elastic 数据质量与元数据治理体系中,元数据模型是整条治理链路的“骨架”。如果索引、字段、血缘、质量四类元数据各自为政,散落在不同系统、不同格式的文档里,那么后续的检索、影响分析、质量告警和审计都会变得极其脆弱。本节要解决的核心问题是:如何把这四类元数据放进一个统一、可关联、可扩展的存储结构中,并明确它们之间的关系。

一、四类元数据的职责边界

先明确每类元数据“管什么”,避免字段重复和职责混淆。

  • 索引元数据(Index Metadata):描述索引这一层对象的属性,例如索引名、别名、生命周期阶段、分片与副本数、文档量级、写入速率、所属业务域、负责人、创建时间、是否启用 ILM 等。它回答“这个索引是什么、归谁管、处于什么状态”。
  • 字段元数据(Field Metadata):描述索引内每个字段的结构与语义,例如字段名、数据类型(keyword、text、date、long、nested 等)、是否可聚合、是否分词、是否为主键或业务键、敏感级别、业务含义、示例值。它回答“这个字段代表什么、能不能这样用”。
  • 血缘元数据(Lineage Metadata):描述数据从哪来、经过哪些处理、流向哪里,例如上游数据源、采集管道、转换任务、目标索引、下游消费方。它回答“数据从哪来、改一处会影响谁”。
  • 质量元数据(Quality Metadata):描述数据质量规则与结果,例如规则类型(非空、唯一、范围、枚举、引用完整性)、校验字段、阈值、最近一次校验时间、通过率、异常样本数、告警状态。它回答“数据现在是否可信、哪里出了问题”。

这四类元数据不是并列孤岛,而是围绕“索引—字段”这一核心对象层层挂载:索引是容器,字段是容器内的具体列,血缘连接索引与外部世界,质量规则则绑定到具体字段或索引上。

二、统一存储结构:以实体为中心的关系模型

推荐采用“实体表 + 关系表”的图式结构,而不是把所有信息塞进一张宽表。核心实体包括:index_entity、field_entity、lineage_node、quality_rule。关系包括:索引包含字段、字段参与血缘、规则绑定字段或索引、血缘节点之间上下游连接。

在 Elastic 中落地时,可以建立独立的元数据索引,例如 meta-index-v1、meta-field-v1、meta-lineage-v1、meta-quality-v1,并通过统一 ID 规则建立关联。例如字段元数据文档 ID 采用 {index_name}::{field_name},质量规则文档中通过 target_index 和 target_field 指向对应实体。这样既能利用 Elastic 的检索能力,又能保持关系清晰。

统一元数据模型:实体与关系 索引为容器 · 字段为列 · 血缘连外部 · 质量绑字段 索引元数据 index_entity index_name · alias · ILM阶段 分片数 · 文档量 · 负责人 业务域 · 创建时间 字段元数据 field_entity field_name · data_type 可聚合 · 分词 · 敏感级别 业务含义 · 示例值 血缘元数据 lineage_node 上游数据源 · 采集管道 转换任务 · 目标索引 下游消费方 · 方向 质量元数据 quality_rule 规则类型 · 校验字段 阈值 · 通过率 · 异常数 最近校验时间 · 告警状态 包含 参与 绑定 索引级规则 上下游链路 统一关联键 字段ID: {index}::{field} 规则通过 target_index + target_field 定位 关系语义 索引 → 字段(包含) 字段 → 血缘(参与) 字段/索引 → 质量(绑定)

三、关键字段设计与示例

下面给出一份可直接参考的字段设计示例。以电商订单索引 ods_order_2024 为例,其字段 order_id 的元数据文档可以这样组织:

{
  "doc_id": "ods_order_2024::order_id",
  "index_name": "ods_order_2024",
  "field_name": "order_id",
  "data_type": "keyword",
  "is_aggregatable": true,
  "is_analyzed": false,
  "is_business_key": true,
  "sensitivity": "internal",
  "business_desc": "订单唯一标识,全局唯一",
  "sample_values": ["SO20240115001", "SO20240115002"],
  "lineage_upstream": ["mysql.order.order_id"],
  "lineage_downstream": ["dws_order_summary.order_id"],
  "quality_rules": [
    {"rule_id": "QR-001", "type": "not_null", "threshold": 1.0},
    {"rule_id": "QR-002", "type": "unique", "threshold": 1.0}
  ]
}

这个文档把字段自身的结构信息、血缘上下游、质量规则 ID 都聚合在一起,查询时一次命中即可获得完整上下文。质量规则的具体执行结果则单独存放在 meta-quality-v1 中,通过 rule_id 关联,避免每次校验都更新字段主文档。

四、关系约束与一致性维护

统一模型最大的风险是“关系漂移”:索引删了,字段元数据还在;字段改名了,质量规则还指向旧名。建议在写入侧做三件事:

  1. 级联标记:索引下线时,将其下所有字段元数据标记为 status: deprecated,而不是物理删除,保留审计痕迹。
  2. 引用完整性校验:质量规则写入前,先校验 target_index 和 target_field 是否存在于字段元数据中,不存在则拒绝或进入待确认队列。
  3. 变更事件驱动:当字段类型或名称发生变更时,通过变更事件触发血缘和质量规则的重新绑定,并记录变更前后快照。
建议为每类元数据设置独立的 updated_at 和 version 字段,便于做增量同步和冲突检测。字段元数据可采用“主文档 + 质量结果子文档”的分离模式,主文档更新频率低,质量结果写入频率高,分离后写入压力更可控。

五、查询与影响分析示例

模型建好后,最有价值的应用是影响分析。例如要回答“如果 order_id 字段类型从 keyword 改为 text,会影响哪些下游和质量规则”,可以用一次组合查询完成:先按 field_name=order_id 找到字段文档,取出 lineage_downstream 和 quality_rules,再分别到血缘索引和质量索引中展开详情。整个过程不需要跨系统拼接,全部在 Elastic 内完成。

另一个典型场景是质量巡检:按 index_name 聚合所有绑定规则,统计通过率低于 0.95 的字段,并按业务域分组输出。由于质量元数据中保留了 target_field,可以直接定位到具体列,而不是只停留在索引级别。

不要把质量规则的定义和每次校验结果混在同一文档中。定义是低频变更的“配置”,结果是高频追加的“事实”,混在一起会导致文档频繁更新、版本冲突,也会让历史趋势分析变得困难。

总结来看,统一元数据模型的关键不在于字段多全,而在于关系是否明确、关联键是否稳定、写入路径是否可控。索引、字段、血缘、质量四类元数据各司其职,通过 {index}::{field} 和 rule_id 等稳定键连接,才能支撑后续的检索、影响分析、质量告警与审计追溯。