StarRocks 外部目录(External Catalog)全解:CREATE EXTERNAL CATALOG 语法、参数与源码级实战指南
【免费下载链接】starrocksThe world's fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks
本文是一份关于 StarRocksCREATE EXTERNAL CATALOG语句的完整实战指南。外部目录(External Catalog)允许你无需将数据导入 StarRocks、也无需预先创建外部表,即可直接查询 Hive、Iceberg、Hudi、Delta Lake、JDBC、Elasticsearch、Paimon、Fluss 等外部数据源中的数据。读完本文,你将掌握外部目录的创建语法、各类数据源的 PROPERTIES 配置方法、前置环境要求、权限模型,以及从解析到执行的源码级原理,能够在实际集群中一次性创建成功并开展跨 Catalog 联邦查询。
一、什么是外部目录(External Catalog)
StarRocks 从 v2.3 起引入 Catalog 特性,将内部数据(存储在 StarRocks 中的数据)与外部数据(存储在外部数据源中的数据)统一纳入一套管理体系中。集群中仅存在一个管理内部数据的内置目录default_catalog,其余通过 SQL 创建的目录均为外部目录,其本质是"指向外部元数据服务(Metastore)的链接"——FE 通过它访问外部元数据以生成执行计划,BE/CN 并行扫描外部数据文件并回传结果。详见 catalog_overview.md。
当前版本下,CREATE EXTERNAL CATALOG支持创建以下类型的外部目录:
| 外部目录类型 | 数据源 | 版本要求 |
|---|---|---|
| Hive catalog | Apache Hive | — |
| Iceberg catalog | Apache Iceberg | — |
| Hudi catalog | Apache Hudi | — |
| Delta Lake catalog | Delta Lake | — |
| JDBC catalog | JDBC 兼容数据源 | — |
| Elasticsearch catalog | Elasticsearch | v3.1 起 |
| Paimon catalog | Apache Paimon | v3.1 起 |
| Fluss catalog | Apache Fluss | — |
| Unified catalog | Hive、Iceberg、Hudi、Delta Lake(统一数据源) | v3.2 起 |
在源码层面,这些类型与 ConnectorType.java 枚举一一对应:hive、iceberg、jdbc、hudi、deltalake、es、paimon、fluss、unified,以及面向特定场景的odps、kudu、benchmark、lance。每个类型均绑定一个 Connector 实现类(如HiveConnector、IcebergConnector),创建外部目录本质上是实例化一个对应的 Connector。
注意
- 从 v3.0 起,执行该语句需要SYSTEM 级别的
CREATE EXTERNAL CATALOG权限。- 创建前,需要确保 StarRocks 集群能够访问外部数据源的存储系统(如 Amazon S3)、元数据服务(如 Hive metastore)与认证服务(如 Kerberos)。具体要求参见 catalog_overview.md 中各类外部目录主题的 "Before you begin" 部分。
二、创建前置条件
2.1 权限要求
从 v3.0 起,CREATE EXTERNAL CATALOG属于系统级操作,用户必须持有 SYSTEM 对象的CREATE EXTERNAL CATALOG权限,否则会被拒绝。在 PrivilegeType.java 中该权限定义为new PrivilegeType(26, "CREATE EXTERNAL CATALOG");AuthorizerStmtVisitor.java 中的visitCreateCatalogStatement会先调用Authorizer.checkSystemAction(...)校验该权限,校验失败即抛出AccessDeniedException。
建议由管理员授予:
GRANT CREATE EXTERNAL CATALOG ON SYSTEM TO USER <user_name>;2.2 集群与网络配置
- 存储系统:确认 BE/CN 节点可访问外部存储(HDFS 或 S3 等对象存储),必要时在
be/conf/hadoop_env.sh、cn/conf/hadoop_env.sh中设置访问用户,并放置hdfs-site.xml、core-site.xml到对应 conf 目录(HA/ViewFs 场景)。 - 元数据服务:确认 FE 节点可连通 Hive metastore(默认端口 9083)。建议在
/etc/hosts中配置 Hive 元数据节点的主机名与 IP 映射,否则查询时可能解析失败。 - 认证服务:使用 Kerberos 时,需在 FE/BE/CN 上执行
kinit获取 TGT,并在fe.conf、be.conf、cn.conf中配置-Djava.security.krb5.conf。具体步骤见 hive_catalog.md。
2.3 命名规范
catalog_name需遵循系统限制:名称可包含字母、数字(0-9)与下划线(_),必须以字母开头;名称大小写敏感且长度不能超过 1023 个字符。此外,外部目录名称不能与内置目录default同名。详见 System_limit.md。
从 v4.0 起,FE 配置项enable_table_name_case_insensitive控制目录名等对象名是否大小写不敏感(默认关闭)。官方文档明确提示:启用该特性可能导致外部目录不可用——外部服务命名与大小写约定各异,StarRocks 强制转小写后可能在源端查不到对应对象而报 "not found",因此不要对使用外部目录的集群开启该特性。
三、语法与参数详解
CREATE EXTERNAL CATALOG [IF NOT EXISTS] <catalog_name> [COMMENT <comment>] PROPERTIES ("key"="value", ...)参数说明:
| 参数 | 是否必填 | 说明 |
|---|---|---|
catalog_name | 是 | 外部目录名称,命名规范见上文及 System_limit.md |
comment | 否 | 外部目录的描述信息 |
PROPERTIES | 是 | 外部目录的属性键值对,需根据目录类型按需配置,详见 Hive catalog、Iceberg catalog、Hudi catalog、Delta Lake catalog、JDBC Catalog、Fluss catalog 等主题 |
3.1 通用属性:type
PROPERTIES中type是强制要求的第一个属性,用于声明数据源类型,取值即上文ConnectorType枚举中的名称(如hive、iceberg、hudi、deltalake、jdbc、es、paimon、fluss、unified)。缺失type或填了不支持的取值,语句都会被直接拒绝(详见下文源码分析)。
3.2 Hive 目录常用属性
以最常见的 Hive 目录为例(完整属性见 hive_catalog.md),PROPERTIES 可分为四组:
- GeneralParams(通用):
enable_recursive_listing,是否递归读取表/分区物理路径下的子目录,默认true。 - MetastoreParams(元数据服务):
- Hive metastore:
"hive.metastore.type"="hive"+"hive.metastore.uris"="thrift://<metastore_IP>:<port>"。若 Hive metastore 启用了 HA,可配置多个 URI 并用逗号分隔。 - AWS Glue(仅当存储为 AWS S3 时可用):
"hive.metastore.type"="glue",并配合aws.glue.region、aws.glue.use_instance_profile/aws.glue.iam_role_arn/ 访问密钥等认证参数。
- Hive metastore:
- StorageCredentialParams(存储认证):访问 S3 等对象存储所需的
aws.s3.access_key、aws.s3.secret_key、aws.s3.endpoint、aws.s3.region、aws.s3.enable_path_style_access等;HDFS 无需在 PROPERTIES 中配置凭据。 - MetadataUpdateParams(元数据缓存更新):如
enable_metastore_cache、enable_remote_file_cache、metadata_cache_refresh_interval_sec等。
其他类型的目录(Iceberg、Hudi、JDBC、Paimon、Fluss 等)同样有各自专属的属性集,配置前请查阅对应外部目录主题文档。
四、完整创建示例
示例 1:Hive 目录(Hive metastore 为元数据服务)
CREATE EXTERNAL CATALOG hive_metastore_catalog COMMENT "External catalog to Hive" PROPERTIES( "type"="hive", "hive.metastore.uris"="thrift://xx.xx.xx.xx:9083" );示例 2:Hive 目录(AWS Glue 为元数据服务)
CREATE EXTERNAL CATALOG hive_glue_catalog COMMENT "External catalog to Hive" PROPERTIES( "type"="hive", "hive.metastore.type"="glue", "aws.hive.metastore.glue.aws-access-key"="xxxxxx", "aws.hive.metastore.glue.aws-secret-key"="xxxxxxxxxxxx", "aws.hive.metastore.glue.endpoint"="https://glue.x-x-x.amazonaws.com" );示例 3:Iceberg 目录(Hive metastore 为元数据服务)
CREATE EXTERNAL CATALOG iceberg_metastore_catalog COMMENT "External catalog to Iceberg" PROPERTIES( "type"="iceberg", "iceberg.catalog.type"="hive", "iceberg.catalog.hive.metastore.uris"="thrift://xx.xx.xx.xx:9083" );示例 4:Iceberg 目录(AWS Glue 为元数据服务)
CREATE EXTERNAL CATALOG iceberg_glue_catalog COMMENT "External catalog to Iceberg" PROPERTIES( "type"="iceberg", "iceberg.catalog.type"="glue", "aws.hive.metastore.glue.aws-access-key"="xxxxx", "aws.hive.metastore.glue.aws-secret-key"="xxxxxxxxxxxx", "aws.hive.metastore.glue.endpoint"="https://glue.x-x-x.amazonaws.com" );示例 5:Hudi 目录(Hive metastore 为元数据服务)
CREATE EXTERNAL CATALOG hudi_metastore_catalog COMMENT "External catalog to Hudi" PROPERTIES( "type"="hudi", "hive.metastore.uris"="thrift://xx.xx.xx.xx:9083" );示例 6:Hudi 目录(AWS Glue 为元数据服务)
CREATE EXTERNAL CATALOG hudi_glue_catalog COMMENT "External catalog to Hudi" PROPERTIES( "type"="hudi", "hive.metastore.type"="glue", "aws.hive.metastore.glue.aws-access-key"="xxxxxx", "aws.hive.metastore.glue.aws-secret-key"="xxxxxxxxxxxx", "aws.hive.metastore.glue.endpoint"="https://glue.x-x-x.amazonaws.com" );示例 7:Delta Lake 目录(Hive metastore 为元数据服务)
CREATE EXTERNAL CATALOG delta_metastore_catalog COMMENT "External catalog to Delta" PROPERTIES( "type"="deltalake", "hive.metastore.uris"="thrift://xx.xx.xx.xx:9083" );示例 8:Delta Lake 目录(AWS Glue 为元数据服务)
CREATE EXTERNAL CATALOG delta_glue_catalog COMMENT "External catalog to Delta" PROPERTIES( "type"="deltalake", "hive.metastore.type"="glue", "aws.hive.metastore.glue.aws-access-key"="xxxxxx", "aws.hive.metastore.glue.aws-secret-key"="xxxxxxxxxxxx", "aws.hive.metastore.glue.endpoint"="https://glue.x-x-x.amazonaws.com" );五、源码级原理:从 SQL 到外部目录的完整链路
理解创建语句背后的执行链路,有助于排查"为什么创建失败"以及理解目录的本质。以下路径均基于当前仓库 FE 端源码。
5.1 语法解析(Parser)
SQL 语句先由 AstBuilder.java 中的visitCreateExternalCatalogStatement解析:识别IF NOT EXISTS、提取目录名(identifierOrString)、可选comment,并调用getCaseSensitiveProperties保留PROPERTIES中键的大小写,最终构造CreateCatalogStmt语法树节点。注意这里有个实现细节:PROPERTIES 的 key 是大小写敏感的,配置属性时请严格按文档书写键名。
5.2 语义校验(Analyzer)
CatalogAnalyzer.java 的visitCreateCatalogStatement执行一系列校验:
- 目录名非空,且通过
FeNameFormat.checkCatalogName命名检查; - 目录名不能与内置目录
default相同; PROPERTIES中必须包含type键,否则报'type' can not be null or empty;type取值必须被ConnectorType.isSupport支持,否则报[type : xxx] is not supported。
随后,AuthorizerStmtVisitor.java 校验当前用户的 SYSTEM 级CREATE EXTERNAL CATALOG权限。
5.3 执行与持久化(CatalogMgr)
真正落地由 CatalogMgr.java 的createCatalog完成:
- 加写锁,校验目录不存在(已存在则报错);
- 通过
connectorMgr.createHiddenConnector依据(catalogName, type, properties)实例化对应的 Connector(如HiveConnector),失败则抛出DdlException; - 为目录分配全局 ID,构造
ExternalCatalog对象(见 ExternalCatalog.java); - 写入 EditLog(WAL),在日志落盘成功后再把目录注册进内存 Map 并把 Connector 挂载到 ConnectorMgr——这保证了元数据持久化与 Connector 创建的一致性。
5.4 测试验证
仓库中的 CatalogStmtTest.java 覆盖了上述全部校验路径,可作为行为契约参考:
- 合法语句(含
type)解析成功并生成CreateCatalogStmt; - 缺少
PROPERTIES的语句解析失败; type取值不支持的语句失败(如"type"="xxx");- 缺少
type键的语句失败; - 目录名为
default的语句失败; IF NOT EXISTS语义正确:重复创建同一目录时报exists,带上IF NOT EXISTS后不再报错;- 测试还验证了
catalog.access.control等扩展属性可以被解析并生效。
六、创建后的目录管理与使用
创建外部目录后,可通过以下语句查看与管理(对应文档均位于 Catalog 语句目录):
- 切换目录:
SET CATALOG <catalog_name>,切换后可直接用database.table方式查询该目录下数据,详见 SET_CATALOG.md。 - 查看全部目录:
SHOW CATALOGS [LIKE '<pattern>'],其中%匹配任意字符、_匹配单个字符。注意:该语句只返回当前用户拥有 USAGE 权限的外部目录;若用户对任何外部目录都没有权限,则只返回default_catalog,详见 SHOW_CATALOGS.md。 - 查看创建语句:
SHOW CREATE CATALOG <catalog_name>,可回看某外部目录的原始 DDL,便于迁移与审计,详见 SHOW_CREATE_CATALOG.md。 - 删除目录:
DROP CATALOG <catalog_name>,详见 DROP_CATALOG.md。
跨目录联邦查询
创建好外部目录后,无需任何数据搬迁即可做联邦查询:以catalog_name.database_name或catalog_name.database_name.table_name的三段式/两段式名称引用对象。例如当前会话在default_catalog下直接查询 Hive 数据:
SELECT * FROM hive_catalog.hive_db.hive_table;或将外部表与内部表 JOIN:
SELECT * FROM hive_catalog.hive_db.hive_table h JOIN default_catalog.olap_db.olap_table o WHERE h.id = o.id;详细用法可参考 catalog_overview.md 与 query_external_data.md。
七、最佳实践与常见问题
- 先建连接、再建目录:创建前务必先在 FE/BE/CN 侧验证与存储、Metastore、KDC 的网络连通性(如
telnet <metastore_ip> 9083),并将元数据节点主机名写入/etc/hosts,避免创建成功但查询超时的"假成功"。 type键必须准确且大小写正确:type值是强校验项,写错会直接报is not supported;而其他属性的 key 同样大小写敏感,务必对照 hive_catalog.md 等文档逐字核对。- 权限最小化:
CREATE EXTERNAL CATALOG是 SYSTEM 级权限,建议仅授予管理员;普通用户通过 USAGE 权限访问外部目录(SHOW CATALOGS也以此过滤)。 - 慎用
enable_table_name_case_insensitive:该配置与外部目录不兼容(可能导致对象名被改写后查不到),使用外部目录的集群应保持其默认关闭。 - 命名规范提前规划:目录名必须以字母开头、只能包含字母数字下划线、≤1023 字符且大小写敏感,且不能占用内置名
default;一次规划、全集群复用,避免后续 DROP/重建带来的权限与引用变更。 - 善用
IF NOT EXISTS与幂等脚本:在自动化初始化脚本中加上IF NOT EXISTS,配合SHOW CREATE CATALOG回读配置,可以安全地重复执行初始化流程。
【免费下载链接】starrocksThe world's fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考