

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# Open-table 格式支持
<a name="emr-lf-fgac1"></a>

当你 AWS Lake Formation 使用 Spark SQL 读取和写入数据时，亚马逊 EMR 6.15.0 及更高版本支持基于 Hive 表、Apache Iceberg、Apache Hudi 和 Delta Lake 的精细访问控制。Amazon EMR 支持使用 Apache Hudi 进行表、行、列和单元格级别的访问控制。Amazon EMR 6.15.0 及更高版本支持基于 AWS Lake Formation 实现行、列或单元格级精细访问控制。从 EMR 7.12 开始，Apache Hive、Apache Iceberg 和 Delta Lake 表支持使用 Lake Formation 提供的凭据修改表数据的 DML 和 DDL 操作。

本节中的主题介绍如何通过精细访问控制从 EMR Spark 作业或交互式会话中以开放表格格式访问 Lake Formation 注册的表。

## 权限要求
<a name="emr-lf-perm"></a>

### 未在中注册的表 AWS Lake Formation
<a name="emr-lf-tbl-reg"></a>

对于未向注册的表 AWS Lake Formation，作业运行时角色同时访问 Glue 数据 AWS 目录和 Amazon S3 中的基础表数据。这要求任务运行时角色拥有相应的 IAM 权限，可同时执行 Glue AWS 和 Amazon S3 操作。

### 在中注册的表 AWS Lake Formation
<a name="emr-lf-tbl-not-reg"></a>

对于注册到的表 AWS Lake Formation，作业运行时角色访问 AWS Glue 数据目录元数据，而 Lake Formation 提供的临时证书则访问 Amazon S3 中的基础表数据。执行操作所需的 Lake For AWS mation 权限取决于 Spark 任务启动的 Glue 数据目录和 Amazon S3 API 调用，可以总结如下：
+ D@@ **ES** CRIBE 权限允许运行时角色读取数据目录中的表或数据库元数据
+ **ALTER** 权限允许运行时角色修改数据目录中的表或数据库元数据
+ **DROP** 权限允许运行时角色从数据目录中删除表或数据库元数据
+ SE@@ **LECT** 权限允许运行时角色从 Amazon S3 读取表数据
+ INS@@ **ERT** 权限允许运行时角色将表数据写入 Amazon S3
+ **删除**权限允许运行时角色从 Amazon S3 中删除表数据
**注意**  
当 Spark 任务调用 G AWS lue 来检索表元数据并调用 Amazon S3 来检索表数据时，Lake Formation 会延迟评估权限。在 Spark 发出需要缺少权限的 AWS Glue 或 Amazon S3 调用之前，使用权限不足的运行时角色的任务不会失败。

**注意**  
在以下支持的表格矩阵中：  
标记为 “**支持**” 的操作仅使用 Lake Formation 凭据来访问在 Lake Formation 中注册的表的表数据。如果 Lake Formation 权限不足，则操作将不会回退到运行时角色证书。对于未在 Lake Formation 中注册的表，作业运行时角色凭据可以访问表数据。
在 A **mazon S3 位置上标记为 “支持” 且具有 IAM 权限**的操作不会使用 Lake Formation 凭证访问亚马逊 S3 中的基础表数据。要运行这些操作，无论表是否已在 Lake Formation 中注册，任务运行时角色都必须具有访问表数据所必需的 Amazon S3 IAM 权限。

------
#### [ Hive ]


