DataHub元数据摄取完全指南:Push与Pull模式详解
【免费下载链接】datahub 项目地址: https://gitcode.com/gh_mirrors/datahub/datahub
本文全面解析DataHub的元数据摄取机制,详细对比Push与Pull两种集成模式。文章首先介绍DataHub提供的三种元数据摄取方法(UI摄取、CLI摄取和SDK编程式摄取),通过对比表格分析各方法的易用性、灵活性、自动化能力和适用场景。然后深入探讨Push-based集成模式,包括Airflow、Spark等实时推送机制,以及Pull-based集成模式的批量爬取能力。最后详细解析Sources、Sinks、Recipe三大核心概念,为构建高效的元数据管道提供完整指南。
DataHub元数据摄取三种方法对比
DataHub提供了三种主要的元数据摄取方法:UI摄取、CLI摄取和SDK编程式摄取。每种方法都有其独特的优势和适用场景,理解它们的区别对于构建高效的元数据管理流程至关重要。
方法概览对比
下表展示了三种摄取方法的核心特征对比:
| 特性维度 | UI摄取 | CLI摄取 | SDK编程式摄取 |
|---|---|---|---|
| 易用性 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| 灵活性 | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 自动化能力 | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 实时性 | 批量 | 批量 | 实时/批量 |
| 部署复杂度 | 低 | 中 | 高 |
| 适用场景 | 快速开始、简单集成 | 生产环境、定期批量 | 自定义逻辑、实时推送 |
UI摄取:可视化配置与管理
UI摄取方法通过DataHub的Web界面提供直观的配置体验,特别适合快速入门和简单集成场景。
核心优势:
- 零代码配置:无需编写任何代码即可完成摄取配置
- 可视化监控:实时查看摄取执行状态和日志
- 安全管理:内置密钥管理功能,支持敏感信息加密存储
- 计划调度:支持CRON表达式配置定期执行计划
典型配置示例:
# MySQL到DataHub的UI摄取配置
source:
type: mysql
config:
host_port: localhost:3306
database: my_database
username: ${MYSQL_USERNAME}
password: ${MYSQL_PASSWORD}
sink:
type: datahub-rest
config:
server: http://localhost:8080
CLI摄取:命令行批量处理
CLI摄取基于YAML配方文件和命令行工具,提供更强的灵活性和自动化能力。
核心特性:
- 配方文件驱动:使用YAML文件定义完整的摄取逻辑
- 环境变量支持:支持${ENV_VAR}语法注入环境变量
- 插件架构:按需安装特定数据源插件
- 集成调度:可与Airflow、CRON等调度系统集成
典型工作流程:
- 安装DataHub CLI:
pip install acryl-datahub - 安装所需插件:
pip install 'acryl-datahub[mysql]' - 创建配方文件:定义source和sink配置
- 执行摄取:
datahub ingest -c recipe.yaml
SDK编程式摄取:完全自定义控制
SDK编程式摄取提供最高级别的灵活性,允许开发者以编程方式构建和发送元数据事件。
核心能力:
- 实时事件推送:支持毫秒级延迟的元数据更新
- 自定义逻辑:可在业务逻辑中嵌入元数据发射
- 多协议支持:支持REST和Kafka两种发射方式
- 细粒度控制:精确控制每个元数据事件的生成和发送
Python SDK示例:
from datahub.emitter.rest_emitter import DatahubRestEmitter
from datahub.emitter.mce_builder import make_dataset_urn
from datahub.metadata.schema_classes import DatasetPropertiesClass
# 创建REST发射器
emitter = DatahubRestEmitter(gms_server="http://localhost:8080")
# 构建数据集属性
properties = DatasetPropertiesClass(
description="用户配置文件表",
customProperties={"governance": "ENABLED"}
)
# 发射元数据事件
emitter.emit(metadata_event)
技术架构对比
从技术架构角度,三种方法在数据处理流程上存在显著差异:
选择指南
根据不同的业务需求和技术环境,选择合适的摄取方法:
选择UI摄取当:
- 需要快速验证概念或演示
- 团队缺乏编程经验但需要元数据管理
- 只需要简单的定期批量摄取
选择CLI摄取当:
- 需要与现有CI/CD流水线集成
- 要求灵活的调度和自动化
- 需要在多个环境中保持配置一致性
选择SDK摄取当:
- 需要实时元数据更新
- 有复杂的业务逻辑需要嵌入元数据发射
- 需要高度自定义的元数据处理流程
性能与扩展性考虑
每种方法在性能和扩展性方面都有不同的特点:
| 性能指标 | UI摄取 | CLI摄取 | SDK摄取 |
|---|---|---|---|
| 吞吐量 | 中等 | 高 | 极高 |
| 延迟 | 分钟级 | 分钟级 | 毫秒级 |
| 资源消耗 | 中等 | 低 | 可变 |
| 扩展性 | 有限 | 良好 | 优秀 |
在实际部署中,通常建议采用混合策略:使用UI摄取进行快速原型验证,CLI摄取处理定期批量任务,SDK摄取处理实时性要求高的场景。
Push-based集成:Airflow、Spark等实时推送
DataHub的Push-based集成模式为现代数据栈提供了实时元数据同步能力,让Airflow、Spark等数据处理框架能够主动将元数据推送到DataHub平台。这种模式特别适合需要实时反映数据处理状态和血缘关系的场景。
DataHub REST Emitter核心机制
DataHub提供了强大的REST Emitter作为Push模式的核心组件,支持通过HTTP协议将元数据实时推送到DataHub GMS服务。
REST Emitter核心类结构
class DataHubRestEmitter(Closeable, Emitter):
def __init__(
self,
gms_server: str,
token: Optional[str] = None,
timeout_sec: Optional[float] = None,
connect_timeout_sec: Optional[float] = None,
read_timeout_sec: Optional[float] = None,
retry_status_codes: Optional[List[int]] = None,
retry_methods: Optional[List[str]] = None,
retry_max_times: Optional[int] = None,
extra_headers: Optional[Dict[str, str]] = None,
ca_certificate_path: Optional[str] = None,
client_certificate_path: Optional[str] = None,
disable_ssl_verification: bool = False,
):
# 初始化配置
self._gms_server = fixup_gms_url(gms_server)
self._token = token
self._session = requests.Session()
# 设置HTTP头
self._session.headers.update({
"X-RestLi-Protocol-Version": "2.0.0",
"Content-Type": "application/json",
})
# 认证配置
if token:
self._session.headers.update({"Authorization": f"Bearer {token}"})
元数据推送流程
Airflow集成深度解析
DataHub为Airflow提供了完整的插件支持,通过DataHub Airflow Plugin实现任务执行元数据的自动采集和推送。
Airflow插件架构
关键配置参数
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| datahub_conn_id | string | datahub_rest | DataHub连接ID |
| gms_host | string | http://localhost:8080 | GMS服务地址 |
| token | string | None | 认证令牌 |
| timeout_sec | int | 30 | 连接超时时间 |
| extra_headers | dict | {} | 额外HTTP头 |
Spark应用集成模式
Spark应用可以通过DataHub的Python SDK实现元数据的实时推送,特别适合ETL作业的血缘追踪。
Spark元数据推送示例
from datahub.emitter.rest_emitter import DataHubRestEmitter
from datahub.metadata.schema_classes import (
DatasetSnapshotClass,
MetadataChangeEventClass,
DatasetPropertiesClass
)
# 初始化Emitter
emitter = DataHubRestEmitter(
gms_server="http://datahub-gms:8080",
token="your-token"
)
def push_spark_metadata(dataframe, job_name, output_dataset):
"""推送Spark作业元数据到DataHub"""
# 构建数据集快照
dataset_snapshot = DatasetSnapshotClass(
urn=f"urn:li:dataset:(urn:li:dataPlatform:spark,{output_dataset},PROD)",
aspects=[]
)
# 添加数据集属性
properties = DatasetPropertiesClass(
name=output_dataset,
description=f"Generated by Spark job: {job_name}",
customProperties={
"spark_job_name": job_name,
"row_count": str(dataframe.count()),
"column_count": str(len(dataframe.columns))
}
)
dataset_snapshot.aspects.append(properties)
# 创建元数据变更事件
mce = MetadataChangeEventClass(proposedSnapshot=dataset_snapshot)
# 推送元数据
emitter.emit(mce)
Spark血缘关系追踪
实时推送最佳实践
1. 批量处理优化
from datahub.emitter.rest_emitter import DataHubRestEmitter
from datahub.emitter.mcp import MetadataChangeProposalWrapper
class BatchEmitter:
def __init__(self, emitter: DataHubRestEmitter, batch_size: int = 100):
self.emitter = emitter
self.batch_size = batch_size
self.batch: List[MetadataChangeProposalWrapper] = []
def add_to_batch(self, mcp: MetadataChangeProposalWrapper):
self.batch.append(mcp)
if len(self.batch) >= self.batch_size:
self.flush()
def flush(self):
if self.batch:
self.emitter.emit_mcps(self.batch)
self.batch.clear()
2. 错误处理和重试机制
def safe_emit(emitter, item, max_retries=3):
"""带重试机制的元数据推送"""
for attempt in range(max_retries):
try:
emitter.emit(item)
return True
except Exception as e:
if attempt == max_retries - 1:
logger.error(f"Failed to emit after {max_retries} attempts: {e}")
return False
time.sleep(2 ** attempt) # 指数退避
return False
3. 性能监控指标
| 指标名称 | 类型 | 描述 |
|---|---|---|
| emit_success_count | Counter | 成功推送次数 |
| emit_failure_count | Counter | 推送失败次数 |
| emit_duration_ms | Histogram | 推送耗时分布 |
| batch_size | Gauge | 当前批次大小 |
集成部署架构
Push-based集成模式为DataHub提供了强大的实时元数据管理能力,通过标准化的REST API和丰富的客户端SDK,使得各种数据处理框架都能轻松集成到DataHub的元数据生态系统中。这种模式特别适合需要实时数据血缘追踪、作业状态监控和元数据一致性保证的生产环境。
Pull-based集成:批量爬取各类数据源
在DataHub的元数据摄取体系中,Pull-based集成是构建完整数据目录的核心机制。这种集成方式通过主动连接到各类数据系统,以批处理或增量批处理的方式提取元数据,为组织提供全面、准确的数据资产视图。
Pull-based集成架构解析
Pull-based集成遵循标准化的架构模式,主要由以下组件构成:
核心组件详解
连接器配置(Connector Configuration) 每个数据源连接器都有特定的配置参数,通过YAML格式定义:
source:
type: snowflake
config:
host: company.snowflakecomputing.com
username: datahub_user
password: ${SNOWFLAKE_PASSWORD}
warehouse: analytics_wh
role: datahub_role
include_technical_schema: true
profiling:
enabled: true
max_workers: 10
元数据提取模式 DataHub支持多种元数据提取策略:
| 提取模式 | 描述 | 适用场景 |
|---|---|---|
| 全量提取 | 每次运行都提取所有元数据 | 初始同步、定期重建 |
| 增量提取 | 只提取自上次运行以来的变更 | 日常同步、频繁更新 |
| 基于时间戳 | 根据最后修改时间筛选 | 时间敏感型数据源 |
| 基于状态 | 维护提取状态和检查点 | 大规模数据源 |
主流数据源集成实现
数据库类数据源
Snowflake集成示例
from datahub.ingestion.source.snowflake.snowflake import SnowflakeSource
from datahub.ingestion.source.snowflake.config import SnowflakeConfig
config = SnowflakeConfig(
host="company.snowflakecomputing.com",
username="datahub_user",
password=os.getenv("SNOWFLAKE_PASSWORD"),
warehouse="analytics_wh",
include_technical_schema=True,
profiling=GEProfilingConfig(enabled=True, max_workers=5)
)
source = SnowflakeSource(config=config, ctx=PipelineContext(run_id="snowflake-run-001"))
workunits = source.get_workunits()
BigQuery集成特性 BigQuery V2连接器提供高级功能:
source:
type: bigquery-v2
config:
project_id: my-gcp-project
credential:
project_id: my-gcp-project
private_key: ${BIGQUERY_PRIVATE_KEY}
client_email: datahub@my-gcp-project.iam.gserviceaccount.com
include_table_lineage: true
include_usage_statistics: true
usage:
start_time: 2024-01-01T00:00:00Z
end_time: 2024-01-31T23:59:59Z
商业智能工具集成
Tableau元数据提取 Tableau连接器能够提取工作簿、数据源、仪表板等完整元数据:
Looker集成配置
source:
type: looker
config:
base_url: https://company.looker.com
client_id: ${LOOKER_CLIENT_ID}
client_secret: ${LOOKER_CLIENT_SECRET}
include_deleted: false
extract_column_level_lineage: true
max_file_snippet_length: 100000
文件系统与数据湖集成
S3数据湖元数据提取
source:
type: s3
config:
aws_config:
aws_access_key_id: ${AWS_ACCESS_KEY_ID}
aws_secret_access_key: ${AWS_SECRET_ACCESS_KEY}
aws_region: us-west-2
path_specs:
- include: "s3://data-lake/raw/**/*.parquet"
exclude: "s3://data-lake/raw/temp/**"
- include: "s3://data-lake/processed/**/*.csv"
profiling:
enabled: true
sample_size: 10000
Delta Lake集成 Delta Lake连接器支持ACID事务元数据提取:
from datahub.ingestion.source.delta_lake.delta_lake import DeltaLakeSource
from datahub.ingestion.source.delta_lake.config import DeltaLakeConfig
config = DeltaLakeConfig(
base_path="/path/to/delta/tables",
platform="delta-lake",
env="PROD",
include_profiling=True,
profiling=DataLakeProfilerConfig(
enabled=True,
sample_size=5000,
profile_table_level_only=False
)
)
高级功能与最佳实践
增量元数据提取
DataHub支持智能的增量提取机制,通过状态管理实现高效同步:
# 状态管理实现增量提取
state_provider = SQLAlchemyStateProvider(
connection_string="postgresql://user:pass@localhost/datahub_state"
)
source = SnowflakeSource(
config=config,
ctx=PipelineContext(run_id="incremental-run", state_provider=state_provider)
)
# 自动处理增量逻辑
for workunit in source.get_workunits():
if workunit.is_incremental():
process_incremental_change(workunit)
性能优化策略
并行处理配置
source:
type: bigquery-v2
config:
# ... 其他配置
max_workers: 8
query_parallelism: 4
profiling:
max_workers: 6
use_sampling: true
sample_size: 10000
内存优化设置
source:
type: snowflake
config:
# ... 其他配置
max_memory_usage_mb: 4096
chunk_size: 1000
enable_stateful_ingestion: true
错误处理与重试机制
DataHub提供完善的错误处理框架:
from datahub.ingestion.source.common.data_reader import DataReader
from datahub.ingestion.reporting import SourceReport
class ResilientSource:
def __init__(self, config, max_retries=3, backoff_factor=2):
self.config = config
self.max_retries = max_retries
self.backoff_factor = backoff_factor
self.report = SourceReport()
def get_workunits_with_retry(self):
for attempt in range(self.max_retries):
try:
return self._get_workunits()
except Exception as e:
if attempt == self.max_retries - 1:
self.report.report_failure("source", str(e))
raise
time.sleep(self.backoff_factor ** attempt)
监控与运维
提取状态监控
# 监控配置示例
monitoring:
enabled: true
metrics:
- name: ingestion_duration_seconds
help: "元数据提取耗时"
labels: ["source_type", "status"]
- name: entities_ingested_total
help: "已提取实体数量"
labels: ["source_type", "entity_type"]
alerts:
- alert: IngestionDurationHigh
expr: ingestion_duration_seconds > 300
for: 5m
labels:
severity: warning
annotations:
summary: "元数据提取耗时过长"
日志与审计
DataHub提供详细的审计日志功能:
import logging
from datahub.ingestion.source.source_report import SourceReport
# 配置结构化日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('ingestion.log'),
logging.StreamHandler()
]
)
# 审计日志记录
def audit_ingestion_activity(source_type, config, report: SourceReport):
logger.info(f"开始提取 {source_type} 元数据")
logger.info(f"配置参数: {config}")
# 记录提取结果
for warning in report.warnings:
logger.warning(f"警告: {warning}")
for failure in report.failures:
logger.error(f"失败: {failure}")
logger.info(f"提取完成: {report.summary}")
通过完善的Pull-based集成体系,DataHub能够为组织提供全面、准确、及时的元数据管理能力,支撑数据发现、数据治理和数据血缘分析等关键数据管理场景。
Sources、Sinks、Recipe核心概念解析
在DataHub的元数据摄取生态系统中,Sources(源)、Sinks(接收器)和Recipe(配方)构成了核心的三元架构。理解这些概念对于构建高效的元数据管道至关重要。
Recipe:元数据摄取的蓝图
Recipe是DataHub元数据摄取的核心配置文件,它定义了从何处提取元数据(Source)以及将元数据发送到何处(Sink)。Recipe采用YAML格式,结构清晰且易于配置。
# 基础Recipe结构示例
source:
type: snowflake
config:
account_id: my_account
username: ${SNOWFLAKE_USERNAME}
password: ${SNOWFLAKE_PASSWORD}
warehouse: COMPUTE_WH
role: SYSADMIN
sink:
type: datahub-rest
config:
server: "http://localhost:8080"
token: ${DATAHUB_TOKEN}
Recipe的设计遵循单一职责原则,每个Recipe文件只能包含一个Source和一个Sink。这种设计确保了管道的清晰性和可维护性。
Sources:元数据的源头
Sources代表了各种数据系统,DataHub从中提取元数据。每个Source类型都有特定的配置参数,用于连接到对应的数据源。
Source类型分类
DataHub支持多种类型的Sources,主要包括:
| Source类别 | 示例 | 主要功能 |
|---|---|---|
| 数据库系统 | MySQL, PostgreSQL, Snowflake | 提取表结构、列信息、权限等 |
| 数据仓库 | BigQuery, Redshift, Databricks | 获取数据集、视图、物化视图 |
| 消息队列 | Kafka, Pulsar | 收集主题、分区、消费者组信息 |
| 文件系统 | S3, HDFS, Delta Lake | 提取文件元数据、目录结构 |
| BI工具 | Looker, Tableau | 获取仪表板、报表元数据 |
Source配置示例
# Kafka Source配置示例
source:
type: kafka
config:
connection:
bootstrap: "localhost:9092"
schema_registry_url: "http://localhost:8081"
topic_patterns:
allow:
- ".*important.*"
deny:
- ".*test.*"
Sinks:元数据的目的地
Sinks定义了元数据的输出目的地,负责将提取的元数据发送到指定的存储或处理系统。
主要Sink类型
| Sink类型 | 协议 | 适用场景 |
|---|---|---|
| datahub-rest | HTTP/REST | 生产环境,直接推送到DataHub |
| datahub-kafka | Kafka | 高吞吐量场景,异步处理 |
| console | 标准输出 | 调试和开发环境 |
| file | 本地文件 | 离线分析和备份 |
Sink配置深度解析
# datahub-rest Sink高级配置
sink:
type: datahub-rest
config:
server: "https://datahub.example.com"
timeout_sec: 30
retry_max_times: 3
retry_backoff_factor: 1.5
extra_headers:
X-Custom-Header: "custom-value"
# 启用压缩传输
compress_requests: true
核心架构流程图
环境变量与安全配置
DataHub提供了灵活的安全配置机制,支持环境变量替换,确保敏感信息的安全处理:
source:
type: bigquery
config:
project_id: ${GCP_PROJECT_ID}
credential:
__DATAHUB_TO_FILE_private_key: ${GCP_PRIVATE_KEY}
# 自动替换为文件路径
高级功能:Transformers
Transformers允许在元数据到达Sink之前进行自定义处理,为元数据管道提供了极大的灵活性:
transformers:
- type: simple_add_dataset_tags
config:
tag_urns:
- "urn:li:tag:Production"
- "urn:li:tag:Critical"
- type: pattern_add_dataset_ownership
config:
owner_pattern:
pattern: "^(.*?)_.*$"
owner_type: "USER"
配置验证与自动补全
DataHub支持配置文件的语法验证和自动补全功能。通过使用.dhub.yaml文件扩展名,开发者可以获得IDE的智能提示支持:
# my_recipe.dhub.yaml
source:
type: mssql
config:
username: sa
password: ${MSSQL_PASSWORD}
database: DemoData
# IDE会自动提示可用的配置选项
这种设计极大地提高了配置的准确性和开发效率,减少了因配置错误导致的问题。
通过深入理解Sources、Sinks和Recipe这三个核心概念,开发者可以构建出高效、可靠且易于维护的元数据摄取管道,为数据治理和数据发现奠定坚实的基础。
总结
DataHub提供了强大而灵活的元数据摄取生态系统,通过Push和Pull两种模式满足不同场景的需求。Push模式适合实时元数据同步,为Airflow、Spark等数据处理框架提供主动推送能力;Pull模式则通过批量爬取各类数据源,构建完整的数据目录。Sources、Sinks和Recipe三大核心概念构成了清晰的元数据管道架构,使开发者能够构建高效、可靠的元数据管理解决方案。掌握这些核心概念和技术,对于实施有效的数据治理和数据发现策略至关重要。
【免费下载链接】datahub 项目地址: https://gitcode.com/gh_mirrors/datahub/datahub
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



