快速开始

使用 Polaris

师成师成· 更新于 2026-09-29· 阅读 23 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

使用 Polaris

安装设置

从 PyPI 安装 Polaris CLI:

pip install apache-polaris

请确保 CLIENT_ID 和 CLIENT_SECRET 变量已经定义,因为它们是之前启动 Polaris 服务器时所必需的。

export CLIENT_ID=YOUR_CLIENT_ID
export CLIENT_SECRET=YOUR_CLIENT_SECRET

请参阅创建目录页面,了解如何针对你的具体存储类型定义目录。以下示例假设目录名称为 quickstart_catalog。

在 Polaris 中,catalog(目录)是顶层实体,表(table)和视图(view)等对象都归属于它进行组织。

你在创建目录时提供的 DEFAULT_BASE_LOCATION 值,将成为该目录中对象的默认存储位置。

此外,如果 Polaris 运行在 localhost:8181 以外的位置,你可以通过提供 --host 和 --port 参数来指定正确的主机名和端口。有关 CLI 支持的完整选项列表,请参阅文档。

创建主体并为其分配权限

目录创建完成后,我们可以创建一个具有访问权限的主体(principal),用于管理该目录。有关如何配置 Polaris CLI 的详细信息,请参阅创建目录页面或参阅文档。

polaris \
  --client-id ${CLIENT_ID} \
  --client-secret ${CLIENT_SECRET} \
  principals \
  create \
  quickstart_user

polaris \
  --client-id ${CLIENT_ID} \
  --client-secret ${CLIENT_SECRET} \
  principal-roles \
  create \
  quickstart_user_role

polaris \
  --client-id ${CLIENT_ID} \
  --client-secret ${CLIENT_SECRET} \
  catalog-roles \
  create \
  --catalog quickstart_catalog \
  quickstart_catalog_role

请务必像之前一样提供所需的凭据、主机名和端口。

principals create 命令成功完成后,会返回这个新主体的凭据。请将其导出以便后续使用。例如:

polaris ... principals create example
{"clientId": "XXXX", "clientSecret": "YYYY"}
export USER_CLIENT_ID=XXXX
export USER_CLIENT_SECRET=YYYY

现在,我们为该主体授予已创建的主体角色,并为已创建的目录角色授予该主体角色。有关这些实体的更多信息,请参阅上述链接的文档。

polaris \
  --client-id ${CLIENT_ID} \
  --client-secret ${CLIENT_SECRET} \
  principal-roles \
  grant \
  --principal quickstart_user \
  quickstart_user_role

polaris \
  --client-id ${CLIENT_ID} \
  --client-secret ${CLIENT_SECRET} \
  catalog-roles \
  grant \
  --catalog quickstart_catalog \
  --principal-role quickstart_user_role \
  quickstart_catalog_role

现在,我们已通过角色将主体与目录关联起来,如下所示:

主体与目录的关联

为了使该主体能够与目录进行交互,我们必须分配一些权限。目前,我们将赋予该主体完全管理新目录中内容的能力。可以通过 CLI 这样操作:

polaris \
  --client-id ${CLIENT_ID} \
  --client-secret ${CLIENT_SECRET} \
  privileges \
  catalog \
  grant \
  --catalog quickstart_catalog \
  --catalog-role quickstart_catalog_role \
  CATALOG_MANAGE_CONTENT

这会将目录权限 CATALOG_MANAGE_CONTENT 授予我们的目录角色,从而像下图这样将所有内容关联起来:

带有目录角色的主体到目录

CATALOG_MANAGE_CONTENT 对目录内的所有实体拥有创建、列出、读取和写入的权限。同样的权限也可以授予某个命名空间,在这种情况下,该主体就可以在该命名空间下创建、列出、读取和写入任何实体。

使用 Iceberg 与 Polaris

至此,我们已经创建了一个主体,并授予其管理目录的能力。现在我们可以使用外部引擎来扮演该主体,访问我们的目录,并使用 Apache Iceberg 将数据存储在该目录中。Polaris 兼容任何支持 REST API 的 Apache Iceberg 客户端。请根据你计划使用的客户端,参考下方相应的示例。