| 操作 | AWS Lake Formation 权限 | Support 状态 | 
| --- | --- | --- | 
| SELECT | SELECT | 支持 | 
| CREATE TABLE | 创建表 | 支持 | 
| CREATE TABLE LIKE | 创建表 | 支持 Amazon S3 位置的 IAM 权限 | 
| CREATE TABLE AS SELECT | 创建表 | 支持 Amazon S3 位置的 IAM 权限 | 
| DESCRIBE TABLE | DESCRIBE | 支持 | 
| SHOW TBLPROPERTIES | DESCRIBE | 支持 | 
| SHOW COLUMNS | DESCRIBE | 支持 | 
| SHOW PARTITIONS | DESCRIBE | 支持 | 
| SHOW CREATE TABLE | DESCRIBE | 支持 | 
| 更改表格 tablename | 选择并更改 | 支持 | 
| 更改餐桌tablename布置位置 | - | 不支持 | 
| 修改表tablename添加分区 | 选择、插入和更改 | 支持 | 
| REPAIR TABLE | 选择并更改 | 支持 | 
| 加载数据 |  | 不支持 | 
| INSERT | 插入和更改 | 支持 | 
| INSERT OVERWRITE | 选择、插入、删除和更改 | 支持 | 
| DROP TABLE | 选择、删除、删除和更改 | 支持 | 
| TRUNCATE TABLE | 选择、插入、删除和更改 | 支持 | 
| DataFrame Writer V1 | 与相应的 SQL 操作相同 | 向现有表追加数据时支持。有关更多信息，请参阅[注意事项和限制](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/emr-serverless-lf-enable-considerations.html) | 
| DataFrame Writer V2 | 与相应的 SQL 操作相同 | 向现有表追加数据时支持。有关更多信息，请参阅[注意事项和限制](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/emr-serverless-lf-enable-considerations.html) | 

------
#### [ Iceberg ]


| 操作 | AWS Lake Formation 权限 | Support 状态 | 
| --- | --- | --- | 
| SELECT | SELECT | 支持 | 
| CREATE TABLE | 创建表 | 支持 | 
| CREATE TABLE LIKE | 创建表 | 支持 Amazon S3 位置的 IAM 权限 | 
| CREATE TABLE AS SELECT | 创建表 | 支持 Amazon S3 位置的 IAM 权限 | 
| 将表格替换为选定内容 | 选择、插入和更改 | 支持 | 
| DESCRIBE TABLE | DESCRIBE | 支持 Amazon S3 位置的 IAM 权限 | 
| SHOW TBLPROPERTIES | DESCRIBE | 支持 Amazon S3 位置的 IAM 权限 | 
| SHOW CREATE TABLE | DESCRIBE | 支持 Amazon S3 位置的 IAM 权限 | 
| ALTER TABLE | 选择、插入和更改 | 支持  | 
| ALTER TABLE SET LOCATION | 选择、插入和更改 | 支持 Amazon S3 位置的 IAM 权限 | 
| 更改表写入顺序依据 | 选择、插入和更改 | 支持 Amazon S3 位置的 IAM 权限 | 
| 更改表写入分发者 | 选择、插入和更改 | 支持 Amazon S3 位置的 IAM 权限 | 
| 更改表重命名表 | CREATE\_TABLE，然后删除 | 支持 | 
| INSERT INTO | 选择、插入和更改 | 支持 | 
| INSERT OVERWRITE | 选择、插入和更改 | 支持 | 
| DELETE | 选择、插入和更改 | 支持 | 
| UPDATE | 选择、插入和更改 | 支持 | 
| MERGE INTO | 选择、插入和更改 | 支持 | 
| DROP TABLE | 选择、删除和删除 | 支持 | 
| DataFrame Writer V1 | - | 不支持 | 
| DataFrame Writer V2 | 与相应的 SQL 操作相同 | 向现有表追加数据时支持。有关更多信息，请参阅[注意事项和限制](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/emr-serverless-lf-enable-considerations.html)。 | 
| 元数据表 | SELECT | 支持。某些表格是隐藏的。有关更多信息，请参阅[注意事项和限制](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/emr-serverless-lf-enable-considerations.html)。 | 
| 存储过程 | - | 支持满足以下条件的表：[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_cn/emr/latest/ManagementGuide/emr-lf-fgac1.html) | 

**Iceberg 的 Spark 配置：**如果要使用 Iceberg 格式，请设置以下配置。将 `{{DB_LOCATION}}` 替换为 Iceberg 表所在的 Amazon S3 路径，并将区域和账户 ID 占位符替换为您自己的值。

