使用 Polaris
使用 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_CONTENTSpark 将失去对该表的访问权限:
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_CONTENTTrino 将失去对该表的访问权限:
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"后续步骤
- 访问使用 Keycloak 作为外部身份提供商。
- 访问将 Polaris 与遥测工具配合使用。
- 访问为生产环境配置 Polaris。
- 关于使用 Spark 与 Jupyter Notebook 的入门体验,可参见此处的文档。
- 若要关闭本地部署的 Polaris 服务器并清理所有相关的 Docker 容器,请运行下面列出的命令。云部署在其部署页面上提供了各自的终止命令,而在 Gradle 上运行的 Polaris 会在 Gradle 进程终止时一并终止。
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评论
登录后参与评论
KnowForge