OpenMetadata Omni 连接器完全指南:配置、模型/仪表盘接入与血缘构建
【免费下载链接】OpenMetadataThe Open Context Layer for Data and AI , OpenMetadata is the open platform for building trusted data context and business semantics for humans, AI assistants, and agents.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMetadata
导读
本文基于 OpenMetadata 仓库中 Omni 连接器的官方配置文档,系统讲解如何将 Omni(面向 AI 时代的语义层/BI 平台)接入 OpenMetadata 元数据体系:包括连接配置的四个核心参数(Host Port、API Token、Verify SSL、SSL Config)、完整可运行的工作流 YAML,以及连接器底层是如何把 Omni 的模型(Model)/主题(Topic)转化为数据模型(Data Model)、把文档(Document/Workbook)转化为仪表盘与图表,并打通"数据仓库表 → 主题 → 仪表盘"的端到端血缘。读完本文,你将能够独立在 OpenMetadata 中创建 Omni 服务、完成连接测试、执行元数据摄取,并理解其源码级工作原理与常见故障排查方法。
一、连接器概览:它能摄取什么
根据 Omni 连接器的官方文档定义,该连接器通过Omni 的 REST API工作,核心摄取能力分为三块:
- 数据模型(Data Model):Omni 的模型(Model)及其内部的主题(Topic)会被摄取为 OpenMetadata 的 Dashboard Data Model 实体;
- 仪表盘与图表(Dashboard & Chart):Omni 的文档(Document)(即 Workbooks/仪表盘)会被摄取为 Dashboard 实体,文档中的Tile(磁贴)则对应为图表(Chart);
- 血缘(Lineage):连接器会构建从数据仓库中的物理表 → 主题(Topic)→ 仪表盘(Dashboard)的完整血缘链路。
这一能力在源码中得到了直接印证。连接器的服务规范 service_spec.py 将元数据源类与连接类注册到 OpenMetadata 的 Source 体系:
ServiceSpec = BaseSpec(metadata_source_class=OmniSource, connection_class=OmniConnection)而主处理类OmniSource(见 metadata.py)的模块文档明确写道:
ingests models/topics as data models, documents as dashboards with charts, and builds lineage from warehouse tables through topics to dashboards.
此外,连接器的 JSON Schema 描述也确认了定位:"Omni BI connector: models, topics, workbooks/dashboards and lineage"(见 omniConnection.json)。
二、前置要求(Requirements)
在开始配置之前,需要确认以下前提条件:
| 前提 | 说明 |
|---|---|
| Omni REST API 可用 | OpenMetadata 完全依赖 Omni 的 REST API 进行数据摄取,官方要求参考 Omni 的 API 文档理解接口语义 |
| 认证凭据 | 需要Organization API Key(由组织管理员创建)或Personal Access Token(PAT),且该凭据必须拥有访问你的模型(models)和文档(documents)的权限 |
| 网络可达性 | OpenMetadata 摄取服务所在环境必须能够访问 Omni 实例的 API 域名 |
| 速率限制意识 | Omni API 默认速率限制为60 次请求/分钟(源码注释确认,见 connection.py),大规模摄取时应关注是否会触发 429 限流 |
值得强调的是,从源码实现看,连接器对 API 的调用做了充分的速率控制设计:
- 分页请求使用游标(cursor)分页,每页默认
PAGE_SIZE = 100(见 client.py); - 主题解析采用一次
/models/{id}/yaml调用返回模型内全部视图与主题的策略,避免逐主题请求打满限额(见 client.py 的注释"One/models/{id}/yamlcall returns every view + topic for the model, which keeps us well within the API rate limit"); - 连接测试(Test Connection)的每个步骤超时预算放宽至3 分钟(
step_timeout_seconds = THREE_MIN,见 connection.py),避免限流导致测试误报失败。
三、连接配置详解(Connection Details)
Omni 服务的连接配置由四个参数组成。在 OpenMetadata UI 中创建 Dashboard 服务并选择 Omni 类型后,即可看到这些字段;它们与 omniConnection.json 中定义的hostPort、token、verifySSL、sslConfig一一对应。
3.1 Host Port(主机与端口)
参数 ID:hostPort
这是 Omni 实例 API 的基础 URL,格式为:
https://<your-org>.omniapp.co/api即你的 Omni 登录 URL 末尾追加/api得到。例如组织域名为acme.omniapp.co,则填写https://acme.omniapp.co/api。
源码层的容错处理值得注意:在 client.py 中,OmniApiClient构建时会先对用户输入做归一化——去除尾部多余斜杠、剥离可能误填的/api或/api/v<N>后缀,然后统一追加/api:
base_url = clean_uri(str(config.hostPort)).rstrip("/") base_url = re.sub(r"/api(/v\d+)?$", "", base_url) base_url = f"{base_url}/api"也就是说,无论用户填https://acme.omniapp.co、https://acme.omniapp.co/还是https://acme.omniapp.co/api,最终都会以正确的 API 根路径发起请求,API 版本(v1)由 REST 客户端单独拼接。Schema 中该字段的默认值为https://your-org.omniapp.co,说明/api会被自动追加,但官方文档仍推荐按完整格式填写以避免歧义。
3.2 API Token(API 令牌)
参数 ID:token
用于向 Omni 进行身份认证的 API 令牌。它会被放入 HTTP 请求的Authorization头,以Bearer令牌形式发送(见 client.py,auth_token_mode="Bearer")。
可用的令牌类型有两种:
- Organization API Key——由组织管理员创建,粒度覆盖整个组织的模型与文档;
- Personal Access Token(PAT)——个人级访问令牌。
认证细节可参考 Omni 官方认证文档。需要特别强调的是,令牌必须拥有读取模型与文档的权限,否则连接测试阶段就会被拒绝(403)。在 Schema 中该字段类型为format: "password",属于敏感字段,OpenMetadata 会以密文方式存储与展示(见 omniConnection.json)。
3.3 Verify SSL(SSL 校验开关)
参数 ID:verifySSL
客户端 SSL 校验开关。该字段引用公共的 SSL 校验配置,可选值在 verifySSLConfig.json 中定义,共三档:
| 取值 | 含义 | 连接器行为 |
|---|---|---|
no-ssl(默认) | 不额外做自定义校验 | 使用系统默认 CA 证书链(verify_ssl = None) |
ignore | 忽略证书校验 | 禁用校验(verify = False),适用于自签名证书 |
validate | 严格校验 | 使用sslConfig中提供的 CA 证书进行校验 |
官方文档特别提示:启用该校验选项时,务必同时配置 SSL Config(见下节)。源码中校验逻辑的处理非常清晰(见 connection.py):
verify_ssl = None if connection.verifySSL: verify_ssl = get_verify_ssl_fn(connection.verifySSL)(connection.sslConfig) # `validate` returns the raw CA certificate *content*, but requests # treats a string ``verify`` value as a path to a CA bundle. Write the # certificate to a temp file (kept for the session) and pass its path. if isinstance(verify_ssl, str) and connection.sslConfig: verify_ssl = SSLManager(ca=connection.sslConfig.root.caCertificate).ca_file_path这里有一个值得开发者了解的底层细节:requests库的verify参数若为字符串,会被当作CA 证书文件的路径而非证书内容。因此当校验模式为validate时,连接器会通过SSLManager把用户提供的 CA 证书内容写入临时文件,再把临时文件路径传给 HTTP 客户端,从而保证自建 CA 的 Omni 实例可以正常完成 TLS 握手。
3.4 SSL Config(SSL 配置)
参数 ID:sslConfig
客户端 SSL 配置。当你的 Omni 实例部署在内部证书颁发机构(internal CA)之后时,在此处提供 CA 证书(caCertificate)即可。该配置与verifySSL: validate配合使用;如果设置为ignore,则无需提供证书。
从错误诊断逻辑(见 connection.py)可以看出 TLS 场景的推荐做法:
TLS verification failed —— 服务器证书校验失败。请在SSL Config中提供 CA 证书并将Verify SSL设为
validate;若是自签名证书,可临时将Verify SSL设为ignore。
四、完整配置示例:可直接运行的摄取工作流
仓库为 Omni 连接器提供了完整的 YAML 工作流示例(见 omni.yaml),可以直接作为本地运行(metadata ingest -c omni.yaml)或 Airflow DAG 配置的蓝本:
source: type: omni serviceName: local_omni serviceConnection: config: type: Omni hostPort: https://your-org.omniapp.co/api token: api_token sourceConfig: config: type: DashboardMetadata # 针对这些数据库服务解析仓库表血缘 # (prefix = serviceName[.database[.schema[.table]]]). lineageInformation: dbServicePrefixes: [db_service_name] sink: type: metadata-rest config: {} workflowConfig: loggerLevel: DEBUG # DEBUG, INFO, WARN or ERROR openMetadataServerConfig: hostPort: http://localhost:8585/api authProvider: openmetadata securityConfig: jwtToken: "eyJraWQ****..."要点解析:
source.type: omni:声明源类型为 Omni;serviceConnection.config:与上文四个连接参数一一对应,type: Omni必须保留;sourceConfig.config.type: DashboardMetadata:声明这是仪表盘元数据摄取;lineageInformation.dbServicePrefixes:血缘解析的关键配置。它声明了应当参与血缘解析的数据仓库服务前缀列表。前缀格式为serviceName[.database[.schema[.table]]]——例如你的表存在于数据库服务mysql_prod的analytics库、publicschema 下,则应配置dbServicePrefixes: ["mysql_prod.analytics.public"]。血缘解析时,连接器会用该前缀限定搜索范围,将 Omni 主题的base_schema/base_table匹配到具体的仓库表实体(具体逻辑见下文血缘章节);sink:写入 OpenMetadata 服务端;workflowConfig:OpenMetadata 服务端地址与认证信息(生产环境推荐使用 JWT Token 或 Basic Auth)。
连接器还支持在服务连接级别配置四类过滤模式(定义于 omniConnection.json):
| 过滤参数 | 作用对象 | 说明 |
|---|---|---|
dashboardFilterPattern | 仪表盘 | 正则 include/exclude 哪些文档(dashboard) |
chartFilterPattern | 图表 | 正则 include/exclude 哪些 tile(chart) |
dataModelFilterPattern | 数据模型 | 正则 include/exclude 哪些 Omni 主题(topic) |
projectFilterPattern | 项目/文件夹 | 正则 include/exclude 哪些 Omni 文件夹(folder) |
其中dataModelFilterPattern的过滤发生在摄取早期:OmniSource.prepare()会一次性拉取全部模型与主题,并在该阶段按数据模型名统一过滤,保证后续"批量数据模型、血缘索引、血缘输出"各环节的过滤结果一致(见 metadata.py)。
五、源码实现剖析:一次 Omni 摄取的完整链路
理解了配置后,我们顺着源码追踪一次典型摄取的执行路径。Omni 连接器代码全部位于 ingestion/src/metadata/ingestion/source/dashboard/omni/ 目录,共 5 个模块,职责划分清晰:
| 模块 | 职责 |
|---|---|
| service_spec.py | 服务规范注册(元数据源类 + 连接类) |
| connection.py | 连接建立、SSL 处理、连接测试检查项 |
| client.py | 底层 REST 客户端:认证、分页、API 调用封装 |
| models.py | API 响应模型与归一化领域模型(Topic/Field) |
| metadata.py | 主摄取逻辑:数据模型、仪表盘、图表、血缘产出 |
5.1 模型与主题 → 数据模型
流程的第一步是OmniSource.prepare()(见 metadata.py):
- 调用
client.get_models()拉取实例内所有模型(modelKind为SHARED的语义模型才会保留); - 对每个模型调用
client.get_model_topics(model),通过GET /models/{id}/yaml?fullyResolved=true一次性获取该模型的完整 YAML 定义; - 解析 YAML 中的每个
.view文件与.topic文件,得到归一化的OmniTopic列表。
YAML 解析逻辑在 client.py 的_parse_model_yaml中实现,其语义映射为:
- 每个
.view文件→ 一个基于物理仓库表的数据模型(提取schema、table_name、字段); - 每个
.topic文件→ 一个策展(curated)数据模型,它引用某个基础视图(base view),用于后续的仓库表血缘解析; - 主题中的dimensions/measures字段被提取为
OmniField,其中类型名(type/data_type)与描述(description)被保留。
在 metadata.py 中,Omni 字段类型会被映射为 OpenMetadata 标准列类型:
OMNI_DATATYPE_MAP = { "string": DataType.STRING, "number": DataType.DOUBLE, "integer": DataType.INT, "int": DataType.INT, "float": DataType.FLOAT, "double": DataType.DOUBLE, "boolean": DataType.BOOLEAN, "date": DataType.DATE, "datetime": DataType.DATETIME, "timestamp": DataType.TIMESTAMP, }未识别的类型会被标记为DataType.UNKNOWN,而字段名通过truncate_column_name处理以保证长度合规(见 metadata.py)。
数据模型命名采用模型名.主题名(如my_model.orders_topic)的形式(见_datamodel_name,metadata.py),从而避免不同模型中同名视图/主题在 FQN 上的冲突。同时,每个数据模型会打上dataModelType: OmniDataModel与所属模型名(project)标记(见 metadata.py)。
5.2 文档 → 仪表盘与图表
仪表盘摄取链路为:
get_documents()调用GET /documents?include=labels拉取全部文档,游标分页;get_dashboards_list()过滤出hasDashboard == true且未删除(deleted != true)的文档,并应用仪表盘过滤模式(见 metadata.py);get_dashboard_document(document_id)调用GET /documents/{id}/queries获取该文档的 tiles:每个 query 对应一个 tile(图表),query 对象中的table与fields字段用于后续血缘解析(见 client.py);- 图表的展示名取 tile 的
name,缺失时回退为Tile {idx};图表类型通过get_standard_chart_type映射为 OpenMetadata 标准图表类型(见 metadata.py)。
一个重要的容错细节:当文档的 tiles 无法获取时(例如旧版 Omni Workbooks 返回400 "Workbook needs to be migrated"),连接器依然会创建该仪表盘,只是不带图表,而不是整体丢弃(见 client.py 注释"the dashboard is created without charts rather than being dropped entirely")。
仪表盘的Project 概念映射为 Omni 文件夹(folder.path或folder.name)。对于不在任何文件夹中的文档,返回默认项目名"default",以规避基类在配置了 projectFilterPattern 时因 project 为空而静默丢弃无文件夹仪表盘的问题(见 [metadata.py](https://link.gitcode.com/i/26d82821bca07a0a187dcb36397bc846#L75-L77, L328-L339))。
5.3 血缘构建:仓库表 → 主题 → 仪表盘
血缘是 Omni 连接器最有价值的能力,其实现分为两个阶段:
阶段一:仓库表 → 数据模型(在批量数据模型阶段完成)
_yield_bulk_datamodel_lineage()(见 metadata.py)在所有数据模型写入之后统一触发:对每个配置了dbServicePrefixes的数据库服务(未配置则全局搜索),把每个解析到物理表的主题,产出Table → DashboardDataModel的血缘边。
表实体的解析通过build_es_fqn_search_string构造搜索串,并调用metadata.search_in_any_service在任意数据库服务中检索(见 metadata.py)。db_service_prefix会被解析为serviceName[.database[.schema[.table]]]四段,逐级限定搜索范围;主题的base_schema/base_table作为兜底参与匹配。
阶段二:数据模型 → 仪表盘(在仪表盘处理阶段完成)
yield_dashboard_lineage_details()(见 metadata.py)对每个仪表盘的每个 tile:读取 tile query 的table引用 → 通过_resolve_topic在主题索引中解析出对应的数据模型 → 产出DashboardDataModel → Dashboard的血缘边。
主题引用解析(_resolve_topic)有几个精心设计的细节(见 metadata.py):
- Omni 中引用限定符可能是
.、/或__,解析时会先归一化为.形式; - 索引同时包含裸名称与 schema 限定名称(
schema.name),使限定引用能命中正确的主题; - 刻意不做"剥离限定符到裸叶名"的降级匹配——如果限定引用无法精确命中,宁可放弃该血缘,也不允许血缘误连到其他模型的同名主题上(源码注释:
we deliberately do NOT strip a qualifier down to its bare leaf: that could match an unrelated topic and misroute lineage); - 跨模型出现同名冲突时,打印告警并跳过该血缘,杜绝静默错连。
两阶段设计保证了:即使某个数据模型没有任何仪表盘使用,其到仓库表的血缘依然会被完整记录(阶段一独立于仪表盘执行)。
5.4 所有者解析
当sourceConfig开启includeOwners时,文档的 owner 会通过邮箱关联到 OpenMetadata 用户(get_reference_by_email,见 metadata.py),实现 Omni 文档所有者在元数据平台的自动归属。
六、连接测试(Test Connection)与常见错误排查
连接测试是配置完成后验证连通性的第一道关卡。Omni 的测试逻辑定义在 connection.py,包含两个检查步骤:
| 步骤 | 底层调用 | 验证内容 |
|---|---|---|
| CheckAccess | GET /models(pageSize=1) | 认证是否通过、主机是否可达 |
| GetDashboards | GET /documents(pageSize=1) | 文档列表是否可读 |
其中CheckAccess是入口闸门:令牌无效或主机不可达会在此步骤直接失败并终止,GetDashboards不会继续执行。
连接器针对 Omni 常见故障提供了精准的诊断与修复建议(见 connection.py 的OMNI_ERRORS):
| HTTP 状态/异常 | 诊断 | 修复建议 |
|---|---|---|
| 401 | 认证失败 | 检查令牌值是否有效、是否被吊销;确认 Host Port 指向正确的组织域名(https://<org>.omniapp.co) |
| 403 | 权限不足 | 令牌有效但未被授权;使用能够读取模型和文档的组织级 API Key |
| 429 | 触发速率限制 | Omni 默认限流 60 请求/分钟;等待后重试,或联系 Omni 提升 API Key 限额 |
| SSLError | TLS 校验失败 | 在 SSL Config 中提供 CA 证书并将 Verify SSL 设为validate;自签名证书可设ignore |
| 网络类错误 | 主机不可达/超时 | 检查网络连通性与防火墙规则(NETWORK_ERRORS统一纳入诊断) |
连接器对 429/5xx 响应还配置了自动重试:REST 客户端的retry_codes=[429, 500, 502, 503](见 client.py),配合 3 分钟的单步超时预算,最大限度避免限流导致摄取任务抖动。
七、测试用例与验证方式
仓库为 Omni 连接器提供了完整的单元测试(见 test_omni.py,共 440 行),覆盖了摄取链路的核心环节,可以作为理解连接器行为的补充读物:
- 数据模型(
CreateDashboardDataModelRequest)的产出与批量血缘(Barrier哨兵机制); - 仪表盘(
CreateDashboardRequest)与图表(CreateChartRequest)的产出; - 表 → 数据模型、数据模型 → 仪表盘的两类血缘(
AddLineageRequest)解析; - 测试用配置与 omni.yaml 结构一致,包含
includeDataModels、includeOwners等开关。
本地验证的推荐路径:
- 在 OpenMetadata UI 中新建 Dashboard 服务,选择Omni类型,按第三节配置四个连接参数;
- 点击Test Connection,确认两个检查步骤全部通过(可结合第六节的错误对照表排查);
- 配置摄取管线(Ingestion Pipeline),选择 DashboardMetadata 类型,设置过滤模式与
lineageInformation.dbServicePrefixes; - 运行后前往数据资产页检查:Omni 数据模型(含列与类型映射)、仪表盘与图表、以及"仓库表 → 数据模型 → 仪表盘"的血缘视图。
八、总结
Omni 连接器是 OpenMetadata 接入现代语义层平台的一站式方案:通过 omniConnection.json 定义的最小连接配置(Host Port + API Token),辅以 SSL 校验与四类过滤模式,即可将 Omni 的模型、主题、文档、图表完整纳入统一元数据体系,并借助dbServicePrefixes构建贯通"物理表 → 语义主题 → 仪表盘"的端到端血缘。其源码在 ingestion/src/metadata/ingestion/source/dashboard/omni/ 目录中保持了清晰的职责分层,且在 API 速率限制、TLS 证书处理、同名冲突防护、无仪表盘场景的血缘完整性等方面都做了工程化考量,值得在实际部署前通读以理解其行为边界。
【免费下载链接】OpenMetadataThe Open Context Layer for Data and AI , OpenMetadata is the open platform for building trusted data context and business semantics for humans, AI assistants, and agents.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMetadata
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考