```
spark-sql \
--conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions
--conf spark.sql.catalog.spark_catalog=org.apache.iceberg.spark.SparkSessionCatalog 
--conf spark.sql.catalog.spark_catalog.warehouse=s3://{{DB_LOCATION}}
--conf spark.sql.catalog.spark_catalog.catalog-impl=org.apache.iceberg.aws.glue.GlueCatalog 
--conf spark.sql.catalog.spark_catalog.io-impl=org.apache.iceberg.aws.s3.S3FileIO
--conf spark.sql.catalog.spark_catalog.glue.account-id={{ACCOUNT_ID}}
--conf spark.sql.catalog.spark_catalog.glue.id={{ACCOUNT_ID}}
--conf spark.sql.catalog.spark_catalog.client.region={{AWS_REGION}}
```

如果要在早期 EMR 版本上使用 Iceberg 格式，请改为使用以下命令：

```
spark-sql \
--conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions,com.amazonaws.emr.recordserver.connector.spark.sql.RecordServerSQLExtension  
--conf spark.sql.catalog.spark_catalog=org.apache.iceberg.spark.SparkCatalog 
--conf spark.sql.catalog.spark_catalog.warehouse=s3://{{DB_LOCATION}}
--conf spark.sql.catalog.spark_catalog.catalog-impl=org.apache.iceberg.aws.glue.GlueCatalog 
--conf spark.sql.catalog.spark_catalog.io-impl=org.apache.iceberg.aws.s3.S3FileIO  
--conf spark.sql.catalog.spark_catalog.glue.account-id={{ACCOUNT_ID}}
--conf spark.sql.catalog.spark_catalog.glue.id={{ACCOUNT_ID}}
--conf spark.sql.catalog.spark_catalog.client.assume-role.region={{AWS_REGION}}
--conf spark.sql.catalog.spark_catalog.lf.managed=true
```

**示例：**

以下是一些使用 Iceberg 表的示例：

```
-- Create an Iceberg table
CREATE TABLE my_iceberg_table (
    id BIGINT,
    name STRING,
    created_at TIMESTAMP
) USING ICEBERG;

-- Insert data
INSERT INTO my_iceberg_table VALUES (1, 'Alice', current_timestamp());

-- Query the table
SELECT * FROM my_iceberg_table;
```

------
#### [ Hudi ]


| 操作 | AWS Lake Formation 权限 | Support 状态 | 
| --- | --- | --- | 
| SELECT | SELECT | 支持 | 
| CREATE TABLE | 创建表 | 支持 Amazon S3 位置的 IAM 权限 | 
| CREATE TABLE LIKE | 创建表 | 支持 Amazon S3 位置的 IAM 权限 | 
| CREATE TABLE AS SELECT | - | 不支持 | 
| DESCRIBE TABLE | DESCRIBE | 支持 Amazon S3 位置的 IAM 权限 | 
| SHOW TBLPROPERTIES | DESCRIBE | 支持 Amazon S3 位置的 IAM 权限 | 
| SHOW COLUMNS | DESCRIBE | 支持 Amazon S3 位置的 IAM 权限 | 
| SHOW CREATE TABLE | DESCRIBE | 支持 Amazon S3 位置的 IAM 权限 | 
| ALTER TABLE | SELECT | 支持 Amazon S3 位置的 IAM 权限 | 
| INSERT INTO | 选择并更改 | 支持 Amazon S3 位置的 IAM 权限 | 
| INSERT OVERWRITE | 选择并更改 | 支持 Amazon S3 位置的 IAM 权限 | 
| DELETE | - | 不支持 | 
| UPDATE | - | 不支持 | 
| MERGE INTO | - | 不支持 | 
| DROP TABLE | 选择并删除 | 支持 Amazon S3 位置的 IAM 权限 | 
| DataFrame Writer V1 | - | 不支持 | 
| DataFrame Writer V2 | 与相应的 SQL 操作相同 | 支持 Amazon S3 位置的 IAM 权限 | 
| 元数据表 | - | 不支持 | 
| 表维护和实用程序功能 | - | 不支持 | 

**Hudi 的 Spark 配置：**

要在 EMR 7.10 或更高版本上启动 Spark shell，请使用以下命令：

```
spark-sql
--jars /usr/lib/hudi/hudi-spark-bundle.jar \
--conf spark.sql.catalog.spark_catalog=org.apache.spark.sql.hudi.catalog.HoodieCatalog \
--conf spark.sql.extensions=org.apache.spark.sql.hudi.HoodieSparkSessionExtension
```