通过 Spark 连接

使用本地构建的 Spark

要在 Apache Spark 中使用由 Polaris 管理的目录,我们可以将 Spark 配置为使用 Iceberg 目录 REST API。

本指南使用 Apache Spark 3.5,但请务必找到与你的 Spark 版本相匹配的 iceberg-spark 包。在本地 branch-3.5 分支的 Spark 克隆目录中,我们可以运行以下命令:

注意:此处提供的凭据是我们主体的凭据,而非 root 凭据。

bin/spark-sql \
--packages org.apache.iceberg:iceberg-spark-runtime-3.5_2.12:1.10.0,org.apache.iceberg:iceberg-aws-bundle:1.10.0 \
--conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions \
--conf spark.sql.catalog.polaris.warehouse=quickstart_catalog \
--conf spark.sql.catalog.polaris.header.X-Iceberg-Access-Delegation=vended-credentials \
--conf spark.sql.catalog.polaris=org.apache.iceberg.spark.SparkCatalog \
--conf spark.sql.catalog.polaris.catalog-impl=org.apache.iceberg.rest.RESTCatalog \
--conf spark.sql.catalog.polaris.uri=http://localhost:8181/api/catalog \
--conf spark.sql.catalog.polaris.credential=${USER_CLIENT_ID}:${USER_CLIENT_SECRET} \
--conf spark.sql.catalog.polaris.scope='PRINCIPAL_ROLE:ALL' \
--conf spark.sql.catalog.polaris.token-refresh-enabled=true \
--conf spark.sql.catalog.polaris.client.region=us-west-2

与上面的 CLI 命令类似,该配置让 Spark 使用运行在 localhost:8181 的 Polaris。如果你的 Polaris 服务器运行在其他位置,请务必相应地更新配置。

最后,请注意这里包含了 iceberg-aws-bundle 包。如果你的表使用的是其他文件系统,请务必引入相应的依赖。

从 Docker 容器中使用 Spark SQL

使用用户的凭据刷新 Docker 容器:

docker compose -p polaris -f getting-started/jdbc/docker-compose.yml stop spark-sql
docker compose -p polaris -f getting-started/jdbc/docker-compose.yml rm -f spark-sql
docker compose -p polaris -f getting-started/jdbc/docker-compose.yml up -d --no-deps spark-sql

附加到正在运行的 spark-sql 容器:

docker attach $(docker ps -q --filter name=spark-sql)

示例命令

Spark 会话启动后,我们可以在该 catalog 中创建命名空间和表:

USE polaris;
CREATE NAMESPACE IF NOT EXISTS quickstart_namespace;
CREATE NAMESPACE IF NOT EXISTS quickstart_namespace.schema;
USE NAMESPACE quickstart_namespace.schema;
CREATE TABLE IF NOT EXISTS quickstart_table (id BIGINT, data STRING) USING ICEBERG;

我们现在可以像使用其他任何表一样使用这张表:

INSERT INTO quickstart_table VALUES (1, 'some data');
SELECT * FROM quickstart_table;
. . .
+---+---------+
|id |data     |
+---+---------+
|1  |some data|
+---+---------+

如果在任何时候访问权限被撤销,

polaris \
  --client-id ${CLIENT_ID} \
  --client-secret ${CLIENT_SECRET} \
  privileges \
  catalog \
  revoke \
  --catalog quickstart_catalog \
  --catalog-role quickstart_catalog_role \
  CATALOG_MANAGE_CONTENT

Spark 将失去对该表的访问权限:

INSERT INTO quickstart_table VALUES (1, 'some data');

org.apache.iceberg.exceptions.ForbiddenException: Forbidden: Principal 'quickstart_user' with activated PrincipalRoles '[]' and activated grants via '[quickstart_catalog_role, quickstart_user_role]' is not authorized for op LOAD_TABLE_WITH_READ_DELEGATION

与 Trino 连接

使用用户凭据刷新 Docker 容器:

