Catalog 是一项面向企业数据平台的托管服务,严格遵循 Apache Iceberg REST API 规范,为各类计算引擎提供统一、标准的 Iceberg 元数据读写功能。该服务旨在简化多引擎、多租户环境下的数据管理和安全治理工作。
- 统一接入:通过单一的 REST 端点为多个计算引擎和工作负载提供服务,可显著降低接入与运维成本。
- 多租户与多目录管理:以火山引擎账号和 Catalog 为边界进行资源隔离与治理,能够简化权限管理与审计工作。
- 开放规范兼容:完全兼容 Iceberg REST v1 规范,支持命名空间、表的创建、查询、删除等全套标准操作。
说明
本功能目前处于白名单开放阶段,仅华北2(北京)及华东2(上海)区域支持使用。如需使用,请提交工单申请。开通后,您将获得服务访问端点(Endpoint),结合火山引擎访问密钥(AK/SK)即可在计算引擎中进行配置并使用。 在使用前,请务必理解以下关键概念在火山引擎环境中的映射关系:
- Metalake:对应您的火山引擎账号 ID (AccountId)。所有资源和权限均以此为边界进行隔离与管理。
- Catalog:统一映射到火山引擎 LAS 元数据管理服务中的 Hive Catalog。
在配置客户端前,请完成以下准备工作,以确保服务能被顺利调用。
服务 Endpoint 与区域 (Region)
您需要从火山引擎获取服务的访问端点(Endpoint)。请确保客户端部署在与服务相同的区域(Region),或具备网络可达性。Region 的取值示例包括 cn-beijing、cn-shanghai 等。
所有 API 请求都必须经过签名认证。请前往火山引擎控制台的“访问控制”页面创建并获取访问密钥(Access Key ID 和 Secret Access Key)。 Apache® Gravitino Iceberg REST Catalog 采用火山引擎标准的 API 签名机制,以确保请求的机密性、完整性和身份验证。您需要在每个请求的 Header 中添加 Authorization 和 X-Date 字段。
Apache Gravitino, the names of other Apache projects, and the ASF logo are either registered trademarks or trademarks of the Apache Software Foundation in the United States and/or other countries.
签名步骤概览:
- 构建规范请求 (Canonical Request):拼接 HTTP 方法、URI、查询字符串、请求头和请求体哈希值。
- 创建待签名字符串 (String to Sign):组合签名算法、时间戳、凭证范围和规范请求的哈希值。
- 计算签名密钥 (Signing Key):使用 SK 和时间、区域、服务等信息派生出签名密钥。
- 计算最终签名 (Signature):使用签名密钥对待签名字符串进行 HMAC-SHA256 哈希计算。
- 组装 Authorization 头:将 AK 和计算出的签名信息组合成最终的 Authorization 请求头。
以下是一个生成签名的伪代码示例,帮助您理解签名过程:
AK = "{ak}" # 您的 Access Key ID
SK = "{sk}" # 您的 Secret Access Key
Region = "{region}" # 例如:cn-beijing
Service = "las" # 服务名称固定为 las
Host = "{endpoint}" # 服务端点
Path = "/v1/namespaces/{namespace}/tables"
Timestamp = "20251117T100000Z" # ISO8601 格式的 UTC 时间
RequestPayload = "{...}" # 请求体 JSON 内容
# 2. 构造规范化请求 (Canonical Request)
CanonicalRequest = Method + '\n' + Path + '\n' + '' + '\n' + 'host:' + Host + '\n' + 'x-date:' + Timestamp + '\n' + '\n' + Headers + '\n' + Hex(SHA256(RequestPayload))
# 3. 构造签名字符串 (String to Sign)
StringToSign = "HMAC-SHA256" + '\n' + Timestamp + '\n' + Date(Timestamp) + '/' + Region + '/' + Service + '/request' + '\n' + Hex(SHA256(CanonicalRequest))
# 4. 计算签名密钥 (Signing Key)
DateKey = HMAC-SHA256(Date(Timestamp), SK)
DateRegionKey = HMAC-SHA256(Region, DateKey)
DateRegionServiceKey = HMAC-SHA256(Service, DateRegionKey)
SigningKey = HMAC-SHA256("request", DateRegionServiceKey)
Signature = Hex(HMAC-SHA256(StringToSign, SigningKey))
# 6. 构造 Authorization Header
AuthorizationHeader = "HMAC-SHA256 Credential=" + AK + "/" + Date(Timestamp) + "/" + Region + "/" + Service + "/request, SignedHeaders=" + Headers + ", Signature=" + Signature
注意:上述伪代码主要用于演示核心签名流程。实际使用中,如果需要控制签名有效期,请在请求头中额外加入 X-Expire 字段。该字段与 X-Date 协同工作,用于控制有效天数,例如 -1 表示永不过期。为保持兼容性,SignedHeaders 中可不包含 X-Expire。
以下是核心 API 的详细说明。所有请求均需包含正确的签名头 Authorization 和 X-Date。
查询指定 Catalog 下的所有 Namespaces。
查询参数:
请求示例:
curl --location 'https://{endpoint}/iceberg/v1/namespaces?pageSize=10' \
--header 'X-Date: 20251117T100000Z' \
--header 'X-Expire: -1' \
--header 'Authorization: HMAC-SHA256 Credential={ak}/20251117/{region}/las/request, SignedHeaders=host;x-date, Signature={signature}' \
--header 'Region: {region}'
响应示例 (成功):
"next-page-token": "..."
状态码与错误码:
- 401 Unauthorized: 签名无效或权限不足。
- 500 Internal Server Error: 服务器内部错误。
在 Catalog 中创建一个新的 Namespace。
请求体:
请求示例:
curl --location 'https://{endpoint}/iceberg/v1/namespaces' \
--header 'X-Date: 20251117T100000Z' \
--header 'X-Expire: -1' \
--header 'Authorization: HMAC-SHA256 Credential={ak}/20251117/{region}/las/request, SignedHeaders=host;x-date, Signature={signature}' \
--header 'Region: {region}' \
--header 'Content-Type: application/json' \
"location": "tos://my-bucket/sales_data"
响应示例 (成功):
"location": "tos://my-bucket/sales_data"
状态码与错误码:
- 409 Conflict: Namespace 已存在。
获取指定 Namespace 的元数据信息。
- 路径: /v1/namespaces/{namespace}
请求示例:
curl --location 'https://{endpoint}/iceberg/v1/namespaces/sales' \
--header 'X-Date: 20251117T100000Z' \
--header 'X-Expire: -1' \
--header 'Authorization: HMAC-SHA256 Credential={ak}/20251117/{region}/las/request, SignedHeaders=host;x-date, Signature={signature}' \
--header 'Region: {region}'
响应示例 (成功):
"location": "tos://bucket-path/sales_data"
状态码与错误码:
- 404 Not Found: Namespace 不存在。
删除一个空的 Namespace。
- 路径: /v1/namespaces/{namespace}
请求示例:
curl --location --request DELETE 'https://{endpoint}/iceberg/v1/namespaces/temp_ns' \
--header 'X-Date: 20251117T100000Z' \
--header 'X-Expire: -1' \
--header 'Authorization: HMAC-SHA256 Credential={ak}/20251117/{region}/las/request, SignedHeaders=host;x-date, Signature={signature}' \
--header 'Region: {region}'
响应示例 (成功):
(无响应体,状态码 204 No Content)
状态码与错误码:
- 404 Not Found: Namespace 不存在。
- 409 Conflict: Namespace 不为空,无法删除。
查询指定 Namespace 下的所有表。
- 路径: /v1/namespaces/{namespace}/tables
请求示例:
curl --location 'https://{endpoint}/iceberg/v1/namespaces/sales/tables' \
--header 'X-Date: 20251117T100000Z' \
--header 'X-Expire: -1' \
--header 'Authorization: HMAC-SHA256 Credential={ak}/20251117/{region}/las/request, SignedHeaders=host;x-date, Signature={signature}' \
--header 'Region: {region}'
响应示例 (成功):
{"namespace": ["sales"], "name": "orders"},
{"namespace": ["sales"], "name": "customers"}
在指定的 Namespace 中创建一个新表。
- 路径: /v1/namespaces/{namespace}/tables
请求体:
请求体是一个复杂的 JSON 对象,包含表名、Schema、分区规范、写入模式和属性等。详细结构请参考 Iceberg 官方 REST API 文档。
请求示例:
curl --location 'https://{endpoint}/iceberg/v1/namespaces/sales/tables' \
--header 'X-Date: 20251117T100000Z' \
--header 'X-Expire: -1' \
--header 'Authorization: HMAC-SHA256 Credential={ak}/20251117/{region}/las/request, SignedHeaders=host;x-date, Signature={signature}' \
--header 'Region: {region}' \
--header 'Content-Type: application/json' \
"partition-spec": { ... }
响应示例 (成功):
返回完整的表元数据 JSON 对象。
"metadata-location": "tos://.../metadata.json",