要在早期 EMR 版本上启动 Spark Shell，请改为使用以下命令：

```
spark-sql
--jars /usr/lib/hudi/hudi-spark-bundle.jar \
--conf spark.serializer=org.apache.spark.serializer.KryoSerializer \
--conf spark.sql.catalog.spark_catalog=org.apache.spark.sql.hudi.catalog.HoodieCatalog \
--conf spark.sql.extensions=org.apache.spark.sql.hudi.HoodieSparkSessionExtension,com.amazonaws.emr.recordserver.connector.spark.sql.RecordServerSQLExtension  \
--conf spark.sql.catalog.spark_catalog.lf.managed=true
```

**示例：**

以下是一些使用 Hudi 表的示例：

```
-- Create a Hudi table
CREATE TABLE my_hudi_table (
    id BIGINT,
    name STRING,
    created_at TIMESTAMP
) USING HUDI
TBLPROPERTIES (
    'type' = 'cow',
    'primaryKey' = 'id'
);

-- Insert data
INSERT INTO my_hudi_table VALUES (1, 'Alice', current_timestamp());

-- Query the latest snapshot
SELECT * FROM my_hudi_table;
```

要查询写入时复制表的最新快照，请执行以下操作：

```
SELECT * FROM {{my_hudi_cow_table}}
```

```
spark.read.table("{{my_hudi_cow_table}}")
```

要查询 `MOR` 表的最新压缩数据，您可以查询以 `_ro` 为后缀的读取优化表：

```
SELECT * FROM {{my_hudi_mor_table}}_ro
```

```
spark.read.table("{{my_hudi_mor_table}}_ro")
```

------
#### [ Delta Lake ]


| 操作 | AWS Lake Formation 权限 | Support 状态 | 
| --- | --- | --- | 
| SELECT | SELECT | 支持 | 
| CREATE TABLE | 创建表 | 支持 | 
| CREATE TABLE LIKE | - | 不支持 | 
| CREATE TABLE AS SELECT | 创建表 | 支持  | 
| 将表格替换为选定内容 | 选择、插入和更改 | 支持 | 
| DESCRIBE TABLE | DESCRIBE | 支持 Amazon S3 位置的 IAM 权限 | 
| SHOW TBLPROPERTIES | DESCRIBE | 支持 Amazon S3 位置的 IAM 权限 | 
| SHOW COLUMNS | DESCRIBE | 支持 Amazon S3 位置的 IAM 权限 | 
| SHOW CREATE TABLE | DESCRIBE | 支持 Amazon S3 位置的 IAM 权限 | 
| ALTER TABLE | 选择并插入  | 支持  | 
| ALTER TABLE SET LOCATION | 选择并插入  | 支持 Amazon S3 位置的 IAM 权限 | 
| 按以下方式更改表tablename集群 | 选择并插入 | 支持 Amazon S3 位置的 IAM 权限 | 
| 更改表tablename添加约束 | 选择并插入 | 支持 Amazon S3 位置的 IAM 权限 | 
| 更改表格tablename删除约束 | 选择并插入 | 支持 Amazon S3 位置的 IAM 权限 | 
| INSERT INTO | 选择并插入 | 支持 | 
| INSERT OVERWRITE | 选择并插入 | 支持 | 
| DELETE | 选择并插入 | 支持 | 
| UPDATE | 选择并插入 | 支持 | 
| MERGE INTO | 选择并插入 | 支持 | 
| DROP TABLE | 选择、删除和删除 | 支持 | 
| DataFrame Writer V1 | - | 不支持 | 
| DataFrame Writer V2 | 与相应的 SQL 操作相同 | 支持  | 
| 表维护和实用程序功能 | - | 不支持 | 

**三角洲湖的 Spark 配置：**

要在 EMR 7.10 及更高版本上将 Delta Lake 和 Lake Formation 结合使用，请运行以下命令：

```
spark-sql \
   --conf spark.sql.extensions=io.delta.sql.DeltaSparkSessionExtension \
  --conf spark.sql.catalog.spark_catalog=org.apache.spark.sql.delta.catalog.DeltaCatalog
```