docker compose -p polaris -f getting-started/jdbc/docker-compose.yml stop trino
docker compose -p polaris -f getting-started/jdbc/docker-compose.yml rm -f trino
docker compose -p polaris -f getting-started/jdbc/docker-compose.yml up -d --no-deps trino

附加到正在运行的 Trino 容器:

docker exec -it $(docker ps -q --filter name=trino) trino

你可能不会立即看到 Trino 的提示符,按 ENTER 键即可显示。以下是一些你可以尝试的命令:

SHOW CATALOGS;
SHOW SCHEMAS FROM iceberg;
CREATE SCHEMA iceberg.quickstart_schema;
CREATE TABLE iceberg.quickstart_schema.quickstart_table AS SELECT 1 x;
SELECT * FROM iceberg.quickstart_schema.quickstart_table;

如果在任何时候访问权限被撤销……

polaris \
  --client-id ${CLIENT_ID} \
  --client-secret ${CLIENT_SECRET} \
  privileges \
  catalog \
  revoke \
  --catalog quickstart_catalog \
  --catalog-role quickstart_catalog_role \
  CATALOG_MANAGE_CONTENT

Trino 将失去对该表的访问权限:

SELECT * FROM iceberg.quickstart_schema.quickstart_table;

org.apache.iceberg.exceptions.ForbiddenException: Forbidden: Principal 'quickstart_user' with activated PrincipalRoles '[]' and activated grants via '[quickstart_catalog_role, quickstart_user_role]' is not authorized for op LOAD_TABLE_WITH_READ_DELEGATION

使用 PyIceberg 连接

使用凭据

from pyiceberg.catalog import load_catalog

catalog = load_catalog(
    type='rest',
    uri='http://localhost:8181/api/catalog',
    warehouse='quickstart_catalog',
    scope="PRINCIPAL_ROLE:ALL",
    credential=f"{CLIENT_ID}:{CLIENT_SECRET}",
)

如果使用凭据调用 load_catalog 函数,PyIceberg 会自动向 v1/oauth/tokens 端点请求授权令牌,之后使用该令牌向 Polaris Catalog 证明其身份。

使用令牌

from pyiceberg.catalog import load_catalog
import requests

# Step 1: Get OAuth token
response = requests.post(
    "http://localhost:8181/api/catalog/v1/oauth/tokens",
    auth =(CLIENT_ID, CLIENT_SECRET),
    data = {
        "grant_type": "client_credentials",
        "scope": "PRINCIPAL_ROLE:ALL"
    })
token = response.json()["access_token"]

# Step 2: Load the catalog using the token
catalog = load_catalog(
    type='rest',
    uri='http://localhost:8181/api/catalog',
    warehouse='quickstart_catalog',
    token=token,
)

你可以直接提供授权令牌来使用 load_catalog 函数。当使用外部身份提供方(例如 Google Identity)时,这种方法非常有用。

通过 REST API 连接

要从宿主机访问 Polaris,首先请求一个访问令牌:

export POLARIS_TOKEN=$(curl -s http://polaris:8181/api/catalog/v1/oauth/tokens \
   --resolve polaris:8181:127.0.0.1 \
   --user ${CLIENT_ID}:${CLIENT_SECRET} \
   -d 'grant_type=client_credentials' \
   -d 'scope=PRINCIPAL_ROLE:ALL' | jq -r .access_token)

然后,在访问 Polaris 时,请在 Authorization 请求头中使用该访问令牌:

curl -v http://127.0.0.1:8181/api/management/v1/principal-roles -H "Authorization: Bearer $POLARIS_TOKEN"
curl -v http://127.0.0.1:8181/api/management/v1/catalogs/quickstart_catalog -H "Authorization: Bearer $POLARIS_TOKEN"

后续步骤

docker compose -p polaris \
  -f getting-started/assets/postgres/docker-compose-postgres.yml \
  -f getting-started/jdbc/docker-compose-bootstrap-db.yml \
  -f getting-started/jdbc/docker-compose.yml \
  down

评论

登录后参与评论

正在加载评论…