2. Catalog核心概念

好,咱们正式开始聊 Catalog。说实话,很多刚接触数据湖仓的同学,一上来就被这几个概念搞晕了——Catalog 是什么?它和 Schema、Table 到底啥关系?元数据服务又是干嘛的?

我当年刚入行时也踩过这个坑。记得有一次,我在一个项目里把 Hive Metastore 和 Catalog 混为一谈,结果跟 DBA 沟通时鸡同鸭讲了半小时。后来才明白,Catalog 其实是一个逻辑上的顶层容器,它管的是「数据在哪里、长什么样、怎么访问」这件事。

1. 什么是 Catalog

说白了,Catalog 就是一个元数据的命名空间。它把数据库、表、分区、列、格式、位置等信息统一管理起来。你可以把它想象成一个「数据目录」——就像图书馆的索引卡片柜,告诉你每本书放在哪个书架、哪个位置。

核心定义:Catalog 是元数据的顶层容器,负责管理数据资产的逻辑视图和物理映射。

在数据湖仓的语境下,Catalog 通常包含以下几类信息:

  • 数据对象定义:表名、列名、数据类型、分区键
  • 物理位置:文件路径、存储系统(HDFS、S3、OSS)
  • 格式信息:Parquet、ORC、Avro、Delta Lake、Iceberg 等
  • 访问权限:谁可以读、谁可以写
  • 统计信息:行数、文件大小、列值分布

我个人的习惯是,把 Catalog 理解成「数据湖的 DNS」——它把逻辑表名解析成物理文件路径。没有它,你每次查数据都得手动拼路径,那得多痛苦。

2. Catalog 与 Schema、Table 的关系

这三者的层级关系非常清晰。我画了一张图,你看完就明白了。

Catalog - Schema - Table 层级关系 Catalog → Schema → Table 层级关系 Catalog(元数据命名空间) 管理多个 Schema,提供统一视图和访问入口 Schema(逻辑数据库) 组织 Table 的逻辑分组,通常对应业务域或数据源 Table(数据表) 包含列定义、分区信息、存储格式、物理路径 列名 + 数据类型 分区键 + 文件路径 存储格式 + 统计信息

你看,从上到下是三层结构:

  • Catalog:最顶层,一个集群或平台可以有多个 Catalog。比如你可能有 prod_catalog、dev_catalog、analytics_catalog。
  • Schema:Catalog 下面的逻辑分组,相当于传统数据库里的 Database。比如 sales、finance、hr。
  • Table:最底层的数据表,包含具体的列、分区、格式信息。

举个例子,在 Trino 或 Spark 里,你查数据时写的路径是这样的:

-- 完整的三级命名
SELECT * FROM hive.sales.orders

-- 其中:
--   hive     = Catalog(连接器名称)
--   sales    = Schema(逻辑数据库)
--   orders   = Table(数据表)

我的经验:在项目中,我建议把 Schema 按业务域划分,而不是按数据源划分。比如把「用户行为」和「订单交易」分成两个 Schema,而不是「MySQL 数据」和「Kafka 数据」。这样后期做权限管理和数据治理会轻松很多。

3. 元数据服务的作用

Catalog 本身只是一个逻辑概念,真正干活的是背后的元数据服务。我遇到过不少团队,把 Catalog 和元数据服务混为一谈,其实它们是「接口 vs 实现」的关系。

元数据服务承担了以下几个关键职责:

职责 说明 典型实现
元数据存储 持久化存储表定义、列信息、分区信息 Hive Metastore (RDS)、AWS Glue、Polaris
元数据发现 自动扫描数据文件,推断 Schema 和分区 Spark Catalog Plugin、Iceberg REST Catalog
权限校验 控制谁可以访问哪些表、哪些列 Ranger、Atlas、Unity Catalog
统计信息 收集行数、文件大小、列值分布,供优化器使用 ANALYZE TABLE、CBO 统计
版本管理 记录表结构变更历史,支持时间旅行查询 Iceberg、Delta Lake 的元数据层

你想想看,如果没有元数据服务,每次查表都得去扫描整个目录树,那性能得多差?我见过一个团队,因为没配好 Hive Metastore,每次查询都要花 30 秒去列举 S3 上的文件——后来加上元数据缓存,查询时间直接降到 2 秒。

避坑指南:我曾经在一个多集群项目里,因为没统一元数据服务,导致两个集群对同一张表的 Schema 认知不一致——一个认为是 10 列,另一个认为是 12 列。结果数据同步时频繁报错。后来我们统一用 Iceberg REST Catalog 作为元数据服务层,才彻底解决这个问题。

4. 多 Catalog 场景下的元数据挑战

当你的数据湖仓里只有一个 Catalog 时,事情很简单。但一旦涉及多 Catalog 整合,元数据服务就成了核心瓶颈。我总结了几类常见挑战:

  • 元数据割裂:不同 Catalog 之间无法互相感知,导致数据孤岛
  • 权限不一致:A Catalog 用 Ranger,B Catalog 用原生的 Hive 权限,管理混乱
  • Schema 冲突:同一张表在不同 Catalog 里定义不同,数据质量无法保证
  • 查询路由:查询引擎需要知道去哪个 Catalog 找哪张表,否则会报错

嗯,这里要注意,解决这些问题的关键不是「消灭多 Catalog」,而是「统一元数据视图」。说白了,就是在上层加一个统一的元数据服务层,把底层的多个 Catalog 抽象成统一的接口。

核心思路:多 Catalog 整合的本质,是元数据层面的联邦查询 + 统一治理。不是把数据搬到一个地方,而是让查询引擎能「看到」所有 Catalog 的表,并且用一致的权限和 Schema 去访问。

我个人比较推荐的做法是,用 Iceberg REST Catalog 或 Polaris 作为统一的元数据网关。这样上层引擎(Trino、Spark、Flink)只需要对接这一个网关,底层可以挂接 Hive Metastore、AWS Glue、自建 Catalog 等。后面几章我会详细讲具体怎么搭。