要在 EMR 6.15 至 7.9 版本中将 Delta Lake 和 Lake Formation 结合使用，请运行以下命令

```
spark-sql \
  --conf spark.sql.extensions=io.delta.sql.DeltaSparkSessionExtension,com.amazonaws.emr.recordserver.connector.spark.sql.RecordServerSQLExtension \
  --conf spark.sql.catalog.spark_catalog=org.apache.spark.sql.delta.catalog.DeltaCatalog \
  --conf spark.sql.catalog.spark_catalog.lf.managed=true
```

如果希望 Lake Form 使用记录服务器来管理 Spark 目录，请将 `spark.sql.catalog.<managed_catalog_name>.lf.managed` 设置为 true。

**示例：**

以下是一些使用 Delta Lake 表格的示例：

```
-- Create a Delta Lake table
CREATE TABLE my_delta_table (
    id BIGINT,
    name STRING,
    created_at TIMESTAMP
) USING DELTA;

-- Insert data
INSERT INTO my_delta_table VALUES (1, 'Alice', current_timestamp());

-- Query the table
SELECT * FROM my_delta_table;

-- Update data
UPDATE my_delta_table SET name = 'Alice Smith' WHERE id = 1;

-- Merge data
MERGE INTO my_delta_table AS target
USING (SELECT 2 as id, 'Bob' as name, current_timestamp() as created_at) AS source
ON target.id = source.id
WHEN MATCHED THEN UPDATE SET *
WHEN NOT MATCHED THEN INSERT *;
```

**在 AWS Glue 数据目录中创建 Delta Lake 表**

带有 Lake Formation 的 Amazon EMR 不支持 7.12 之前的 EMR 版本中的 DDL 命令和 Delta 表创建。按照以下步骤在 Glue 数据 AWS 目录中创建表。

1. 使用以下示例创建 Delta 表。确保 S3 位置存在。

   ```
   spark-sql \
   --conf "spark.sql.extensions=io.delta.sql.DeltaSparkSessionExtension" \
   --conf "spark.sql.catalog.spark_catalog=org.apache.spark.sql.delta.catalog.DeltaCatalog"
   
   > CREATE DATABASE if not exists {{<DATABASE_NAME>}} LOCATION 's3://{{<S3_LOCATION>}}/transactionaldata/native-delta/{{<DATABASE_NAME>}}/';
   > CREATE TABLE {{<TABLE_NAME>}} (x INT, y STRING, z STRING) USING delta;
   > INSERT INTO {{<TABLE_NAME>}} VALUES (1, 'a1', 'b1');
   ```

1. 要查看您的表格的详细信息，请转至[https://console.aws.amazon.com/glue/](https://console.aws.amazon.com/glue/)。

1. 在左侧导航栏中，展开**数据目录**，选择**表**，然后选择您创建的表。在 “**架构”** 下，您应该会看到使用 Spark 创建的 Delta 表将所有列存储在 Glue `array<string>` 中的数据类型 AWS 中。

1. 要在 Lake Formation 中定义列级和单元格级筛选条件，请从架构中删除 `col` 列，然后添加表架构中的列。在此示例中，添加 `x` `y`、和 `z` 列。

------

使用此功能，您可以对写入时复制的表运行快照查询，用于在指定的提交或压缩时刻查询表的最新快照。目前，Lake Formation-enabled Amazon EMR 集群必须检索 Hudi 的提交时间列才能执行增量查询和时空旅行查询。但不支持 Spark 的 `timestamp as of` 语法和 `Spark.read()` 函数。正确的语法是 `select * from table where _hoodie_commit_time <= point_in_time`。有关更多信息，请参阅 [Hudi 表上的时间点 Time-Travel 查询](https://cwiki.apache.org/confluence/display/HUDI/RFC+-+07+%3A+Point+in+time+Time-Travel+queries+on+Hudi+table)。

**注意**  
Lake Formation 集群上的读取性能可能会因不支持的优化而变慢。这些功能包括基于 Hudi 元数据的文件列表和数据跳过。我们建议您测试应用程序的性能，以确保其符合您的要求。