

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

# 将 Amazon EMR 与 AWS Lake Formation
<a name="emr-lake-formation"></a>

AWS Lake Formation 是一项托管服务，可帮助您发现、分类、清理和保护亚马逊简单存储服务 (S3) Simple Service 数据湖中的数据。Lake Formation 在列、行或单元级别提供对 Glue 数据目录中的数据库和表的精 AWS 细访问。有关更多信息，请参阅[什么是 AWS Lake Formation？](https://docs.aws.amazon.com/lake-formation/latest/dg/what-is-lake-formation.html)

使用 Amazon EMR 发行版本 6.7.0 及更高版本，您可以将基于 Lake Formation 的访问控制应用于您提交到 Amazon EMR 集群的 Spark、Hive 和 Presto 作业。要与 Lake Formation 集成，您必须创建具有*运行时角色*的 EMR 集群。运行时角色是您与 Amazon EMR 作业或查询关联的 AWS Identity and Access Management (IAM) 角色。然后，Amazon EMR 使用此角色访问 AWS 资源。有关更多信息，请参阅 [Amazon EMR 步骤的运行时角色](emr-steps-runtime-roles.md)。

## Amazon EMR 如何与 Lake Formation 结合使用
<a name="how-emr-lf-works"></a>

将亚马逊 EMR 与 Lake Formation 集成后，您可以使用 [`Step`API](https://docs.aws.amazon.com/emr/latest/APIReference/API_Step.html) 或 AI Studio 对亚马逊 EMR 集群执行查询。 SageMaker 然后，Lake Formation 通过 Amazon EMR 的临时凭证提供对数据的访问。此过程称为凭证售卖。有关更多信息，请参阅[什么是 AWS Lake Formation？](https://docs.aws.amazon.com/lake-formation/latest/dg/what-is-lake-formation.html)

以下是 Amazon EMR 如何访问受 Lake Formation 安全策略保护的数据的高级概览。

![\[Amazon EMR 如何访问受 Lake Formation 安全策略保护的数据\]](http://docs.aws.amazon.com/zh_cn/emr/latest/ManagementGuide/images/lf-emr-security.png)


1. 用户对 Lake Formation 中的数据提交 Amazon EMR 查询。

1. Amazon EMR 从 Lake Formation 请求临时凭证以授予用户数据访问权限。

1. Lake Formation 返回临时凭证。

1. Amazon EMR 发送查询请求以从 Amazon S3 检索数据。

1. Amazon EMR 接收来自 Amazon S3 的数据，进行筛选，然后根据用户在 Lake Formation 中定义的用户权限返回结果。

有关将用户和组添加到 Lake Formation 策略中的更多信息，请参阅[授予数据目录权限](https://docs.aws.amazon.com/lake-formation/latest/dg/granting-catalog-permissions.html)。

## 先决条件
<a name="prerequisites"></a>

集成 Amazon EMR 和 Lake Formation 之前，您必须满足以下要求：
+ 在 Amazon EMR 集群上开启运行时角色授权。
+ 使用 AWS Glue 数据目录作为元数据存储。
+ 在 Lake For AWS mation 中定义和管理访问 Glue 数据目录中数据库、表和列的权限。有关更多信息，请参阅[什么是 AWS Lake Formation？](https://docs.aws.amazon.com/lake-formation/latest/dg/what-is-lake-formation.html)

# 使用 Lake Formation 进行精细访问控制
<a name="lake-formation-fine-grained-access"></a>

亚马逊 EMR 6.15.0 及更高版本支持基于 Lake Formation 的行、列或单元格级别的精细访问控制。 AWS 本节中的主题涵盖如何从 EMR Spark 作业或交互式会话中访问受 Lake Formation 保护的 Glue Data Catalog 表并实现精细访问控制。

# 使用 Amazon EMR 启用 Lake Formation
<a name="emr-lf-enable"></a>

在 Amazon EMR 6.15.0 及更高版本中，当您在访问 G AWS lue 数据目录中数据的 EC2 集群上在 Amazon EMR 上运行 Spark 作业时，您可以使用 AWS Lake Formation 对基于 Hudi、Iceberg 或 Delta Lake 的表应用表、行、列和单元级别的权限。

在本节中，我们将介绍如何创建安全配置和设置 Lake Formation 以与 Amazon EMR 结合使用。还将介绍如何使用您为 Lake Formation 创建的安全配置启动集群。

## 步骤 1：为 EMR 集群设置运行时角色
<a name="emr-lf-launch-cluster"></a>

要为 EMR 集群使用运行时角色，您必须创建安全配置。利用安全配置，您可以在集群中应用一致的安全性、授权和身份验证选项。

1. 使用以下安全配置创建名为 `lf-runtime-roles-sec-cfg.json` 的文件。

   ```
   {
       "AuthorizationConfiguration": {
           "IAMConfiguration": {
               "EnableApplicationScopedIAMRole": true,
               "ApplicationScopedIAMRoleConfiguration": {
                   "PropagateSourceIdentity": true
               }
           },
           "LakeFormationConfiguration": {
               "AuthorizedSessionTagValue": "Amazon EMR"
           }
       },
       "EncryptionConfiguration": {
   	    "EnableAtRestEncryption": false,
               "EnableInTransitEncryption": true,
               "InTransitEncryptionConfiguration": {
               "TLSCertificateConfiguration": {<certificate-configuration>}
           }
       }
   }
   ```

   以下示例说明了如何在 Amazon S3 中使用包含证书的 zip 文件进行证书配置：
   + Amazon S3 中包含证书的 zip 文件用作密钥提供程序。（有关证书要求，请参阅 [为通过 Amazon EMR 加密来加密传输中的数据提供凭证](emr-encryption-enable.md#emr-encryption-certificates)。）

   ```
   "TLSCertificateConfiguration": {
   	"CertificateProviderType": "PEM",       
   	"S3Object": "s3://MyConfigStore/artifacts/MyCerts.zip"
    }
   ```

   以下示例说明了如何使用自定义密钥提供程序进行证书配置：
   + 使用自定义密钥提供程序。（有关证书要求，请参阅 [为通过 Amazon EMR 加密来加密传输中的数据提供凭证](emr-encryption-enable.md#emr-encryption-certificates)。）

   ```
   "TLSCertificateConfiguration": {
   	"CertificateProviderType": "Custom",
   	"S3Object": "s3://MyConfig/artifacts/MyCerts.jar",
   	"CertificateProviderClass": "com.mycompany.MyCertProvider"
       }
   ```

1. 接下来，为确保会话标签可以授权 Lake Formation，请将 `LakeFormationConfiguration/AuthorizedSessionTagValue` 属性设置为 `Amazon EMR`。

1. 使用以下命令创建 Amazon EMR 安全配置。

   ```
   aws emr create-security-configuration \
   --name 'iamconfig-with-iam-lf' \
   --security-configuration file://lf-runtime-roles-sec-cfg.json
   ```

   或者，您可以使用 [Amazon EMR 控制台](https://console.aws.amazon.com//emr)创建具有自定义设置的安全配置。

## 第 2 步：启动一个 Amazon EMR 集群
<a name="emr-lf-launch-cluster"></a>

现在您可以使用您在上一步中创建的安全配置启动 EMR 集群。有关安全配置的更多信息，请参阅 [使用安全配置设置 Amazon EMR 集群安全性](emr-security-configurations.md) 和 [Amazon EMR 步骤的运行时角色](emr-steps-runtime-roles.md)。

## 步骤 3：使用 Amazon EMR 运行时系统角色设置基于 Lake Formation 的列、行或单元格级别权限
<a name="emr-lf-fgac-perms"></a>

要使用 Lake Formation 在列、行或单元格级别应用精细访问控制，Lake Formation 的数据湖管理员必须将 `Amazon EMR` 设置为会话标签配置的值 `AuthorizedSessionTagValue`。Lake Formation 使用该会话标签来授权调用者并提供对数据湖的访问权限。您可以在 Lake Formation 控制台的**应用程序集成设置**部分设置此会话标签。*123456789012*用你自己的 AWS 账户 身份证替换。

## 第 4 步：为亚马逊 EMR 运行时角色配置 AWS Glue 和 Lake Formation 授权
<a name="emr-lf-trust-policy"></a>

要继续使用亚马逊 EMR 运行时角色设置基于 Lake Formation 的访问控制，您必须为亚马逊 EMR 运行时角色配置 Gl AWS ue 和 Lake Formation 授权。要让您的 IAM 运行时角色与 Lake Formation 进行交互，请使用 `lakeformation:GetDataAccess` 和 `glue:Get*` 向其授予访问权限。

Lake For AWS mation 权限控制对 Glue 数据目录资源、Amazon S3 位置以及这些位置的基础数据的访问权限。IAM 权限控制对 Lake Formation 和 AWS Glue APIs 以及资源的访问。尽管您可能拥有访问数据目录 (SELECT) 中的表的 Lake Formation 权限，但如果没有 `glue:Get*` API 的 IAM 权限，您的操作将失败。有关 Lake Formation 访问控制的更多信息，请参阅 [Lake Formation access control overview](https://docs.aws.amazon.com/lake-formation/latest/dg/lf-permissions-overview.html)（Lake Formation 访问控制概述）。

1.  创建 `emr-runtime-roles-lake-formation-policy.json` 文件并输入以下内容。

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Sid": "LakeFormationManagedAccess",
         "Effect": "Allow",
         "Action": [
           "lakeformation:GetDataAccess",
           "glue:Get*",
           "glue:Create*",
           "glue:Update*"
         ],
         "Resource": [
           "*"
         ]
       }
     ]
   }
   ```

------

1. 创建相关的 IAM policy。

   ```
   aws iam create-policy \
   --policy-name emr-runtime-roles-lake-formation-policy \
   --policy-document file://emr-runtime-roles-lake-formation-policy.json
   ```

1. 要将此策略分配给您的 IAM 运行时角色，请按照[管理 AWS Lake Formation 权限](https://docs.aws.amazon.com/lake-formation/latest/dg/managing-permissions.html)中的步骤操作。

现在您可以使用运行时角色和 Lake Formation 来应用表和列级别权限。您还可以使用源身份来控制操作和监控操作 AWS CloudTrail。

对于您计划用作运行时角色的每个 IAM 角色，设置以下信任策略，将 `EMR_EC2_DefaultRole` 替换为您的实例配置文件角色。要修改 IAM 角色的信任策略，请参阅[修改角色信任策略](https://docs.aws.amazon.com//IAM/latest/UserGuide/roles-managingrole-editing-console.html)。

```
{
   "Sid":"AllowAssumeRole",
   "Effect":"Allow",
   "Principal":{
     "AWS":"arn:aws:iam::<AWS_ACCOUNT_ID>:role/EMR_EC2_DefaultRole"
   },
   "Action":[
        "sts:AssumeRole",
        "sts:TagSession"
       ]
 }
```

有关详细示 end-to-end例，请参阅 [Amazon EMR 步骤的运行时角色简介](https://aws.amazon.com/blogs/big-data/introducing-runtime-roles-for-amazon-emr-steps-use-iam-roles-and-aws-lake-formation-for-access-control-with-amazon-emr/)。<a name="iceberg-with-lake-formation-spark-catalog-integration-lf-ec2"></a>

有关如何与 Iceberg 和 AWS Glue 数据目录集成以实现多目录层次结构的信息，请参阅[在 Glue 数据目录中配置 Spark 以访问多目录层次结构 AWS 。](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-multi-catalog.html#emr-lakehouse-using-spark-access)

# 开放表格式支持
<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 ]

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/emr/latest/ManagementGuide/emr-lf-fgac1.html)

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

[\[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 ]

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/emr/latest/ManagementGuide/emr-lf-fgac1.html)

**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;
```

要查询 copy-on-write表的最新快照，请执行以下操作：

```
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 ]

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/emr/latest/ManagementGuide/emr-lf-fgac1.html)

**三角洲湖的 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` 列。

------

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

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

# 在 Amazon EMR 中使用 Glue Data Catalog 视图
<a name="SECTION-jobs-glue-data-catalog-views-ec2"></a>

**注意**  
在 Amazon EMR 7.10.0 及更高[版本中，可以创建和管理 AWS 用于 EC2 上的 EMR](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-7100-release.html) 的 Glue 数据目录视图。

您可以在 AWS Glue 数据目录中创建和管理视图，以便与 EC2 上的 EMR 配合使用。这些视图通常被称为 AWS Glue 数据目录视图。这些视图非常有用，因为它们支持多个 SQL 查询引擎，因此您可以跨不同的 AWS 服务（例如 EC2 上的 EMR 和 Amazon Redshift 上的 EMR 和 Amazon Redshift）访问相同的视图。 Amazon Athena

通过在数据目录中创建视图，您可以在中使用资源授予和基于标签的访问控制 AWS Lake Formation 来授予对其的访问权限。使用这种访问控制方法，您无需为创建视图时引用的表配置其他访问权限。这种授予权限的方法称为定义者语义，这些视图称为定义者视图。有关 Lake Formation 中访问控制的更多信息，请参阅[《Lake Formation 开发者指南》中的授予和撤消数据目录资源的权限](https://docs.aws.amazon.com/lake-formation/latest/dg/granting-catalog-permissions.html)。 AWS 

数据目录视图对于以下用例非常实用：
+ **精细访问控制**：您可以创建一个视图，根据用户所需的权限来限制数据访问。例如，您可以使用 Data Catalog 中的视图来防止不在 HR 部门工作的员工查看个人身份信息 (PII)。
+ **完整视图定义**：通过对 Data Catalog 中的视图应用筛选条件，可确保 Data Catalog 中视图内的数据记录始终完整。
+ **增强安全性**：用于创建视图的查询定义必须完整。这种优势意味着 Data Catalog 中的视图不容易受到恶意行为者的 SQL 命令的影响。
+ **简单共享数据**-无需移动数据即可与其他 AWS 账户共享数据。有关更多信息，请参阅 [Lake Formation 中的跨账户数据共享](https://docs.aws.amazon.com/lake-formation/latest/dg/cross-account-permissions.html)。

## 创建 Data Catalog 视图
<a name="SECTION-jobs-glue-data-catalog-views-create-ec2"></a>

创建 Data Catalog 视图的方法有很多种。其中包括使用 AWS CLI 或 Spark SQL。以下是一些示例。

------
#### [ Using SQL ]

下面展示了创建 Data Catalog 视图的语法。注意 `MULTI DIALECT` 视图类型。这将 Data Catalog 视图与其他视图区分开来。`SECURITY` 谓词指定为 `DEFINER`。这表示带有 `DEFINER` 语义的 Data Catalog 视图。

```
CREATE [ OR REPLACE ] PROTECTED MULTI DIALECT VIEW [IF NOT EXISTS] view_name
[(column_name [COMMENT column_comment], ...) ]
[ COMMENT view_comment ]
[TBLPROPERTIES (property_name = property_value, ... )]
SECURITY DEFINER
AS query;
```

以下是 `CREATE` 语句示例，其语法如下：

```
CREATE PROTECTED MULTI DIALECT VIEW catalog_view
SECURITY DEFINER
AS
SELECT order_date, sum(totalprice) AS price
FROM source_table
GROUP BY order_date
```

您还可以使用 SQL 在试运行模式下创建视图以测试视图创建，而无需实际创建资源。使用此选项会导致 “试运行”，该试运行可以验证输入，如果验证成功，则返回将代表视图的 Glue AWS 表对象的 JSON。在这种情况下，不会创建实际视图。

```
CREATE [ OR REPLACE ] PROTECTED MULTI DIALECT VIEW view_name
SECURITY DEFINER 
[ SHOW VIEW JSON ]
AS view-sql
```

------
#### [ Using the AWS CLI ]

**注意**  
使用 CLI 命令时，不会解析用于创建视图的 SQL。这可能会导致创建视图，但查询不成功。创建视图之前，请务必测试 SQL 语法。

您可以使用以下 CLI 命令创建视图：

```
aws glue create-table --cli-input-json '{
  "DatabaseName": "database",
  "TableInput": {
    "Name": "view",
    "StorageDescriptor": {
      "Columns": [
        {
          "Name": "col1",
          "Type": "data-type"
        },
        ...
        {
          "Name": "col_n",
          "Type": "data-type"
        }
      ],
      "SerdeInfo": {}
    },
    "ViewDefinition": {
      "SubObjects": [
        "arn:aws:glue:aws-region:aws-account-id:table/database/referenced-table1",
        ...
        "arn:aws:glue:aws-region:aws-account-id:table/database/referenced-tableN",
       ],
      "IsProtected": true,
      "Representations": [
        {
          "Dialect": "SPARK",
          "DialectVersion": "1.0",
          "ViewOriginalText": "Spark-SQL",
          "ViewExpandedText": "Spark-SQL"
        }
      ]
    }
  }
}'
```

------

## 支持的视图操作
<a name="SECTION-jobs-glue-data-catalog-views-supported-operations-ec2"></a>

以下命令片段展示了使用 Data Catalog 视图的各种方法：
+ **CREATE VIEW**

  创建数据目录视图。以下示例演示如何根据现有表格创建视图：

  ```
  CREATE PROTECTED MULTI DIALECT VIEW catalog_view 
  SECURITY DEFINER AS SELECT * FROM my_catalog.my_database.source_table
  ```
+ **ALTER VIEW**

  可用语法：
  + `ALTER VIEW view_name [FORCE] ADD DIALECT AS query`
  + `ALTER VIEW view_name [FORCE] UPDATE DIALECT AS query`
  + `ALTER VIEW view_name DROP DIALECT`

  您可以使用 `FORCE ADD DIALECT` 选项，根据新的引擎方言强制更新架构和子对象。请注意，如果不同时使用 `FORCE` 更新其他引擎方言，这样做可能会导致查询错误。示例如下：

  ```
  ALTER VIEW catalog_view FORCE ADD DIALECT
  AS
  SELECT order_date, sum(totalprice) AS price
  FROM source_table
  GROUP BY orderdate;
  ```

  下例显示了如何更改视图来更新方言：

  ```
  ALTER VIEW catalog_view UPDATE DIALECT AS 
  SELECT count(*) FROM my_catalog.my_database.source_table;
  ```
+ **DESCRIBE VIEW**

  描述视图的可用语法：
  + `SHOW COLUMNS {FROM|IN} view_name [{FROM|IN} database_name]`— 如果用户拥有描述视图所需的 AWS Glue 和 Lake Formation 权限，则他们可以列出这些列。下面显示了几个用于显示列的示例命令：

    ```
    SHOW COLUMNS FROM my_database.source_table;    
    SHOW COLUMNS IN my_database.source_table;
    ```
  + `DESCRIBE view_name`— 如果用户具有描述视图所需的 AWS Glue 和 Lake Formation 权限，则他们可以列出视图中的列及其元数据。
+ **DROP VIEW**

  可用语法：
  + `DROP VIEW [ IF EXISTS ] view_name`

    以下示例显示了 `DROP` 语句，该语句用于在删除视图之前测试视图是否存在：

    ```
    DROP VIEW IF EXISTS catalog_view;
    ```
+ **显示创建视图**
  + `SHOW CREATE VIEW view_name`：显示创建指定视图的 SQL 语句。以下示例演示如何创建数据目录视图：

    ```
    SHOW CREATE TABLE my_database.catalog_view;
    CREATE PROTECTED MULTI DIALECT VIEW my_catalog.my_database.catalog_view (
      net_profit,
      customer_id,
      item_id,
      sold_date)
    TBLPROPERTIES (
      'transient_lastDdlTime' = '1736267222')
    SECURITY DEFINER AS SELECT * FROM
    my_database.store_sales_partitioned_lf WHERE customer_id IN (SELECT customer_id from source_table limit 10)
    ```
+ **SHOW VIEWS**

  列出目录中的所有视图，例如常规视图、多方言视图 (MDV) 和没有 Spark 方言的 MDV。可用语法如下：
  + `SHOW VIEWS [{ FROM | IN } database_name] [LIKE regex_pattern]`:

    下面显示了用于显示视图的示例命令：

    ```
    SHOW VIEWS IN marketing_analytics LIKE 'catalog_view*';
    ```

有关创建和配置数据目录视图的更多信息，请参阅《 AWS Lake Formation 开发人员指南》中的 B [AWS uilding Glue 数据目录视图](https://docs.aws.amazon.com/lake-formation/latest/dg/working-with-views.html)。

## 查询 Data Catalog 视图
<a name="SECTION-jobs-glue-data-catalog-views-querying-ec2"></a>

 创建数据目录视图后，您可以使用启用了 AWS Lake Formation 精细访问控制的 Amazon EMR Spark 任务对其进行查询。作业运行时角色必须拥有对 Data Catalog 视图的 Lake Formation `SELECT` 权限。您无需授予对视图中引用的基础表的访问权限。

完成所有设置后，就可以查询视图。例如，在 EMR Studio 中创建 Amazon EMR 应用程序后，您可以运行以下查询来访问视图。

```
SELECT * from my_database.catalog_view LIMIT 10;
```

一个有用的功能是 `invoker_principal`。它返回 EMRS 作业运行时角色的唯一标识符。这可用于根据调用主体控制视图输出。您可以使用它在视图中添加一个条件，以便根据调用角色优化查询结果。作业运行时角色必须拥有执行 `LakeFormation:GetDataLakePrincipal` IAM 操作的权限才能使用此函数。

```
select invoker_principal();
```

例如，您可以将此函数添加到 `WHERE` 子句以优化查询结果。

## 注意事项和限制
<a name="SECTION-jobs-glue-data-catalog-views-considerations-ec2"></a>

创建 Data Catalog 视图时，以下内容适用：
+ 只能使用 Amazon EMR 7.10 及更高版本创建 Data Catalog 视图。
+ Data Catalog 视图定义者必须拥有对视图访问的基础基表的 `SELECT` 访问权限。如果特定基表对定义者角色施加了任何 Lake Formation 筛选条件，则创建 Data Catalog 视图将失败。
+ 在 Lake Formation 中，基表不得具有 `IAMAllowedPrincipals` 数据湖权限。如果存在，则会出现错误 “*多方言视图” 只能引用没有 IAMAllowed委托人权限的表*。
+ 该表的 Amazon S3 位置必须注册为 Lake Formation 数据湖位置。如果该表未注册，则会出现错误*多方言视图只能引用 Lake Formation 托管表*。有关如何在 Lake Formation 中注册亚马逊 S3 营业地点的信息，请参阅 AWS Lake Formation 开发者指南中的[注册亚马逊 S3 营业地点](https://docs.aws.amazon.com/lake-formation/latest/dg/register-location.html)。
+ 只能创建 `PROTECTED` 数据目录视图。不支持 `UNPROTECTED` 视图。
+ 您不能在数据目录视图定义中引用其他 AWS 账户中的表。也不能引用不同区域中同一账户中的表。
+ 要跨账户或区域共享数据，必须使用 Lake Formation 资源链接跨账户和跨区域共享整个视图。
+ 不支持用户定义的函数 (UDFs)。
+ 您可以使用基于 Iceberg 表的视图。还支持开放式表格格式 Apache Hudi 和 Delta Lake。
+ 不能在数据目录视图中引用其他视图。
+  AWS Glue 数据目录视图架构始终使用小写形式存储。例如，如果使用 DDL 语句创建包含名为 `Castle` 的列的 Glue Data Catalog 视图，则在 Glue Data Catalog 中创建的列将被小写为 `castle`。如果您随后将 DML 查询中的列名指定为 `Castle` 或 `CASTLE`，EMR Spark 会将名称转换为小写，以便运行查询。但是列标题会使用您在查询中指定的大小写形式显示。

  如果希望在 DML 查询中指定的列名与 Glue Data Catalog 中的列名不匹配时查询失败，您可以设置 `spark.sql.caseSensitive=true`。

# 将 Amazon EMR 与 Lake Formation 结合使用时的注意事项
<a name="emr-lf-limitations-cont"></a>

将 Amazon EMR 与 Lake Formation 结合使用已在所有[可用区域](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-region.html)推出。

## Amazon EMR 7.9 及更早版本与 Lake Formation 结合使用时的注意事项
<a name="emr-lf-limitations-early"></a>

在 EMR 7.9 及更早 AWS Lake Formation 版本上使用时，请考虑以下几点。
+ 行、列和单元格级别的[精细访问控制](emr-lf-enable.md#emr-lf-fgac-perms)在 Amazon EMR 6.15 及更高版本的集群上可用。
+ 具有表访问权限的用户可以访问该表的所有属性。如果您对表具有基于 Lake Formation 的访问控制，则请查看该表以确保属性不包含任何敏感数据或信息。
+ 当 Spark 收集表统计数据时，带有 Lake Formation 的 Amazon EMR 集群不支持 Spark 回退到 HDFS。这通常有助于优化查询性能。
+ 通过不受监管的 Apache Spark 表支持基于 Lake Formation 的访问控制的操作包括 `INSERT INTO` 和 `INSERT OVERWRITE`。
+ 通过 Apache Spark 和 Apache Hive 支持基于 Lake Formation 的访问控制的操作包括 `SELECT`、`DESCRIBE`、`SHOW DATABASE`、`SHOW TABLE`、`SHOW COLUMN` 和 `SHOW PARTITION`。
+ Amazon EMR 不支持对以下基于 Lake Formation 的操作进行访问控制：
  + 写入受监管表
  + Amazon EMR 不支持 `CREATE TABLE`。Amazon EMR 6.10.0 及更高版本支持 `ALTER TABLE`。
  + 除 `INSERT` 命令之外的 DML 语句。
+ 使用和不使用基于 Lake Formation 的访问控制的同一查询之间存在性能差异。
+ 您只能将 Amazon EMR 与 Lake Formation 结合使用来执行 Spark 作业。
+ Glue Data Catalog 中的多目录层次结构不支持可信身份传播。有关更多信息，请参阅 [AWS Glue 数据目录中的使用多目录层次结构](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-multi-catalog.html)。

## Amazon EMR 7.10 及更高版本与 Lake Formation 结合使用时的注意事项
<a name="emr-lf-limitations"></a>

在 EMR 7.10 及更高版本中使用 Amazon AWS Lake Formation EMR 时，请考虑以下几点。
+ Amazon EMR 仅支持通过 Lake Formation 对 Apache Hive、Apache Iceberg、Apache Delta 和 Apache Hudi 表进行精细访问控制。Apache Hive 格式包括 Parquet、ORC 和 xSV CSV。
+ 对于启用 Lake Formation 的应用程序，Spark 日志会分两组写入 Amazon S3：系统空间日志和用户空间日志。系统空间日志可能包含敏感信息，例如完整的表结构。为了保护这些数据，Amazon EMR 将系统空间日志与用户空间日志存储在不同的位置。强烈建议账户管理员不要授予用户访问系统空间日志的权限。
+ 如果您向 Lake Formation 注册表位置，则数据访问将完全由用于注册的角色的权限控制，而不是由 Amazon EMR 作业运行时角色控制。如果注册角色配置错误，尝试访问该表的作业将会失败。
+ 您不能为 Lake Formation 作业关闭 `DynamicResourceAllocation`。
+ 您只能将 Lake Formation 与 Spark 作业结合使用。
+ 将 Amazon EMR 与 Lake Formation 结合使用在整个作业中仅支持单个 Spark 会话。
+ 将 Amazon EMR 与 Lake Formation 结合使用仅支持通过资源链接共享的跨账户表查询。
+ 不支持以下项：
  + 弹性分布式数据集（RDD）
  + Spark 流
  + 使用 Lake Formation 授予的权限写入
  + 嵌套列的访问控制
+ Amazon EMR 阻止可能破坏系统驱动程序完全隔离的功能，包括：
  + UDTs、Hive UDFs 以及任何涉及自定义类的用户定义函数
  + 自定义数据来源
  + 为 Spark 扩展、连接器或元存储提供额外的 jar
  + `ANALYZE TABLE` 命令
+ 为了强制执行访问控制，`EXPLAIN PLAN` 和 DDL 操作（如 `DESCRIBE TABLE`）不会公开受限信息。
+ Amazon EMR 限制访问启用 Lake Formation 的应用程序上的系统驱动程序 Spark 日志。由于系统驱动程序以提升的权限运行，因此系统驱动程序生成的事件和日志可能包含敏感信息。为防止未经授权的用户或代码访问此敏感数据，Amazon EMR 禁止访问系统驱动程序日志。

  系统配置文件日志始终保存在托管存储中：这是一项强制性设置，无法禁用。这些日志使用客户托管 KMS 密钥或托管 KMS 密钥 AWS 进行安全存储和加密。

  如果您的 Amazon EMR 应用程序位于带有 Amazon S3 的 VPC 终端节点的私有子网中，并且您附加了终端节点策略来控制访问权限，那么在您的任务可以将日志数据发送到 AWS 托管 Amazon S3 之前，您必须在 VPC 策略中包含[托管存储](logging.html#jobs-log-storage-managed-storage)中详述的权限到 S3 网关终端节点。如需疑难解答请求，请联系 AWS 支持人员。
+ 如果您在 Lake Formation 中注册了表位置，则无论 Amazon EMR 作业运行时角色的 IAM 权限如何，数据访问路径都会经过 Lake Formation 存储的凭证。如果错误配置了在表位置注册的角色，那么使用具有 S3 IAM 权限的角色提交到表位置的作业就会失败。
+ 写入 Lake Formation 表使用的是 IAM 权限，而不是 Lake Formation 授予的权限。如果作业运行时角色拥有必要的 S3 权限，就可以使用该权限来运行写操作。

以下是使用 Apache Iceberg 时的注意事项和限制：
+ 您只能在会话目录中使用 Apache Iceberg，而不能使用任意命名的目录。
+ 在 Lake Formation 中注册的 Iceberg 表仅支持元数据表 `history`、`metadata_log_entries`、`snapshots`、`files`、`manifests` 和 `refs`。Amazon EMR 会隐藏可能包含敏感数据的列，例如 `partitions`、`path` 和 `summaries`。此限制不适用于未在 Lake Formation 中注册的 Iceberg 表。
+ 未在 Lake Formation 中注册的表支持所有 Iceberg 存储过程。任何表都不支持 `register_table` 和 `migrate` 程序。
+ 我们建议您使用 Iceberg DataFrameWriter V2 而不是 V1。

## 7.12 及更高版本中带有 Lake Formation 的亚马逊 EMR 注意事项
<a name="emr-lf-limit-712"></a>

### General
<a name="emr-lf-limits-g"></a>

在亚马逊 EMR 中使用 Lake Formation 时，请查看以下限制。
+ 您不能为 Lake Formation 作业关闭 `DynamicResourceAllocation`。
+ 您只能将 Lake Formation 与 Spark 作业结合使用。
+ 将 Amazon EMR 与 Lake Formation 结合使用在整个作业中仅支持单个 Spark 会话。
+ 将 Amazon EMR 与 Lake Formation 结合使用仅支持通过资源链接共享的跨账户表查询。
+ 不支持以下项：
  + 弹性分布式数据集（RDD）
  + Spark 流
  + 嵌套列的访问控制
+ Amazon EMR 阻止可能破坏系统驱动程序完全隔离的功能，包括：
  + UDTs、Hive UDFs 以及任何涉及自定义类的用户定义函数
  + 自定义数据来源
  + 为 Spark 扩展、连接器或元存储提供额外的 jar
  + `ANALYZE TABLE` 命令
+ 如果您的 Amazon EMR 应用程序位于带有 Amazon S3 的 VPC 终端节点的私有子网中，并且您附加了终端节点策略来控制访问权限，那么在您的任务可以将日志数据发送到 AWS 托管 Amazon S3 之前，您必须在 VPC 策略中包含[托管存储](logging.html#jobs-log-storage-managed-storage)中详述的权限到 S3 网关终端节点。如需疑难解答请求，请联系 AWS 支持人员。
+ 从 Amazon EMR 7.9.0 开始，Spark FGAC 在与 s3a://方案一起使用时支持 S3 AFile 系统。
+ Amazon EMR 7.11 支持使用 CTAS 创建托管表。
+ Amazon EMR 7.12 支持使用 CTAS 创建托管表和外部表。

## Permissions
<a name="emr-lf-permissions"></a>
+ 为了强制执行访问控制，EXPLAIN PLAN 和 DDL 操作（例如 DESCRIBE TABLE）不会泄露受限信息。
+ 当您向 Lake Formation 注册表位置时，数据访问将使用 Lake Formation 存储的证书，而不是 EMR Serverless 作业运行时角色的 IAM 权限。如果表位置的注册角色配置错误，即使运行时角色对该位置拥有 S3 IAM 权限，任务也会失败。
+ 从 Amazon EMR 7.12 开始，你可以在追加模式下使用 DataFrameWriter (V2) 和 Lake Formation 凭证写入现有 Hive 和 Iceberg 表。对于覆盖操作或创建新表时，EMR 使用运行时角色凭据来修改表数据。
+ 使用视图或缓存表作为源数据时，存在以下限制（这些限制不适用于 AWS Glue 数据目录视图）：
  + 用于合并、删除和更新操作
    + 支持：使用视图和缓存表作为源表。
    + 不支持：在赋值和条件子句中使用视图和缓存表。
  + 对于创建或替换和替换表作为选择操作：
    + 不支持：使用视图和缓存表作为源表。
+ 仅当启用删除向量时，包含 UDFs 源数据的 Delta Lake 表才支持合并、删除和更新操作。

## 日志和调试
<a name="emr-lf-logs-debugging"></a>
+ Amazon EMR 限制访问启用 Lake Formation 的应用程序上的系统驱动程序 Spark 日志。由于系统驱动程序以提升的权限运行，因此系统驱动程序生成的事件和日志可能包含敏感信息。为防止未经授权的用户或代码访问此敏感数据，Amazon EMR 禁止访问系统驱动程序日志。

  系统配置文件日志始终保存在托管存储中：这是一项强制性设置，无法禁用。这些日志使用客户托管 KMS 密钥或托管 KMS 密钥 AWS 进行安全存储和加密。

## Iceberg
<a name="emr-lf-iceberg-considerations"></a>

使用 Apache Iceberg 时，请查看以下注意事项：
+ 您只能在会话目录中使用 Apache Iceberg，而不能使用任意命名的目录。
+ 在 Lake Formation 中注册的 Iceberg 表仅支持元数据表 `history`、`metadata_log_entries`、`snapshots`、`files`、`manifests` 和 `refs`。Amazon EMR 会隐藏可能包含敏感数据的列，例如 `partitions`、`path` 和 `summaries`。此限制不适用于未在 Lake Formation 中注册的 Iceberg 表。
+ 未在 Lake Formation 中注册的表支持所有 Iceberg 存储过程。任何表都不支持 `register_table` 和 `migrate` 程序。
+ 我们建议你使用 Iceberg DataFrameWriter V2 而不是 V1。

# Spark 原生精细访问控制允许列入名单 API PySpark
<a name="clean-rooms-spark-fgac-pyspark-api-allowlist"></a>

为了维护安全性和数据访问控制，Spark 精细访问控制 (FGAC) 限制了某些功能。 PySpark 这些限制是通过以下方式强制执行的：
+ 用于阻止函数执行的显式阻塞
+ 使函数无法运行的架构不兼容
+ 可能引发错误、返回被拒绝访问的消息或在调用时什么都不做的函数

Spark FGAC 不支持以下 PySpark 功能：
+ RDD 操作（因 Spark RDDUnsupported 异常而被阻止）
+ Spark Connect（不支持）
+ Spark 直播（不支持）

虽然我们已经在 Native Spark FGAC 环境中测试了列出的函数并确认它们可以按预期运行，但我们的测试通常仅涵盖每个 API 的基本用法。具有多种输入类型或复杂逻辑路径的函数可能有未经测试的场景。

对于此处未列出且不明显属于上述不支持的类别的任何函数，我们建议：
+ 首先在 gamma 环境或小规模部署中对其进行测试
+ 在生产中使用它们之前对其行为进行验证

**注意**  
如果您看到列出了一个类方法但没有列出其基类，则该方法应该仍然有效，这只是意味着我们尚未明确验证基类构造函数。

 PySpark API 被组织成多个模块。下表详细说明了对每个模块中方法的普遍支持。


| 模块名称 | Status | 注意 | 
| --- | --- | --- | 
|  pystark\$1core  |  支持  |  该模块包含主要的 RDD 类，这些函数大多不受支持。  | 
|  pystark\$1sql  |  支持  |  | 
|  pyspark\$1tes  |  支持  |  | 
|  pyspark\$1资源  |  支持  |  | 
|  pyspark\$1stre  |  阻止  |  Spark FGAC 中已禁止使用直播功能。  | 
|  pyspark\$1mllib  |  实验性的  |  该模块包含基于 RDD 的 ML 操作，这些函数大多不受支持。此模块未经过全面测试。  | 
|  pyspark\$1ml  |  实验性的  |  该模块包含 DataFrame 基于机器学习的操作，这些函数大多受支持。此模块未经过全面测试。  | 
|  pypark\$1pandas  |  支持  |    | 
|  pyspark\$1pandas\$1low  |  支持  |    | 
| pyspark\$1con |  阻止  |  Spark FGAC 中禁止使用 Spark Connect。  | 
| pyspark\$1pandas\$1conn |  阻止  |  Spark FGAC 中禁止使用 Spark Connect。  | 
| pyspark\$1pandas\$1slow\$1conn |  阻止  |  Spark FGAC 中禁止使用 Spark Connect。  | 
| pyspark\$1erro |  实验性的  |  此模块未经过全面测试。无法使用自定义错误类。  | 

**API 许可名单**

为了获得可下载且更易于搜索的列表，可以在[原生 FGAC 中允许的 Python 函数中](samples/Python functions allowed in Native FGAC.zip)找到包含模块和类的文件。

# Lake Formation 在 EC2 上访问亚马逊 EMR 的完整表格
<a name="lake-formation-unfiltered-ec2-access"></a>

在 Amazon EMR 7.8.0 及更高版本中，您可以利用带有 Glue Data Catalog 的 Lake Formation AWS ，其中任务运行时角色拥有完整的表权限，不受细粒度访问控制的限制。此功能允许您从 EC2 Spark 批处理和交互式作业上的 Amazon EMR 中读取和写入受 Lake Formation 保护的表。请参阅以下章节，详细了解 Lake Formation 以及如何将其与 EC2 上的 Amazon EMR 配合使用。

## 对 Lake Formation 使用全表访问
<a name="lake-formation-unfiltered-ec2-full-access"></a>

您可以从 Amazon EMR 访问受 AWS Lake Formation 保护的 Glue 数据目录表，或者在 EC2 Spark 作业或交互式会话中，任务的运行时角色具有完整表访问权限。您无需在 EC2 应用程序上的 Amazon EMR 上启用 AWS Lake Formation。将 Spark 作业配置为全表访问权限 (FTA) 时， AWS Lake Formation 凭据将用于 La AWS ke Formati read/write on 注册表的 S3 数据，而作业的运行时角色凭据将用于未在 AWS Lake Formation 中注册的 read/write 表。

**重要**  
请勿启用 AWS Lake Formation 进行精细的访问控制。在同一个 EMR 集群或应用程序上，作业不能同时运行全表访问 (FTA) 和精细访问控制 (FGAC)。

### 步骤 1：在 Lake Formation 中启用全表访问
<a name="lake-formation-unfiltered-ec2-full-table-access"></a>

要使用全表访问 (FTA) 模式，您必须允许第三方查询引擎访问数据，而无需在 La AWS ke Formation 中进行 IAM 会话标签验证。要启用此模式，请按照 [Application integration for full table access](https://docs.aws.amazon.com/lake-formation/latest/dg/full-table-credential-vending.html) 中的步骤操作。

**注意**  
 访问跨账户表时，必须在生产者账户和消费者账户中启用全表访问。同样，在访问跨区域表时，必须在生产者和使用者区域中都启用此设置。

### 第 2 步：设置作业运行时角色的 IAM 权限
<a name="lake-formation-unfiltered-ec2-iam-permissions"></a>

要获得基础数据的读取或写入权限，除 Lake Formation 权限外，作业运行时角色还需要具有 `lakeformation:GetDataAccess` IAM 权限。获得此权限后，Lake Formation 将授权访问数据的临时凭证请求。

下面是一个策略示例，展示了如何提供 IAM 权限以访问 Amazon S3 中的脚本、将日志上传到 S3、 AWS Glue API 权限以及访问 Lake Formation 的权限。

#### 步骤 2.1：配置 Lake Formation 权限
<a name="lake-formation-unfiltered-ec2-permission-model"></a>
+ 从 S3 读取数据的 Spark 作业需要 Lake Formation SELECT 权限。
+ 在 S3 中输入 write/delete 数据的 Spark 任务需要 Lake Formation ALL（超级）权限。
+ 与 Glue Data Catalog 交互的 Spark 作业需要视情况具有 DESCRIBE、ALTER、DROP 权限。

有关更多信息，请参阅[授予对 Data Catalog 资源的权限](https://docs.aws.amazon.com/lake-formation/latest/dg/granting-catalog-permissions.html)。

### 步骤 3：使用 Lake Formation 初始化 Spark 会话以实现全表访问
<a name="lake-formation-unfiltered-ec2-spark-session"></a>

#### 先决条件
<a name="lake-formation-unfiltered-ec2-spark-session-prereq"></a>

AWS 必须将 Glue 数据目录配置为元数据仓才能访问 Lake Formation 表。

设置以下设置以将 Glue 目录配置为元存储：

```
--conf spark.sql.catalogImplementation=hive
--conf spark.hive.metastore.client.factory.class=com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory
```

有关在 EC2 上为亚马逊 EMR 启用数据目录的更多信息，请参阅 EC2 上[亚马逊 EMR 的元数据仓](metastore-config.html)配置。

要访问在 AWS Lake Formation 中注册的表，需要在 Spark 初始化期间设置以下配置，将 Spark 配置为使用 AWS Lake Formation 凭据。

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

```
‐‐conf spark.hadoop.fs.s3.credentialsResolverClass=com.amazonaws.glue.accesscontrol.AWSLakeFormationCredentialResolver
--conf spark.hadoop.fs.s3.useDirectoryHeaderAsFolderObject=true 
--conf spark.hadoop.fs.s3.folderObject.autoAction.disabled=true
--conf spark.sql.catalog.skipLocationValidationOnCreateTable.enabled=true
--conf spark.sql.catalog.createDirectoryAfterTable.enabled=true
--conf spark.sql.catalog.dropDirectoryBeforeTable.enabled=true
```

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

```
--conf spark.sql.catalog.spark_catalog=org.apache.iceberg.spark.SparkSessionCatalog
--conf spark.sql.catalog.spark_catalog.warehouse=S3_DATA_LOCATION
--conf spark.sql.catalog.spark_catalog.client.region=REGION
--conf spark.sql.catalog.spark_catalog.type=glue
--conf spark.sql.catalog.spark_catalog.glue.account-id=ACCOUNT_ID
--conf spark.sql.catalog.spark_catalog.glue.lakeformation-enabled=true
--conf spark.sql.catalog.dropDirectoryBeforeTable.enabled=true
```

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

```
‐‐conf spark.hadoop.fs.s3.credentialsResolverClass=com.amazonaws.glue.accesscontrol.AWSLakeFormationCredentialResolver
--conf spark.hadoop.fs.s3.useDirectoryHeaderAsFolderObject=true 
--conf spark.hadoop.fs.s3.folderObject.autoAction.disabled=true
--conf spark.sql.catalog.skipLocationValidationOnCreateTable.enabled=true
--conf spark.sql.catalog.createDirectoryAfterTable.enabled=true
--conf spark.sql.catalog.dropDirectoryBeforeTable.enabled=true
```

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

```
‐‐conf spark.hadoop.fs.s3.credentialsResolverClass=com.amazonaws.glue.accesscontrol.AWSLakeFormationCredentialResolver
--conf spark.hadoop.fs.s3.useDirectoryHeaderAsFolderObject=true 
--conf spark.hadoop.fs.s3.folderObject.autoAction.disabled=true
--conf spark.sql.catalog.skipLocationValidationOnCreateTable.enabled=true
--conf spark.sql.catalog.createDirectoryAfterTable.enabled=true
--conf spark.sql.catalog.dropDirectoryBeforeTable.enabled=true
--conf spark.jars=/usr/lib/hudi/hudi-spark-bundle.jar
--conf spark.sql.extensions=org.apache.spark.sql.hudi.HoodieSparkSessionExtension
--conf spark.sql.catalog.spark_catalog=org.apache.spark.sql.hudi.catalog.HoodieCatalog
--conf spark.serializer=org.apache.spark.serializer.KryoSerializer
```

------
+ `spark.hadoop.fs.s3.credentialsResolverClass=com.amazonaws.glue.accesscontrol.AWSLakeFormationCredentialResolver`：将 EMR 文件系统 (EMRFS) 或 EMR S3A 配置为对 Lake Formation 注册表使用 L AWS ake Formation S3 凭据。如果表未注册，请使用作业的运行时角色凭证。
+ `spark.hadoop.fs.s3.useDirectoryHeaderAsFolderObject=true` 和 `spark.hadoop.fs.s3.folderObject.autoAction.disabled=true`：在创建 S3 文件夹时，将 EMRFS 配置为使用内容类型标头应用程序/x 目录，而不是 \$1folder\$1 后缀。这在读取 Lake Formation 表时为必需，因为 Lake Formation 凭证不允许读取带有 \$1folder\$1 后缀的表文件夹。
+ `spark.sql.catalog.skipLocationValidationOnCreateTable.enabled=true`：将 Spark 配置为在创建表之前跳过空表位置验证。这对于注册到 Lake Formation 的表是必需的，因为只有在创建 Glue 数据目标表之后，用于验证空位置的 Lake Formation 凭证才会可用。如果未启用此配置，则作业的运行时角色凭证将会验证空表位置。
+ `spark.sql.catalog.createDirectoryAfterTable.enabled=true`：将 Spark 配置为在 Hive 元数据存储中创建表后再创建 Amazon S3 文件夹。这对于注册到 Lake Formation 的表为必需，因为只有在创建 Glue Data Catalog 表之后，用于创建 S3 文件夹的 Lake Formation 凭证才会可用。
+ `spark.sql.catalog.dropDirectoryBeforeTable.enabled=true`：将 Spark 配置为在 Hive 元数据存储中删除表之前删除 S3 文件夹。这对于注册到 Lake Formation 的表是必需的，因为在从 Glue Data Catalog 中删除表之后，用于删除 S3 文件夹的 Lake Formation 凭证将不可用。
+ `spark.sql.catalog.<catalog>.glue.lakeformation-enabled=true`: 将 Iceberg 目录配置为使用 AWS Lake Formation S3 凭据对 Lake Formation 注册的表。如果表未注册，则会使用默认环境凭证。

#### 在 SageMaker 统一工作室中配置全桌访问模式
<a name="lake-formation-unfiltered-ec2-full-table"></a>

要通过 JupyterLab 笔记本中的交互式 Spark 会话访问 Lake Formation 注册的表，请使用兼容权限模式。使用 %%configure 魔术命令设置 Spark 配置。根据表类型选择配置：

------
#### [ For Hive tables ]

```
%%configure -f
{
    "conf": {
        "spark.hadoop.fs.s3.credentialsResolverClass": "com.amazonaws.glue.accesscontrol.AWSLakeFormationCredentialResolver",
        "spark.hadoop.fs.s3.useDirectoryHeaderAsFolderObject": true,
        "spark.hadoop.fs.s3.folderObject.autoAction.disabled": true,
        "spark.sql.catalog.skipLocationValidationOnCreateTable.enabled": true,
        "spark.sql.catalog.createDirectoryAfterTable.enabled": true,
        "spark.sql.catalog.dropDirectoryBeforeTable.enabled": true
    }
}
```

------
#### [ For Iceberg tables ]

```
%%configure -f
{
    "conf": {
        "spark.sql.catalog.spark_catalog": "org.apache.iceberg.spark.SparkSessionCatalog",
        "spark.sql.catalog.spark_catalog.warehouse": "S3_DATA_LOCATION",
        "spark.sql.catalog.spark_catalog.client.region": "REGION",
        "spark.sql.catalog.spark_catalog.type": "glue",
        "spark.sql.catalog.spark_catalog.glue.account-id": "ACCOUNT_ID",
        "spark.sql.catalog.spark_catalog.glue.lakeformation-enabled": "true",
        "spark.sql.catalog.dropDirectoryBeforeTable.enabled": "true", 
    }
}
```

------
#### [ For Delta Lake tables ]

```
%%configure -f
{
    "conf": {
        "spark.hadoop.fs.s3.credentialsResolverClass": "com.amazonaws.glue.accesscontrol.AWSLakeFormationCredentialResolver",
        "spark.hadoop.fs.s3.useDirectoryHeaderAsFolderObject": true,
        "spark.hadoop.fs.s3.folderObject.autoAction.disabled": true,
        "spark.sql.catalog.skipLocationValidationOnCreateTable.enabled": true,
        "spark.sql.catalog.createDirectoryAfterTable.enabled": true,
        "spark.sql.catalog.dropDirectoryBeforeTable.enabled": true
    }
}
```

------
#### [ For Hudi tables ]

```
%%configure -f
{
    "conf": {
        "spark.hadoop.fs.s3.credentialsResolverClass": "com.amazonaws.glue.accesscontrol.AWSLakeFormationCredentialResolver",
        "spark.hadoop.fs.s3.useDirectoryHeaderAsFolderObject": true,
        "spark.hadoop.fs.s3.folderObject.autoAction.disabled": true,
        "spark.sql.catalog.skipLocationValidationOnCreateTable.enabled": true,
        "spark.sql.catalog.createDirectoryAfterTable.enabled": true,
        "spark.sql.catalog.dropDirectoryBeforeTable.enabled": true,
        "spark.jars": "/usr/lib/hudi/hudi-spark-bundle.jar",
        "spark.sql.extensions": "org.apache.spark.sql.hudi.HoodieSparkSessionExtension",
        "spark.sql.catalog.spark_catalog": "org.apache.spark.sql.hudi.catalog.HoodieCatalog",
        "spark.serializer": "org.apache.spark.serializer.KryoSerializer"
    }
}
```

------

替换占位符：
+ `S3_DATA_LOCATION`：您的 S3 存储桶路径
+ `REGION`: AWS 区域（例如 us-east-1）
+ `ACCOUNT_ID`: 您的 AWS 账户 ID

**注意**  
必须在笔记本中执行任何 Spark 操作之前设置这些配置。

#### 支持的操作
<a name="lake-formation-unfiltered-ec2-supported-operations"></a>

这些操作将使用 AWS Lake Formation 凭据来访问表格数据。
+ CREATE TABLE
+ ALTER TABLE
+ INSERT INTO
+ INSERT OVERWRITE
+ UPDATE
+ MERGE INTO
+ DELETE FROM
+ ANALYZE TABLE
+ REPAIR TABLE
+ DROP TABLE
+ Spark Datasource 查询
+ Spark Datasource 写入

**注意**  
上面未列出的操作将继续使用 IAM 权限来访问表数据。

#### 注意事项
<a name="considerations"></a>
+ 如果使用未启用全表访问的作业创建 Hive 表，并且未插入任何记录，则后续从启用全表访问的作业进行的读取或写入操作都将失败。这是因为未启用全表访问的 EMR Spark 会将 `$folder$` 后缀添加到表文件夹名称。要解决此问题，您可以使用以下任一方法：
  + 从未启用 FTA 的作业在表中至少插入一行。
  + 配置未启用 FTA 的作业，从而确保不在 S3 文件夹名称中使用 `$folder$` 后缀。可以通过设置 Spark 配置 `spark.hadoop.fs.s3.useDirectoryHeaderAsFolderObject=true` 来实现此目的。
  + `s3://path/to/table/table_name`使用 S3 控制台或 S3 CLI 在表的 AWS 位置创建 AWS S3 文件夹。
+ 从 Amazon EMR 版本 7.8.0 开始，EMR 文件系统 (EMRFS) 支持全表访问，从 Amazon EMR 版本 7.10.0 开始，S3A 文件系统支持全表访问。
+ Hive、Iceberg、Delta 和 Hudi 表支持完整表访问权限。
+ **Hudi FTA Write Support 注意事项：**
  + Hudi FTA 写入要求在作业执行期间使用 HoodieCredentialedHadoopStorage 凭证自动售出。运行 Hudi 作业时设置以下配置：`hoodie.storage.class=org.apache.spark.sql.hudi.storage.HoodieCredentialedHadoopStorage`
  + 从 Amazon EMR 7.12 版本开始，Hudi 的全表访问权限 (FTA) 写入支持已推出。
  + Hudi FTA 写入支持目前仅适用于默认 Hudi 配置。自定义或非默认 Hudi 设置可能无法完全支持，并可能导致意外行为。
  + 在 FTA 写入模式下，目前不支持 Hudi Merge-On-Read (MOR) 表的群集。
+ 使用 Lake Formation 精细访问控制 (FGAC) 规则或 Glue Data Catalog 视图引用表的作业将会失败。要使用 FGAC 规则或 Glue Data Catalog 视图查询表，您必须使用 FGAC 模式。您可以按照 AWS 文档中概述的步骤启用 FGAC 模式：在 EC2 [上使用 Amazon EMR 和 Lake Formation 进行精 AWS 细](emr-serverless-lf-enable.html)的访问控制。
+ 全表访问模式不支持 Spark Streaming。
+ 将 Spark DataFrame 写入 Lake Formation 表时，Hive 和 Iceberg 表仅支持 APPEND 模式：`df.write.mode("append").saveAsTable(table_name)`
+ 创建外部表需要 IAM 权限。
+ 由于 Lake Formation 会在 Spark 作业中临时缓存凭证，因此当前正在运行的 Spark 批处理作业或交互式会话可能无法反映权限更改。
+ 您必须使用用户定义的角色而不是服务相关角色：[Lake Formation 对角色的要求](https://docs.aws.amazon.com/lake-formation/latest/dg/registration-role.html)。

#### Hudi FTA Write Support——支持的操作
<a name="hudi-fta-supported-operations"></a>

下表显示了 Hudi Copy-On-Write (COW) 和 Merge-On-Read (MOR) 表在 “全表访问” 模式下支持的写入操作：


**Hudi FTA 支持的写入操作**  

| 表类型 | 操作 | SQL 写入命令 | Status | 
| --- | --- | --- | --- | 
| 牛 | INSERT | INSERT INTO TABLE | 支持 | 
| 牛 | INSERT | 插入表格-分区（静态、动态） | 支持 | 
| 牛 | INSERT | INSERT OVERWRITE | 支持 | 
| 牛 | INSERT | 插入覆盖-分区（静态、动态） | 支持 | 
| UPDATE | UPDATE | UPDATE TABLE | 支持 | 
| 牛 | UPDATE | 更新表-更改分区 | 不支持 | 
| DELETE | DELETE | DELETE FROM TABLE | 支持 | 
| ALTER | ALTER | 更改表格-重命名为 | 不支持 | 
| 牛 | ALTER | 更改表格-设置 TBLPROPERTIES | 支持 | 
| 牛 | ALTER | 更改表格-未设置 TBLPROPERTIES | 支持 | 
| 牛 | ALTER | 更改表格-更改列 | 支持 | 
| 牛 | ALTER | 更改表格-添加列 | 支持 | 
| 牛 | ALTER | 更改表-添加分区 | 支持 | 
| 牛 | ALTER | 更改表-删除分区 | 支持 | 
| 牛 | ALTER | 更改表-恢复分区 | 支持 | 
| 牛 | ALTER | 修复表同步分区 | 支持 | 
| DROP | DROP | DROP TABLE | 支持 | 
| 牛 | DROP | 删除表-清除 | 支持 | 
| CREATE | CREATE | 创建表-托管 | 支持 | 
| 牛 | CREATE | 创建表-分区依据 | 支持 | 
| 牛 | CREATE | 如果不存在则创建表 | 支持 | 
| 牛 | CREATE | CREATE TABLE LIKE | 支持 | 
| 牛 | CREATE | CREATE TABLE AS SELECT | 支持 | 
| CREATE | CREATE | 使用位置创建表-外部表 | 不支持 | 
| 数据框（插入） | 数据框（插入） | saveAsTable. 覆盖 | 支持 | 
| 牛 | 数据框（插入） | saveAsTable.Append | 不支持 | 
| 牛 | 数据框（插入） | saveAsTable。忽略 | 支持 | 
| 牛 | 数据框（插入） | saveAsTable.ErrorIfExists | 支持 | 
| 牛 | 数据框（插入） | saveAsTable -外部表（路径） | 不支持 | 
| 牛 | 数据框（插入） | 保存（路径）-DF v1 | 不支持 | 
| 更多 | INSERT | INSERT INTO TABLE | 支持 | 
| 更多 | INSERT | 插入表格-分区（静态、动态） | 支持 | 
| 更多 | INSERT | INSERT OVERWRITE | 支持 | 
| 更多 | INSERT | 插入覆盖-分区（静态、动态） | 支持 | 
| UPDATE | UPDATE | UPDATE TABLE | 支持 | 
| 更多 | UPDATE | 更新表-更改分区 | 不支持 | 
| DELETE | DELETE | DELETE FROM TABLE | 支持 | 
| ALTER | ALTER | 更改表格-重命名为 | 不支持 | 
| 更多 | ALTER | 更改表格-设置 TBLPROPERTIES | 支持 | 
| 更多 | ALTER | 更改表格-未设置 TBLPROPERTIES | 支持 | 
| 更多 | ALTER | 更改表格-更改列 | 支持 | 
| 更多 | ALTER | 更改表格-添加列 | 支持 | 
| 更多 | ALTER | 更改表-添加分区 | 支持 | 
| 更多 | ALTER | 更改表-删除分区 | 支持 | 
| 更多 | ALTER | 更改表-恢复分区 | 支持 | 
| 更多 | ALTER | 修复表同步分区 | 支持 | 
| DROP | DROP | DROP TABLE | 支持 | 
| 更多 | DROP | 删除表-清除 | 支持 | 
| CREATE | CREATE | 创建表-托管 | 支持 | 
| 更多 | CREATE | 创建表-分区依据 | 支持 | 
| 更多 | CREATE | 如果不存在则创建表 | 支持 | 
| 更多 | CREATE | CREATE TABLE LIKE | 支持 | 
| 更多 | CREATE | CREATE TABLE AS SELECT | 支持 | 
| CREATE | CREATE | 使用位置创建表-外部表 | 不支持 | 
| DATAFRAME（UPSERT） | DATAFRAME（UPSERT） | saveAsTable. 覆盖 | 支持 | 
| 更多 | DATAFRAME（UPSERT） | saveAsTable.Append | 不支持 | 
| 更多 | DATAFRAME（UPSERT） | saveAsTable。忽略 | 支持 | 
| 更多 | DATAFRAME（UPSERT） | saveAsTable.ErrorIfExists | 支持 | 
| 更多 | DATAFRAME（UPSERT） | saveAsTable -外部表（路径） | 不支持 | 
| 更多 | DATAFRAME（UPSERT） | 保存（路径）-DF v1 | 不支持 | 
| 数据框（删除） | 数据框（删除） | saveAsTable.Append | 不支持 | 
| 更多 | 数据框（删除） | saveAsTable -外部表（路径） | 不支持 | 
| 更多 | 数据框（删除） | 保存（路径）-DF v1 | 不支持 | 
| DATAFRAME（批量插入） | DATAFRAME（批量插入） | saveAsTable. 覆盖 | 支持 | 
| 更多 | DATAFRAME（批量插入） | saveAsTable.Append | 不支持 | 
| 更多 | DATAFRAME（批量插入） | saveAsTable。忽略 | 支持 | 
| 更多 | DATAFRAME（批量插入） | saveAsTable.ErrorIfExists | 支持 | 
| 更多 | DATAFRAME（批量插入） | saveAsTable -外部表（路径） | 不支持 | 
| 更多 | DATAFRAME（批量插入） | 保存（路径）-DF v1 | 不支持 | 