本节摘要:管道越长,"哪张表在哪、结构由谁定义、口径归谁管"就越要紧。Catalog 是 Flink SQL 的元数据体系:临时表、环境目录、外部目录三级结构各司其职。本节讲清三级目录的分工、外部目录如何让"建表"变成"挂表"、以及元数据中心化对团队协作的实际价值。读完你应能把自己作业里散落的建表语句收编进正确的层级。
上一节那条 CDC 同步作业里,源表与目标表的定义都写在作业脚本里。作业一多,问题来了:同一个 OLAP 结果表,三个作业各自定义了三遍——某次目标端加列,漏改了一个作业的字段声明,运行时才发现类型对不上。这类事故的病根是元数据散养:表结构这份"户籍信息"被抄写在无数作业脚本里,谁也没义务保持一致。Catalog 的使命就是给户籍上一个系统:表与库的定义集中登记、统一引用、一处修改处处生效。
第一级:临时表(Temporary)。 生命周期跟着会话走,会话结束即消失。适合试验、调试、一次性查询。它是你的草稿纸,不是生产形态——临时表定义留在代码里只会制造上一段的"散养事故"。
第二级:环境目录与内置表。 作业提交时随环境初始化的持久表定义,存放在 Flink 自己管理的元数据存储(或 SQL 客户端的会话环境)里。适合作业专属的中间层定义:上游 connector 的参数、作业私有的视图。它解决"这个作业自己的表"的登记问题。
第三级:外部目录(External Catalog)。 真正的枢纽。它让 Flink 直接挂载别处登记好的元数据——Hive Metastore 里的数仓表、Doris 的库表、Iceberg 的目录,Flink SQL 里一句 USE CATALOG 就能像本地表一样查询与写入。表结构只有一份真源(在 Hive 或 Doris 那边),Flink 不再持有副本;对端改了结构,Flink 侧即刻可见。"建表"从此变成"挂表",这正是元数据中心化的核心红利。
-- 挂载外部目录:Doris 的库表直接在 Flink SQL 里可用 CREATE CATALOG doris WITH ( 'type' = 'doris', 'fenodes' = 'fe-host:8030', 'username' = 'flink-reader', 'password' = '****' ); USE CATALOG doris; SELECT shop_id, SUM(gmv) FROM dwd_orders GROUP BY shop_id; -- 表来自 Doris 的元数据,无需再建 -- 再挂 Hive 数仓目录,跨源联查:实时表与离线维表一锅查 CREATE CATALOG hive WITH ('type' = 'hive'); SELECT o.order_id, d.shop_city FROM doris.dwd_orders o JOIN hive.dim.shop d ON o.shop_id = d.shop_id;
红利一:口径唯一。 同一张维表的定义在元数据中心只有一份,分析口径的分歧在物理上被消灭——这是数据团队内耗的最大减压阀。红利二:变更联动。 目标端加列,Catalog 拉取新结构,作业侧核对字段映射即可,不再需要逐作业手抄。红利三:治理抓手。 血缘、权限、生命周期都能挂在统一的元数据层上做:哪条管道引用了这张表、下线它影响谁,查一下户籍就有答案,而散养时代这类问题靠"问老员工"。
| 层级 | 生命周期 | 适合放什么 | 反例(别放) |
|---|---|---|---|
| 临时表 | 会话内 | 调试、试验、临时探查 | 生产作业的正式表定义 |
| 内置/环境表 | 作业随行 | 作业私有 connector 定义与视图 | 多作业共享的维表 |
| 外部目录 | 独立持久 | 数仓表、OLAP 表、共享维表 | 无 |
给存量作业做元数据收编,务实路径分三步。第一步:盘点,把所有作业里的建表语句拉出来对号——哪些是外部系统的表(应挂 Catalog)、哪些是作业私有的(留内置层)、哪些是散养的维表(迁去元数据中心)。第二步:挂载,配置 Hive 或 Doris 等外部目录,把第一步识别出的共享表迁过去,作业改用目录引用。第三步:立规矩,新作业的表定义只允许出现在两级:作业私有的内置层,或外部目录;代码里出现第三种"抄写外部表结构"的写法即评审打回。三步走完,第 7 章开头的"三遍定义三遍事故"就从机制上绝了根。
⚠️ 常见坑:把外部目录当银弹一步全挂。Catalog 的类型对连接器参数的支持有限(比如某些 CDC 专属参数仍需作业内声明),收编时按"共享表优先、特殊连接器留作业内"的节奏推进,别为了形式上的纯洁把管道搞复杂。
挂载外部目录后还有一个工程细节常被问到:Flink 作业里引用外部表时,连接器参数(比如写入的分区刷新策略、缓存大小)从哪来?答案是分层的——外部目录只提供"表是什么"(结构、类型、主键),"怎么连、怎么写"的连接器参数仍由作业侧声明。于是常见的折中形态出现了:对共享表用目录引用,再在作业内用动态表选项做参数微调(比如给维表 join 挂一个查找缓存)。理解这条边界能避免两类徒劳:指望 Catalog 收编一切连接参数(做不到),或因此放弃 Catalog(因噎废食)。结构与连接分离、共享与特化分层,是元数据体系给人最实用的一课。
第 7 章收官,管道的血管与户籍都通了。最后一章进入实战的总装车间:性能调优,以及把全册知识拧成一股绳的大屏复盘。