

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

# 运行任务
<a name="jobs"></a>

预置应用程序后，请向应用程序提交作业。本节介绍如何使用 AWS CLI 来运行这些作业。本节还确定了 EMR Serverless 上可用的每种应用程序类型的默认值。

**Topics**
+ [

# 任务运行状态
](job-states.md)
+ [

# EMR Serverless 作业运行取消宽限期
](job-cancellation-grace-period.md)
+ [

# 从 EMR Studio 控制台运行作业
](jobs-studio.md)
+ [

# 正在运行来自的作业 AWS CLI
](jobs-cli.md)
+ [

# 执行 IAM 策略
](jobs-cli-execution.md)
+ [

# 使用随机排序优化的磁盘
](jobs-shuffle-optimized-disks.md)
+ [

# 为 Amazon EMR 使用无服务器存储 Serverless
](jobs-serverless-storage.md)
+ [

# 处理连续流数据的流处理作业
](jobs-streaming.md)
+ [

# 运行 EMR Serverless 作业时使用 Spark 配置
](jobs-spark.md)
+ [

# 运行 EMR Serverless 作业时使用 Hive 配置
](jobs-hive.md)
+ [

# EMR Serverless 作业弹性
](jobs-resiliency.md)
+ [

# EMR Serverless 的元存储配置
](metastore-config.md)
+ [

# 从 EMR Serverless 访问另一个 AWS 账户中的 S3 数据
](jobs-s3-access.md)
+ [

# 排查 EMR Serverless 中的错误
](jobs-troubleshoot.md)
+ [

# 启用 Job 级别成本分配
](jobs-job-level-cost-allocation.md)

# 任务运行状态
<a name="job-states"></a>

当您将作业运行提交到 Amazon EMR Serverless 作业队列时，作业运行将进入 `SUBMITTED` 状态。作业状态从 `SUBMITTED` 变为 `RUNNING`，直至达到 `FAILED`、`SUCCESS` 或 `CANCELLING`。

任务运行可具有以下状态：


****  

| 州 | 说明 | 
| --- | --- | 
| 已提交 | 将作业运行提交到 EMR Serverless 时的初始作业状态。作业等待为应用程序安排。EMR Serverless 开始确定作业运行的优先级并安排作业运行。 | 
| 已排队 | 当应用程序级作业运行并发被完全占用时，作业运行将在此状态下等待。有关排队和并发的更多信息，请参阅 [EMR Serverless 应用程序的作业并发和排队](applications-concurrency-queuing.md)。 | 
| 待处理 | 调度程序评估作业运行，确定应用程序运行的优先级和计划。 | 
| 已安排 | EMR Serverless 已安排应用程序的作业运行，并分配资源来执行作业。 | 
| 正在运行 | EMR Serverless 已分配作业最初需要的资源，作业正在应用程序中运行。在 Spark 应用程序中，这意味着 Spark 驱动程序进程处于 running 状态。 | 
| 已失败 | EMR Serverless 未能将作业运行提交到应用程序，或者未成功完成。有关此作业失败的其他信息，请参阅 StateDetails。 | 
|  成功 | 作业运行已成功完成。 | 
| 正在取消 | CancelJobRun API 已请求取消作业运行，或者作业运行已超时。EMR Serverless 正在尝试取消应用程序中的作业并释放资源。 | 
| 已取消 | 作业运行已成功取消，使用的资源也已释放。 | 

# EMR Serverless 作业运行取消宽限期
<a name="job-cancellation-grace-period"></a>

在数据处理系统中，突然终止可能会导致资源浪费、操作不完整和潜在数据不一致。Amazon EMR Serverless 允许您在取消作业运行时指定宽限期。此功能允许在作业终止之前有时间进行适当的清理和完成正在进行的工作。

取消作业运行时，请使用参数 `shutdownGracePeriodInSeconds` 指定一个宽限期（以秒为单位），在此期间作业可以执行清理操作，然后再最终终止。批处理作业和流式处理作业的行为和默认设置有所不同。

## 批处理作业的宽限期
<a name="grace-period-batch-jobs"></a>

对于批处理作业，EMR Serverless 允许您实施在宽限期内执行的自定义清理操作。您可以将这些清理操作注册为应用程序代码中 JVM 关闭钩子的一部分。

**默认行为**

关闭的默认行为没有宽限期。它包含以下两个操作：
+ 立即终止
+ 资源立即释放

**配置选项**

您可以指定导致正常关闭的设置：
+ 关闭宽限期有效范围：15-1800 秒（可选）
+ 立即终止（没有任何宽限期）：0 秒

### 启用正常关闭
<a name="enable-graceful-shutdown-batch"></a>

要实现批处理作业的正常关闭，请按照以下步骤进行操作：

1. 在应用程序代码中添加包含自定义关闭逻辑的关闭钩子。

------
#### [ Example in Scala ]

   ```
   import org.apache.hadoop.util.ShutdownHookManager
   
   // Register shutdown hook with priority (second argument)
   // Higher priority hooks run first
   ShutdownHookManager.get().addShutdownHook(() => {
       logger.info("Performing cleanup operations...")
   }, 100)
   ```

   使用 [ShutdownHookManager](https://hadoop.apache.org/docs/r2.8.0/hadoop-project-dist/hadoop-common/api/org/apache/hadoop/util/ShutdownHookManager.html)

------
#### [ Example in PySpark ]

   ```
   import atexit
   
   def cleanup():
       # Your cleanup logic here
       print("Performing cleanup operations...")
   
   # Register the cleanup function
   atexit.register(cleanup)
   ```

------

1. 指定取消作业时的宽限期，以便有时间执行之前添加的钩子

   **示例**

   ```
   # Default (immediate termination)
   aws emr-serverless cancel-job-run \
     --application-id APPLICATION_ID \
     --job-run-id JOB_RUN_ID
   
   # With 5-minute grace period
   aws emr-serverless cancel-job-run \
     --application-id APPLICATION_ID \
     --job-run-id JOB_RUN_ID \
     --shutdown-grace-period-in-seconds 300
   ```

## 流式处理作业的宽限期
<a name="grace-period-streaming-jobs"></a>

在 Spark Structured Streaming 中，计算涉及从外部数据来源读取数据或向其写入数据，突然关闭可能会导致不需要的结果。流式处理作业以微批次处理数据，而中途中断这些操作可能会导致后续尝试出现重复处理。当以前微批次中的最新检查点未写入时会发生这种情况，导致在流式处理作业重新启动时再次处理相同的数据。这种重复处理不仅浪费计算资源，还会影响业务运营，因此避免突然关闭至关重要。

EMR Serverless 通过流式查询侦听器提供内置正常关闭支持。这样可以确保在作业终止之前正确完成正在进行的微批次。该服务会自动管理流式处理应用程序的微批次之间的正常关闭，确保当前微批次完成处理，正确写入检查点，以及在关闭过程中无需提取新数据即可干净地终止流式处理上下文。

**默认行为**
+ 默认启用 120 秒宽限期。
+ 内置的流式查询侦听器管理正常关闭。

**配置选项**
+ 关闭宽限期有效范围：15-1800 秒（可选）
+ 立即终止：0 秒

### 启用正常关闭
<a name="enable-graceful-shutdown-streaming"></a>

要实现流式处理作业正常关闭，请执行以下操作：

指定取消作业时的宽限期，以便有时间完成正在进行的微批次。

**示例**

```
# Default graceful shutdown (120 seconds)
aws emr-serverless cancel-job-run \
  --application-id APPLICATION_ID \
  --job-run-id JOB_RUN_ID

# Custom grace period (e.g. 300 seconds)
aws emr-serverless cancel-job-run \
  --application-id APPLICATION_ID \
  --job-run-id JOB_RUN_ID \
  --shutdown-grace-period-in-seconds 300

# Immediate Termination
aws emr-serverless cancel-job-run \
  --application-id APPLICATION_ID \
  --job-run-id JOB_RUN_ID \
  --shutdown-grace-period-in-seconds 0
```

### 添加自定义关闭钩子（可选）
<a name="custom-shutdown-hooks"></a>

虽然默认情况下，EMR Serverless 通过其内置的流式查询侦听器管理正常关闭，但是您可以选择为单个流式查询实现自定义关闭逻辑。EMR Serverless 将其优雅关闭侦听器注册为优先级 60（使用）。 ShutdownHookManager由于优先级较高的钩子会优先运行，您可以注册优先级大于 60 的自定义清理操作，从而确保它们在 EMR Serverless 的关闭过程开始之前执行。

要添加自定义钩子，请参考本主题中的第一个示例，该示例展示了如何在应用程序代码中添加关闭钩子。这里，优先级为 100，大于 60。因此，此类关闭钩子会首先运行。

**注意**  
自定义关闭钩子是可选的，并非正常关闭功能所必需，EMR Serverless 会自动处理该功能。

### 宽限期费用和批处理持续时间
<a name="grace-period-charges"></a>

如果使用默认的宽限期值（120 秒）：
+ 如果您的批处理持续时间少于 120 秒，您只需支付完成批处理所需的实际时间费用。
+ 如果您的批处理持续时间超过 120 秒，则将按最大宽限期（120 秒）向您收费，但查询可能不会正常关闭，因为它将被强制终止。

要优化成本并确保正常关闭，请执行以下操作：
+ 对于持续时间超过 120 秒的批处理：考虑增加宽限期以匹配您的批处理持续时间。
+ 对于持续时间少于 120 秒的批处理：无需调整宽限期，因为您只需支付实际处理时间的费用。

## 注意事项
<a name="considerations"></a>

### 宽限期行为
<a name="grace-period-behavior"></a>
+ 宽限期为您注册的关闭钩子完成提供了时间。
+ 即使在宽限期之前，一旦关闭钩子完成，作业也会立即终止。
+ 如果清理作业超过宽限期，则该作业将被强制终止。

### 服务行为
<a name="service-behavior"></a>
+ 宽限期关闭仅适用于处于 RUNNING 状态的作业。
+ CANCELLING 状态下的后续取消请求将被忽略。
+ 如果 EMR Serverless 由于内部服务错误而无法启动宽限期关闭：
  + 服务将重试最多 2 分钟。
  + 如果重试不成功，则作业将被强制终止。

### 计费
<a name="billing"></a>

作业将按作业完全关闭之前所使用的计算资源计费，包括在宽限期内花费的任何时间。

# 从 EMR Studio 控制台运行作业
<a name="jobs-studio"></a>

您可以向 EMR Serverless 应用程序提交作业运行，从 EMR Studio 控制台访问作业。要在 EMR Studio 控制台上创建或导航到 EMR Serverless 应用程序，请按照[控制台入门](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/getting-started.html#gs-console)中的说明操作。

## 提交作业
<a name="studio-submit-job"></a>

在**提交作业**页面上，按如下方式向 EMR Serverless 应用程序提交作业。

------
#### [ Spark ]

1. 在**名称**字段中，输入作业运行的名称。

1. 在**运行时角色**字段中，输入 EMR Serverless 应用程序在运行作业时可代入的 IAM 角色名称。要了解有关运行时角色的更多信息，请参阅 [Amazon EMR Serverless 的作业运行时角色](security-iam-runtime-role.md)。

1. 在**脚本位置**字段中，输入要运行的脚本或 JAR 的 Amazon S3 位置。对于 Spark 作业，脚本可以是 Python（`.py`）文件或 JAR（`.jar`）文件。

1. 如果脚本位置是 JAR 文件，请在**主类**字段中输入作为作业入口的类名。

1. （可选）输入其余字段的值。
   + **脚本参数**：输入要传递给主 JAR 或 Python 脚本的参数。您的代码会读取这些参数。用逗号分隔数组中的每个参数。
   + **Spark 属性**：展开 Spark 属性部分，在此字段中输入任何 Spark 配置参数。
**注意**  
如果指定 Spark 驱动程序和执行程序的大小，请考虑内存开销。在属性 `spark.driver.memoryOverhead` 和 `spark.executor.memoryOverhead` 中指定内存开销值。内存开销的默认值为容器内存的 10%，最小为 384MB。执行程序内存和内存开销之和不能超过工作线程内存。例如，30GB 工作线程的最大 `spark.executor.memory` 必须为 27GB。
   + **作业配置**：在此字段中指定任何作业配置。您可以使用这些作业配置覆盖应用程序的默认配置。
   + **其他设置**：激活或停用作为元存储的 AWS Glue Data Catalog，并修改应用程序日志设置。要了解有关元存储配置的更多信息，请参阅[EMR Serverless 的元存储配置](metastore-config.md)。要了解有关应用程序日志记录选项的更多信息，请参阅[存储日志](logging.md)。
   + **标签**：为应用程序分配自定义标签。

1. 选择**提交作业**。

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

1. 在**名称**字段中，输入作业运行的名称。

1. 在**运行时角色**字段中，输入 EMR Serverless 应用程序在运行作业时可代入的 IAM 角色名称。

1. 在**脚本位置**字段中，输入要运行的脚本或 JAR 的 Amazon S3 位置。对于 Hive 作业，脚本必须是 Hive（`.sql`）文件。

1. （可选）输入其余字段的值。
   + **初始化脚本位置**：输入在 Hive 脚本运行之前初始化表的脚本位置。
   + **Hive 属性**：展开 Hive 属性部分，在此字段中输入任何 Hive 配置参数。
   + **作业配置**：指定任何作业配置。您可以使用这些作业配置覆盖应用程序的默认配置。对于 Hive 作业，`hive.exec.scratchdir` 和 `hive.metastore.warehouse.dir` 是 `hive-site` 配置中的必需属性。

     ```
     {
         "applicationConfiguration": [
             {
                 "classification": "hive-site",
                 "configurations": [],
                 "properties": {
                     "hive.exec.scratchdir": "s3://DOC-EXAMPLE_BUCKET/hive/scratch",
                     "hive.metastore.warehouse.dir": "s3://DOC-EXAMPLE_BUCKET/hive/warehouse"
                 }
             }
         ],
         "monitoringConfiguration": {}
     }
     ```
   + **其他设置**-激活或停用 AWS Glue 数据目录作为元数据仓并修改应用程序日志设置。要了解有关元存储配置的更多信息，请参阅[EMR Serverless 的元存储配置](metastore-config.md)。要了解有关应用程序日志记录选项的更多信息，请参阅[存储日志](logging.md)。
   + **标签**：为应用程序分配任何自定义标签。

1. 选择**提交作业**。

------

## 访问作业运行
<a name="studio-view-jobs"></a>

在应用程序**详细信息**页面上的**作业运行**选项卡中，访问作业运行并对作业运行执行以下操作。

**取消作业**：要取消处于 `RUNNING` 状态的作业运行，请选择此选项。要了解有关作业运行转换的更多信息，请参阅[任务运行状态](job-states.md)。

**克隆作业**：要克隆之前的运行作业并重新提交，请选择此选项。

# 正在运行来自的作业 AWS CLI
<a name="jobs-cli"></a>

您可以在 AWS CLI上创建、描述和删除单个作业。您还可以列出所有作业，以便一目了然地访问它们。

要提交新作业，请使用 `start-job-run`。提供要运行的应用程序的 ID 以及特定于作业的属性。有关 Spark 示例，请参阅 [运行 EMR Serverless 作业时使用 Spark 配置](jobs-spark.md)。有关 Hive 示例，请参阅 [运行 EMR Serverless 作业时使用 Hive 配置](jobs-hive.md)。此命令将返回 `application-id`、ARN 和新的 `job-id`。

每个作业运行都设定了超时时间。如果作业运行超过此持续时间，EMR Serverless 会自动将其取消。默认超时时间为 12 小时。开始作业运行时，请将此超时设置配置为符合作业要求的值。使用 `executionTimeoutMinutes` 属性配置此值。

```
aws emr-serverless start-job-run \
  --application-id application-id \
  --execution-role-arn job-role-arn \
  --execution-timeout-minutes 15 \
  --job-driver '{
    "hive": {
        "query": "s3://amzn-s3-demo-bucket/scripts/create_table.sql",
        "parameters": "--hiveconf hive.exec.scratchdir=s3://amzn-s3-demo-bucket/hive/scratch --hiveconf hive.metastore.warehouse.dir=s3://amzn-s3-demo-bucket/hive/warehouse"
    }
   }' \
  --configuration-overrides '{
    "applicationConfiguration": [{
        "classification": "hive-site",
        "properties": {
            "hive.client.cores": "2",
            "hive.client.memory": "4GIB"
        }
    }]
}'
```

要描述作业，请使用 `get-job-run`。此命令将返回特定于作业的配置和新作业的设置容量。

```
aws emr-serverless get-job-run \
--job-run-id job-id \
--application-id application-id
```

要列出作业，请使用 `list-job-runs`。此命令将返回一组简短的属性，包括作业类型、状态和其他高级属性。如果您不想访问所有作业，请指定要访问的最大作业数，最多 50 个。以下示例指定您想访问最后两次作业运行情况。

```
aws emr-serverless list-job-runs \
--max-results 2 \
--application-id application-id
```

要取消作业，请使用 `cancel-job-run`。提供要取消的作业的 `application-id` 和 `job-id`。

```
aws emr-serverless cancel-job-run \
--job-run-id job-id \
--application-id application-id
```

有关如何从中运行作业的更多信息 AWS CLI，请参阅《[EMR Serverles](https://docs.aws.amazon.com/emr-serverless/latest/APIReference/Welcome.html) s API 参考》。

# 执行 IAM 策略
<a name="jobs-cli-execution"></a>

在 EMR Serverless 上提交作业运行时，除了执行角色之外，您还可以指定执行 IAM 策略。作业运行所采用的权限是执行角色中的权限与指定的执行 IAM 策略中的权限的交集。

## 开始使用
<a name="jobs-cli-execution-getting-started"></a>

使用执行 IAM 策略的步骤：

创建一个 `emr-serverless` 应用程序或使用现有应用程序，然后运行以下 aws cli 以启动带有内联 IAM 策略的作业运行：

```
aws emr-serverless start-job-run --region us-west-2 \
      --application-id application-id \
      --execution-role-arn execution-role-arn \
      --job-driver job-driver-options \
      --execution-iam-policy '{"policy": "inline-policy"}'
```

## CLI 命令示例
<a name="jobs-cli-execution-examples"></a>

如果机器上的 `policy.json` 文件中存储了以下策略：

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-test-bucket",
        "arn:aws:s3:::my-test-bucket/*"
      ],
      "Sid": "AllowS3Getobject"
    }
  ]
}
```

------

然后，我们可以使用以下 AWS CLI 命令使用此策略启动作业：

```
aws emr-serverless start-job-run --region us-west-2 \
      --application-id application-id \
      --execution-role-arn execution-role-arn \
      --job-driver job-driver-options
      --execution-iam-policy '{
          "policy": '$(jq -c '. | @json' policy.json)'
      }'
```

您也可以同时使用客户托管策略 AWS 和客户托管策略，通过以下方式指定它们 ARNs：

```
aws emr-serverless start-job-run --region us-west-2 \
      --application-id application-id \
      --execution-role-arn execution-role-arn \
      --job-driver job-driver-options
      --execution-iam-policy '{
          "policyArns": [
          "arn:aws:iam::aws:policy/AmazonS3FullAccess",
          "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
          ]
    }'
```

也可以在同一个请求 ARNs 中同时指定内联 IAM 策略和托管策略：

```
aws emr-serverless start-job-run --region us-west-2 \
      --application-id application-id \
      --execution-role-arn execution-role-arn \
      --job-driver job-driver-options
      --execution-iam-policy '{
          "policy": '$(jq -c '. | @json' policy.json)',
          "policyArns": [
          "arn:aws:iam::aws:policy/AmazonS3FullAccess",
          "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
          ]
      }'
```

## 重要提示
<a name="jobs-cli-execution-important-notes"></a>
+ `execution-role-policy` 的 `policy` 字段最多可包含 2048 个字符。
+ 在 `execution-iam-policy` 的 `policy` 字段中指定的内联 IAM 策略字符串必须符合 json 字符串标准，不能像前面的示例那样对换行符和引号进行转义。
+  ARNs 可以将最多 10 个托管策略的列表指定为 `execution-iam-policy`'s `policyArns` 字段的值。
+ 托管策略 ARNs 必须是有效 AWS 或客户托管策略 ARN 的列表，当指定客户托管策略 ARN 时，该策略必须属于 EMR-S 的同一个 AWS 账户。 JobRun
+ 当同时使用内联 IAM 策略和托管策略时，用于内联策略和托管策略的明文组合不能超过 2,048 个字符。
+ 由此产生的权限 JobRun 是执行角色和指定执行 IAM 策略中的权限的交集。

## 策略交集
<a name="jobs-cli-execution-policy-intersection"></a>

作业运行所采用的权限是执行角色中的权限与指定的执行 IAM 策略中的权限的交集。这意味着必须在两个地方都指定任何所需的许可才能起作用。 JobRun 但是，对于您不打算更新或覆盖的任何权限，可以在内联策略中指定额外一揽子允许语句。

示例

给定以下执行 IAM 角色策略：

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:*"
      ],
      "Resource": [
        "*"
      ],
      "Sid": "AllowS3"
    },
    {
      "Effect": "Allow",
      "Action": [
        "logs:DescribeLogGroups"
      ],
      "Resource": [
        "arn:aws:logs:us-west-2:123456789012:log-group::log-stream"
      ],
      "Sid": "AllowLOGSDescribeloggroups"
    },
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:DescribeTable"
      ],
      "Resource": [
        "arn:aws:dynamodb:*:*:table/MyCompany1table"
      ],
      "Sid": "AllowDYNAMODBDescribetable"
    }
  ]
}
```

------

以及以下内联 IAM 策略：

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-test-bucket/tenant1",
        "arn:aws:s3:::my-test-bucket/tenant1/*"
      ],
      "Sid": "AllowS3Getobject"
    },
    {
      "Effect": "Allow",
      "Action": [
        "logs:*",
        "dynamodb:*"
      ],
      "Resource": [
        "*"
      ],
      "Sid": "AllowLOGS"
    }
  ]
}
```

------

由此产生的权限 JobRun 为::

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-test-bucket/tenant1",
        "arn:aws:s3:::my-test-bucket/tenant1/*"
      ],
      "Sid": "AllowS3Getobject"
    },
    {
      "Effect": "Allow",
      "Action": [
        "logs:DescribeLogGroups"
      ],
      "Resource": [
        "arn:aws:logs:us-west-2:123456789012:log-group::log-stream"
      ],
      "Sid": "AllowLOGSDescribeloggroups"
    },
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:DescribeTable"
      ],
      "Resource": [
        "arn:aws:dynamodb:*:*:table/MyCompany1table"
      ],
      "Sid": "AllowDYNAMODBDescribetable"
    }
  ]
}
```

------

# 使用随机排序优化的磁盘
<a name="jobs-shuffle-optimized-disks"></a>

在 Amazon EMR 7.1.0 及更高版本中，在运行 Apache Spark 或 Hive 作业时使用经过洗牌优化的磁盘（以提高每秒操作的性能），以加快数据移动速度并减少洗牌I/O-intensive workloads. Compared to standard disks, shuffle-optimized disks provide higher IOPS (I/O操作期间的延迟。随机排序优化的磁盘允许为每个工作线程附加高达 2TB 的磁盘大小，因此请根据工作负载要求配置适当的容量。

## 主要优势
<a name="jobs-shuffle-optimized-disks-key-benefits"></a>

随机排序优化的磁盘具有以下优势。
+ **高 IOPS 性能**：随机排序优化的磁盘具有比标准磁盘更高的 IOPS，可在 Spark 和 Hive 作业以及其他随机排序密集型工作负载期间实现更高效、更快速的数据随机排序。
+ **磁盘容量更大**：随机排序优化的磁盘支持每个工作线程 20GB 到 2TB 的磁盘大小，因此请根据工作负载选择合适的容量。

## 开始使用
<a name="jobs-shuffle-optimized-disks-getting-started"></a>

要在工作流程中使用随机排序优化的磁盘，请参阅以下步骤。

------
#### [ Spark ]

1. 使用以下命令创建 EMR Serverless 7.1.0 版应用程序。

   ```
   aws emr-serverless create-application \
     --type "SPARK" \
     --name my-application-name \
     --release-label emr-7.1.0 \
     --region <AWS_REGION>
   ```

1. 配置您的 Spark 作业，使其包含要在经过洗牌优化的磁盘上运行的参数`spark.emr-serverless.driver.disk.type` and/or `spark.emr-serverless.executor.disk.type`。您可以使用一个或两个参数，具体取决于您的用例。

   ```
   aws emr-serverless start-job-run \
       --application-id application-id \
       --execution-role-arn job-role-arn \
       --job-driver '{
           "sparkSubmit": {
               "entryPoint": "/usr/lib/spark/examples/jars/spark-examples.jar",
               "entryPointArguments": ["1"],
               "sparkSubmitParameters": "--class org.apache.spark.examples.SparkPi 
               --conf spark.executor.cores=4 
               --conf spark.executor.memory=20g 
               --conf spark.driver.cores=4 
               --conf spark.driver.memory=8g 
               --conf spark.executor.instances=1 
               --conf spark.emr-serverless.executor.disk.type=shuffle_optimized"
           }
       }'
   ```

   有关更多信息，请参阅 [Spark 作业属性](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/jobs-spark.html#spark-defaults)。

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

1. 使用以下命令创建 EMR Serverless 7.1.0 版应用程序。

   ```
   aws emr-serverless create-application \
     --type "HIVE" \
     --name my-application-name \
     --release-label emr-7.1.0 \
     --region <AWS_REGION>
   ```

1. 配置您的 Hive 作业，使其包含要在经过洗牌`hive.driver.disk.type` and/or `hive.tez.disk.type`优化的磁盘上运行的参数。您可以使用一个或两个参数，具体取决于您的用例。

   ```
   aws emr-serverless start-job-run \
       --application-id application-id \
       --execution-role-arn job-role-arn \
       --job-driver '{
           "hive": {
               "query": "s3://<DOC-EXAMPLE-BUCKET>/emr-serverless-hive/query/hive-query.ql",
               "parameters": "--hiveconf hive.log.explain.output=false"
           }
       }' \
       --configuration-overrides '{
           "applicationConfiguration": [{
               "classification": "hive-site",
               "properties": {
                   "hive.exec.scratchdir": "s3://<DOC-EXAMPLE-BUCKET>/emr-serverless-hive/hive/scratch",
                   "hive.metastore.warehouse.dir": "s3://<DOC-EXAMPLE-BUCKET>/emr-serverless-hive/hive/warehouse",
                   "hive.driver.cores": "2",
                   "hive.driver.memory": "4g",
                   "hive.tez.container.size": "4096",
                   "hive.tez.cpu.vcores": "1",
                   "hive.driver.disk.type": "shuffle_optimized",
                   "hive.tez.disk.type": "shuffle_optimized"
               }
           }]
       }'
   ```

   有关更多信息，请参阅 [Hive 作业属性](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/jobs-hive.html#hive-defaults)。

------

**配置具有预初始化容量的应用程序**

请参阅以下示例，创建 Amazon EMR 7.1.0 版应用程序。这些应用程序具有以下属性：
+ 5 个预初始化的 Spark 驱动程序，每个都有 2 个 vCPU、4GB 内存和 50GB 随机排序优化的磁盘。
+ 50 个预初始化的执行程序，每个都有 4 个 vCPU、8GB 内存和 500GB 随机排序优化的磁盘。

当应用程序运行 Spark 作业时，会先使用预初始化的工作线程，然后将按需工作线程扩展到最大容量 400 个 vCPU 和 1024GB 内存。您可以选择忽略 `DRIVER` 或 `EXECUTOR` 的容量。

------
#### [ Spark ]

```
aws emr-serverless create-application \
  --type "SPARK" \
  --name <my-application-name> \
  --release-label emr-7.1.0 \
  --initial-capacity '{
    "DRIVER": {
        "workerCount": 5,
        "workerConfiguration": {
            "cpu": "2vCPU",
            "memory": "4GB",
            "disk": "50GB",
            "diskType": "SHUFFLE_OPTIMIZED"
        }
    },
    "EXECUTOR": {
        "workerCount": 50,
        "workerConfiguration": {
            "cpu": "4vCPU",
            "memory": "8GB",
            "disk": "500GB",
            "diskType": "SHUFFLE_OPTIMIZED"
        }
    }
  }' \
  --maximum-capacity '{
    "cpu": "400vCPU",
    "memory": "1024GB"
  }'
```

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

```
aws emr-serverless create-application \
  --type "HIVE" \
  --name <my-application-name> \
  --release-label emr-7.1.0 \
  --initial-capacity '{
    "DRIVER": {
        "workerCount": 5,
        "workerConfiguration": {
            "cpu": "2vCPU",
            "memory": "4GB",
            "disk": "50GB",
            "diskType": "SHUFFLE_OPTIMIZED"
        }
    },
    "EXECUTOR": {
        "workerCount": 50,
        "workerConfiguration": {
            "cpu": "4vCPU",
            "memory": "8GB",
            "disk": "500GB",
            "diskType": "SHUFFLE_OPTIMIZED"
        }
    }
  }' \
  --maximum-capacity '{
    "cpu": "400vCPU",
    "memory": "1024GB"
  }'
```

------

# 为 Amazon EMR 使用无服务器存储 Serverless
<a name="jobs-serverless-storage"></a>

在 Amazon EMR 7.12 及更高版本中，在运行 Apache Spark 任务时使用无服务器存储，以消除本地磁盘配置并降低数据处理成本，并防止由于磁盘容量限制而导致任务失败。Serverless 存储无需配置容量即可自动处理作业的洗牌、磁盘溢出和磁盘缓存操作，并免费存储中间数据。Amazon EMR Serverless 将中间数据存储在完全托管的无服务器存储中，该存储可根据工作负载需求自动扩展，并使 Spark 能够在空闲时立即释放计算工作人员，从而降低计算成本。

## 主要优势
<a name="jobs-serverless-storage-key-benefits"></a>

EMR Serverless 的无服务器存储具有以下优势。
+ **零配置存储** — 无服务器存储无需为每个应用程序或任务配置本地磁盘类型和大小。EMR Serverless 无需容量规划即可自动管理中间数据操作。
+ **通过自动扩展防止任务失败** — 存储容量可根据工作负载需求自动扩展，防止因磁盘容量不足而导致任务失败。
+ **降低数据处理成本** — 无服务器存储通过两种机制降低了处理成本。首先，中间数据存储是免费提供的，您只需为计算和内存资源付费。其次，将存储与 Spark 的动态资源分配分开后，Spark 能够在闲置时立即释放工作人员，而不是保留他们以将中间数据保留在本地磁盘上。这可以加快每个 Spark 阶段的横向扩展和缩小规模，从而降低后期阶段需要比初始阶段更少的工作人员的计算成本。
+ **具有作业级隔离功能的加密存储** — 所有中间数据在传输过程中和静态数据都经过严格的作业级隔离。
+ **精细访问控制支持** — 无服务器存储通过 AWS Lake Formation 集成支持精细的访问控制。

## 开始使用
<a name="jobs-serverless-storage-getting-started"></a>

要在 Spark 工作流程中使用适用于 EMR Serverless 的无服务器存储，请参阅以下步骤。

1. **创建 EMR 无服务器应用程序**

   通过在 spark-defaults 分类中将 spark 属性`spark.aws.serverlessStorage.enabled`设置为 **t** rue，创建启用无服务器存储的 EMR Serverless 7.12（或更高版本）应用程序。

   ```
   aws emr-serverless create-application \
     --type "SPARK" \
     --name my-application \
     --release-label emr-7.12.0 \
     --runtime-configuration '[{
         "classification": "spark-defaults",
           "properties": {
             "spark.aws.serverlessStorage.enabled": "true"
           }
       }]' \
     --region <AWS_REGION>
   ```

1. **开始一个 Spark 任务**

   开始在您的应用程序上运行作业。EMR 的无服务器存储 Serverless 会自动处理中间数据操作，例如作业的随机播放。

   ```
   aws emr-serverless start-job-run \
     --application-id <application-id> \
     --execution-role-arn <job-role-arn> \
     --job-driver '{
       "sparkSubmit": {
         "entryPoint": "s3://<bucket>/script.py",
         "sparkSubmitParameters": "--conf spark.executor.cores=4 
           --conf spark.executor.memory=20g 
           --conf spark.driver.cores=4 
           --conf spark.driver.memory=8g 
           --conf spark.executor.instances=10"
       }
     }'
   ```

   即使未在应用程序级别启用无服务器存储，您也可以在作业级别为 EMR Serverless 启用无服务器存储。这将启动启用了无服务器存储的工作节点来处理您的作业。您还可以通过将相同的 Spark 属性设置为 **false `spark.aws.serverlessStorage.enabled`** 来禁用特定作业的无服务器存储。

   ```
   # Turn on serverless storage for EMR serverless for a specific job
   aws emr-serverless start-job-run \
       --application-id <application-id> \
       --execution-role-arn <job-role-arn> \
       --job-driver '{
   "sparkSubmit": {
   "entryPoint": "/usr/lib/spark/examples/jars/spark-examples.jar",
               "entryPointArguments": ["1"],
               "sparkSubmitParameters": "--class org.apache.spark.examples.SparkPi
               --conf spark.aws.serverlessStorage.enabled": "true"
           }
       }'
   ```
**注意**  
要继续使用传统的本地磁盘配置，请省略`spark.aws.serverlessStorage.enabled`配置或将其设置为 **false**。

## 注意事项和限制
<a name="jobs-serverless-storage-limitations"></a>
+ **发布版本** — Amazon EMR 7.12 及更高版本支持无服务器存储。
+ **数据量限制** — 每个作业每次运行最多可以读取和写入 200 GB 的中间数据。超过此限制的任务将失败，并显示一条错误消息，表明已达到无服务器存储限制。
+ **任务执行超时** — 无服务器存储支持执行超时长达 24 小时的作业。为更长的执行超时配置的作业将失败并显示错误消息。
+ **预初始化容量** — 预初始化的容量工作人员不支持无服务器存储。配置预初始化容量时，只有在作业级别明确禁用无服务器存储的作业才会使用该容量。启用无服务器存储的作业将始终按需配置新的工作人员，并且无论应用程序级别的配置如何，都不会使用任何预先初始化的容量。
+ **工作负载类型**-流式处理和交互式作业不支持无服务器存储。
+ **工作器配置** — 使用 1 或 2 v CPUs 的工作器不支持无服务器存储。

## 支持 AWS 区域
<a name="jobs-serverless-storage-regions"></a>

EMR Serverless 支持以下区域的无服务器存储：
+ 美国东部（弗吉尼亚州北部）
+ 美国西部（俄勒冈州）
+ 欧洲地区（爱尔兰）

# 处理连续流数据的流处理作业
<a name="jobs-streaming"></a>

EMR Serverless 中的流处理作业是一种作业模式，可让您近乎实时地分析和处理流数据。这些长时间运行的作业会轮询流数据，并在数据到达时持续处理结果。流处理作业最适合需要实时数据处理的任务，如近实时分析、欺诈检测和推荐引擎。EMR Serverless 流处理作业提供了优化功能，如内置作业弹性、实时监控、增强的日志管理以及与流连接器的集成。

以下是流处理作业的一些用例：
+ **近实时分析**：Amazon EMR Serverless 中的流处理作业让您可以近乎实时地处理流数据，以便对日志数据、传感器数据或点击流数据等连续数据流执行实时分析，从而根据最新信息获得见解并及时做出决策。
+ **欺诈检测**：在分析数据流并发现可疑模式或异常情况时，可使用流处理作业对金融交易、信用卡业务或在线活动进行近乎实时的欺诈检测。
+ **推荐引擎**：流处理作业可以处理用户活动数据并更新推荐模型。这样可根据行为和偏好进行个性化的实时推荐。
+ **社交媒体分析**：流处理作业可以处理推文、评论和帖子等社交媒体数据，让组织近乎实时地监控趋势、分析情感和管理品牌声誉。
+ **物联网 (IoT) 分析**：流处理作业可以处理和分析来自物联网设备、传感器和连接机器的高速数据流，以便运行异常检测、预测性维护和其他物联网分析用例。
+ **点击流分析**：流处理作业可以处理和分析来自网站或移动应用程序的点击流数据。使用此类数据的企业可以进行分析，以深入了解用户行为、提供个性化用户体验、优化营销活动。
+ **日志监控和分析**：流处理作业还可以处理来自服务器、应用程序和网络设备的日志数据。为您提供异常检测、故障排除、系统运行状况和性能。

**主要优势**

EMR Serverless 中的流处理作业会自动提供作业*弹性*，这是以下因素组合的结果：
+ **自动重试**：EMR Serverless 会自动重试任何失败的作业，无需手动输入。
+ **可用区（AZ）弹性**：如果原始可用区出现问题，EMR Serverless 会自动将流处理作业切换到运行状况良好的可用区。
+ **日志管理：**
  + **日志轮换**：为了更有效地管理磁盘存储，EMR Serverless 会定期轮换长时间流处理作业的日志。这样可防止可能占用磁盘空间的日志累积。
  + **日志压缩**：帮助您有效管理和优化托管持久性中的日志文件。在使用托管 Spark History Server 时，压缩还可以改善调试体验。

**支持的数据来源和数据接收器**

EMR Serverless 可与多个输入数据来源和输出数据接收器配合使用：
+ 支持的输入数据来源：Amazon Kinesis Data Streams、Amazon Managed Streaming for Apache Kafka 和自我管理的 Apache Kafka 集群。默认情况下，Amazon EMR 7.1.0 及更高版本包含 [Amazon Kinesis Data Streams 连接器](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-spark-structured-streaming-kinesis.html)，因此您无需构建或下载任何其他软件包。
+ 支持的输出数据接收器 — AWS Glue 数据目录表、亚马逊 S3、亚马逊 Redshift、MySQL、PostgreSQL 甲骨文、甲骨文、微软 SQL、Apache Iceberg、Delta Lake 和 Apache Hudi。

## 注意事项和限制
<a name="jobs-spark-streaming-considerations"></a>

使用流处理作业时，请记住以下注意事项和限制。
+ [Amazon EMR 7.1.0 及更高版本](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-710-release.html)支持流处理作业。
+ EMR Serverless 期望流处理作业能长时间运行，因此无法设置执行超时来限制作业的运行时间。
+ 流处理作业仅与 Spark 引擎兼容，该引擎构建在[结构化流框架](https://spark.apache.org/streaming/)之上。
+ EMR Serverless 会无限期重试流处理作业，您无法自定义最大尝试次数。如果失败的尝试次数超过了每小时窗口内的阈值，则会自动包含防抖动功能。默认阈值为一小时内 5 次失败尝试。您可以将此阈值配置为 1 到 10 次尝试。有关更多信息，请参阅 [Job resiliency](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/SECTION-jobs-resiliency.xml.html)。
+ 流处理作业具有检查点来保存运行时状态和进度，因此 EMR Serverless 可以从最新的检查点恢复流处理作业。有关更多信息，请参阅 Apache Spark 文档中的 [Recovering from failures with Checkpointing](https://spark.apache.org/docs/latest/structured-streaming-programming-guide.html#recovering-from-failures-with-checkpointing)。

# 开始使用流处理作业
<a name="jobs-spark-streaming-getting-started"></a>

请参阅以下说明，了解如何开始使用流处理作业。

1. 要创建应用程序，请参阅[开始使用 Amazon EMR Serverless](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/getting-started.html)。请注意，您的应用程序必须运行 [Amazon EMR 7.1.0 或更高版本](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-710-release.html)。

1. 应用程序准备就绪后，将`mode`参数设置为`STREAMING`以提交流媒体作业，类似于以下 AWS CLI 示例。

   ```
   aws emr-serverless start-job-run \
   --application-id <APPPLICATION_ID> \
   --execution-role-arn <JOB_EXECUTION_ROLE> \
   --mode 'STREAMING' \
   --job-driver '{
       "sparkSubmit": {
           "entryPoint": "s3://<streaming script>",
           "entryPointArguments": ["s3://<DOC-EXAMPLE-BUCKET-OUTPUT>/output"],
           "sparkSubmitParameters": "--conf spark.executor.cores=4
               --conf spark.executor.memory=16g 
               --conf spark.driver.cores=4
               --conf spark.driver.memory=16g 
               --conf spark.executor.instances=3"
       }
   }'
   ```

# 支持的流处理连接器
<a name="jobs-spark-streaming-connectors"></a>

流处理连接器有助于从流处理源读取数据，也可以将数据写入流处理接收器。

以下是支持的流处理连接器：

**Amazon Kinesis Data Streams 连接器**

适用于 Apache Spark 的 [Amazon Kinesis Data Streams](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-spark-structured-streaming-kinesis.html) 连接器支持构建流处理应用程序和管道，这些应用程序和管道使用来自 Amazon Kinesis Data Streams 的数据并向其写入数据。该连接器支持增强的扇出消耗，每个分片的专用读取吞吐率高达 2MB/秒。默认情况下，Amazon EMR Serverless 7.1.0 及更高版本包含该连接器，因此您无需构建或下载任何其他软件包。有关连接器的更多信息，请参阅[上的 spark-sql-kinesis-connector页面 GitHub](https://github.com/awslabs/spark-sql-kinesis-connector/)。

以下示例展示了如何使用 Kinesis Data Streams 连接器依赖项启动作业运行。

```
aws emr-serverless start-job-run \
--application-id <APPLICATION_ID> \
--execution-role-arn <JOB_EXECUTION_ROLE> \
--mode 'STREAMING' \
--job-driver '{
    "sparkSubmit": {
        "entryPoint": "s3://<Kinesis-streaming-script>",
        "entryPointArguments": ["s3://<DOC-EXAMPLE-BUCKET-OUTPUT>/output"],
        "sparkSubmitParameters": "--conf spark.executor.cores=4
                --conf spark.executor.memory=16g 
                --conf spark.driver.cores=4
                --conf spark.driver.memory=16g 
                --conf spark.executor.instances=3
                --jars /usr/share/aws/kinesis/spark-sql-kinesis/lib/spark-streaming-sql-kinesis-connector.jar"
    }
}'
```

要连接到 Kinesis Data Streams，请将 EMR Serverless 应用程序配置为 VPC 访问，并使用 VPC 端点允许私有访问，或使用 NAT 网关进行公有访问。有关更多信息，请参阅[配置 VPC 访问](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/vpc-access.html)。您还必须确保作业运行时角色拥有访问所需数据流的必要读写权限。要了解有关如何配置作业运行时角色的更多信息，请参阅 [Amazon EMR Serverless 的作业运行时角色](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/security-iam-runtime-role.html)。有关所有必需权限的完整列表，请参阅[上的spark-sql-kinesis-connector 页面 GitHub](https://github.com/awslabs/spark-sql-kinesis-connector/?tab=readme-ov-file#how-to-use-it)。

**Apache Kafka 连接器**

适用于 Spark 结构化流处理的 Apache Kafka 连接器是来自 Spark 社区的开源连接器，可在 Maven 存储库中使用。此连接器有助于 Spark 结构化流处理应用程序从自我管理的 Apache Kafka 和 Amazon Managed Streaming for Apache Kafka 读取数据并向其写入数据。有关连接器的更多信息，请参阅 Apache Spark 文档中的[结构化流处理 \$1 Kafka 集成指南](https://spark.apache.org/docs/latest/structured-streaming-kafka-integration.html)。

以下示例演示了如何在作业运行请求中包含 Kafka 连接器。

```
aws emr-serverless start-job-run \
--application-id <APPLICATION_ID> \
--execution-role-arn <JOB_EXECUTION_ROLE> \
--mode 'STREAMING' \
--job-driver '{
    "sparkSubmit": {
        "entryPoint": "s3://<Kafka-streaming-script>",
        "entryPointArguments": ["s3://<DOC-EXAMPLE-BUCKET-OUTPUT>/output"],
        "sparkSubmitParameters": "--conf spark.executor.cores=4
                --conf spark.executor.memory=16g 
                --conf spark.driver.cores=4
                --conf spark.driver.memory=16g 
                --conf spark.executor.instances=3
                --packages org.apache.spark:spark-sql-kafka-0-10_2.12:<KAFKA_CONNECTOR_VERSION>"
    }
}'
```

Apache Kafka 连接器版本取决于 EMR Serverless 发行版和相应的 Spark 版本。要查找正确的 Kafka 版本，请参阅[结构化流处理 \$1 Kafka 集成指南](https://spark.apache.org/docs/latest/structured-streaming-kafka-integration.html)。

要将 Amazon Managed Streaming for Apache Kafka 与 IAM 身份验证结合使用，请包含另一个依赖项，以使 Kafka 连接器能够通过 IAM 连接到 Amazon MSK。有关更多信息，请参阅[上的aws-msk-iam-auth 存储库 GitHub](https://github.com/aws/aws-msk-iam-auth)。您还必须确保作业运行时角色拥有必要的 IAM 权限。以下示例演示了如何将连接器与 IAM 身份验证结合使用。

```
aws emr-serverless start-job-run \
--application-id <APPLICATION_ID> \
--execution-role-arn <JOB_EXECUTION_ROLE> \
--mode 'STREAMING' \
--job-driver '{
    "sparkSubmit": {
        "entryPoint": "s3://<Kafka-streaming-script>",
        "entryPointArguments": ["s3://<DOC-EXAMPLE-BUCKET-OUTPUT>/output"],
        "sparkSubmitParameters": "--conf spark.executor.cores=4
                --conf spark.executor.memory=16g 
                --conf spark.driver.cores=4
                --conf spark.driver.memory=16g 
                --conf spark.executor.instances=3
                --packages org.apache.spark:spark-sql-kafka-0-10_2.12:<KAFKA_CONNECTOR_VERSION>,software.amazon.msk:aws-msk-iam-auth:<MSK_IAM_LIB_VERSION>"
    }
}'
```

要使用 Kafka 连接器和 Amazon MSK 中的 IAM 身份验证库，请为 EMR Serverless 应用程序配置 VPC 访问。子网必须能够访问互联网，并使用 NAT 网关来访问 Maven 依赖项。有关更多信息，请参阅[配置 VPC 访问](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/vpc-access.html)。子网必须连接网络才能访问 Kafka 集群。无论您的 Kafka 集群是自我管理，还是使用 Amazon Managed Streaming for Apache Kafka，都是如此。

# 流处理作业日志管理
<a name="jobs-spark-streaming-log-management"></a>

流处理作业支持 Spark 应用程序日志和事件日志的日志轮换，以及 Spark 事件日志的日志压缩。这可以帮助您有效管理资源。

**日志轮换**

流处理作业支持 Spark 应用程序日志和事件日志的日志轮换。日志轮换可防止长时间流处理作业生成大型日志文件，占用可用磁盘空间。日志轮换可帮助您节省磁盘存储空间，并防止由于磁盘空间不足而导致作业失败。有关更多信息，请参阅[轮换日志](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/rotating-logs.html)。

**日志压缩**

当托管日志可用时，流处理作业还支持对 Spark 事件日志进行日志压缩。有关托管日志记录的更多详细信息，请参阅[使用托管存储进行日志记录](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/logging.html#jobs-log-storage-managed-storage)。流处理可以长时间运行，事件数据量会随着时间的推移而增加，并显著增加日志文件大小。Spark History Server 会读取这些事件，将其加载到 Spark 应用程序 UI 的内存中。此过程可能会产生高延迟和高成本，尤其是当 Amazon S3 中存储的事件日志非常大时。

日志压缩可减小事件日志的大小，因此 Spark History Server 在任何时候都不必加载超过 1GB 的事件日志。有关更多信息，请参阅 Apache Spark 文档中的[监控和仪表](https://spark.apache.org/docs/latest/monitoring.html)。

# 运行 EMR Serverless 作业时使用 Spark 配置
<a name="jobs-spark"></a>

您可以在 `type` 参数设置为 `SPARK` 的情况下在应用程序上运行 Spark 作业。作业必须与适用于 Amazon EMR 发行版的 Spark 版本兼容。例如，当您在 Amazon EMR 发行版 6.6.0 上运行作业时，作业必须与 Apache Spark 3.2.0 兼容。有关每个发行版的应用程序版本信息，请参阅 [Amazon EMR Serverless 发行版](release-versions.md)。

## Spark 作业参数
<a name="spark-params"></a>

使用 [`StartJobRun` API](https://docs.aws.amazon.com/emr-serverless/latest/APIReference/API_StartJobRun.html) 运行 Spark 作业时，请指定以下参数。

**Topics**
+ [

### Spark 作业运行时角色
](#spark-defaults-executionRoleArn)
+ [

### Spark 作业驱动程序参数
](#spark-defaults-jobDriver)
+ [

### Spark 配置覆盖参数
](#spark-defaults-configurationOverrides)
+ [

### Spark 动态资源分配优化
](#spark-defaults-dynamicResourceAllocation)

### Spark 作业运行时角色
<a name="spark-defaults-executionRoleArn"></a>

使用 **`executionRoleArn`** 指定应用程序用来执行 Spark 作业的 IAM 角色 ARN。此角色必须具有以下权限：
+ 从数据驻留的 S3 存储桶或其他数据来源读取数据
+ 从 PySpark 脚本或 JAR 文件所在的 S3 存储桶或前缀中读取
+ 写入要写入最终输出的 S3 存储桶
+ 将日志写入 `S3MonitoringConfiguration` 指定的 S3 存储桶或前缀
+ 访问 KMS 密钥（如果使用 KMS 密钥加密 S3 存储桶中的数据）
+ 如果你使用 sparkS AWS QL，则可以访问 Glue 数据目录

如果 Spark 作业从/向其他数据来源读取/写入数据，请在此 IAM 角色中指定相应的权限。如果不向 IAM 角色提供这些权限，作业可能会失败。有关更多信息，请参阅 [Amazon EMR Serverless 的作业运行时角色](security-iam-runtime-role.md) 和 [存储日志](logging.md)。

### Spark 作业驱动程序参数
<a name="spark-defaults-jobDriver"></a>

使用 **`jobDriver`** 为作业提供输入。对于要运行的作业类型，作业驱动程序参数只接受一个值。对于 Spark 作业，参数值为 `sparkSubmit`。您可以使用此作业类型通过 Spark 提交来运行 Scala PySpark、Java 和任何其他支持的作业。Spark 作业具有以下参数：
+ **`sparkSubmitParameters`**：这些是您希望发送给作业的其他 Spark 参数。使用此参数可覆盖默认 Spark 属性，例如驱动程序内存或执行程序数量，如 `--conf` 或 `--class` 参数中定义的属性。
+ **`entryPointArguments`**：这是您希望传递给主 JAR 或 Python 文件的参数数组。您应该使用 Entrypoint 代码来处理读取这些参数。用逗号分隔数组中的每个参数。
+ **`entryPoint`**：这是 Amazon S3 中对要运行的主 JAR 或 Python 文件的引用。如果您正在运行 Scala 或 Java JAR，请使用 `--class` 参数指定 `SparkSubmitParameters` 中的主入口类。

有关更多信息，请参阅[使用 spark-submit 启动应用程序](https://spark.apache.org/docs/latest/submitting-applications.html#launching-applications-with-spark-submit)。

### Spark 配置覆盖参数
<a name="spark-defaults-configurationOverrides"></a>

使用 **`configurationOverrides`** 覆盖监控级别和应用程序级别配置属性。该参数接受包含以下两个字段的 JSON 对象：
+ **`monitoringConfiguration`**：使用该字段指定希望 EMR Serverless 作业存储 Spark 作业日志的 Amazon S3 URL（`s3MonitoringConfiguration`）。请确保您创建此存储桶时使用的存储桶与托管应用程序的存储桶相同，且运行任务的 AWS 区域 位置相同。 AWS 账户 
+ **`applicationConfiguration`**：您可以在此字段中提供一个配置对象，来覆盖应用程序的默认配置。您可以使用简写语法提供配置，或可引用 JSON 文件中的配置对象。配置对象包含分类、属性和可选的嵌套配置。属性由您希望在该文件中覆盖的设置组成。您可以在一个 JSON 对象中为多个应用程序指定多个分类。
**注意**  
可用的配置分类因特定的 EMR Serverless 发行版而异。例如，自定义 Log4j `spark-driver-log4j2` 和 `spark-executor-log4j2` 的分类仅适用于 6.8.0 及更高版本。

如果在应用程序覆盖和 Spark 提交参数中使用相同的配置，则 Spark 提交参数优先。配置按优先级从高到低排列如下：
+ EMR Serverless 在创建 `SparkSession` 时提供的配置。
+ 使用 `--conf` 参数作为 `sparkSubmitParameters` 的一部分提供的配置。
+ 启动作业时，作为应用程序覆盖的一部分提供的配置。
+ 创建应用程序时，作为 `runtimeConfiguration` 的一部分提供的配置。
+ Amazon EMR 对发行版使用的优化配置。
+ 应用程序的默认开源配置。

有关在应用程序级别声明配置以及在作业运行期间覆盖配置的更多信息，请参阅 [EMR Serverless 的默认应用程序配置](default-configs.md)。

### Spark 动态资源分配优化
<a name="spark-defaults-dynamicResourceAllocation"></a>

使用 `dynamicAllocationOptimization` 优化 EMR Serverless 中的资源使用情况。在 Spark 配置分类中将此属性设置为 `true` 表示 EMR Serverless 需要优化执行程序资源分配，以便 Spark 请求和取消执行程序的速率与 EMR Serverless 创建和释放工作线程的速率更好地保持一致。这样，EMR Serverless 可以更好地跨阶段重用工作线程，从而在运行多阶段作业时降低成本，同时性能保持不变。

此属性适用于所有 Amazon EMR 发行版。

以下是使用 `dynamicAllocationOptimization` 进行配置分类的示例。

```
[
  {
    "Classification": "spark",
    "Properties": {
      "dynamicAllocationOptimization": "true"
    }
  }
]
```

如果使用动态分配优化，请考虑以下几点：
+ 此优化适用于您为其启用了动态资源分配的 Spark 作业。
+ 为实现最佳成本效益，我们建议根据工作负载情况，使用作业级别设置 `spark.dynamicAllocation.maxExecutors` 或[应用程序级最大容量](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/app-behavior.html#max-capacity)设置来配置工作线程的扩展上限。
+ 在简单的作业中，您可能看不到成本改善。例如，如果您的作业在一个小数据集上运行或在一个阶段内完成运行，Spark 可能不需要大量的执行程序或多个扩展事件。
+ 如果作业顺序是大阶段、小阶段然后又是大阶段，则作业运行时可能会出现回归。由于 EMR Serverless 能有效使用资源，可能会导致大阶段的可用工作线程减少，从而延长运行时间。

## Spark 作业属性
<a name="spark-defaults"></a>

下表列出了提交 Spark 作业时可以覆盖的可选 Spark 属性及其默认值。


**可选 Spark 属性和默认值**  

| Key | 说明 | 默认 值 | 
| --- | --- | --- | 
| spark.archives | 以逗号分隔的存档列表，Spark 将其提取到每个执行程序的工作目录中。支持的文件类型包括 .jar、 .tar.gz、.tgz 和 .zip。若要指定要提取的目录名，请在要提取的文件名后添加 \$1。例如 file.zip\$1directory。 | NULL | 
| spark.authenticate | 开启 Spark 内部连接身份验证的选项。 | TRUE | 
| spark.driver.cores | 驱动程序使用的核心数。 | 4 | 
| spark.driver.extraJavaOptions | Spark 驱动程序的额外 Java 选项。 | NULL | 
| spark.driver.memory | 驱动程序使用的内存量。 | 14G | 
| spark.dynamicAllocation.enabled | 开启动态资源分配的选项。此选项可根据工作负载扩展或缩减在应用程序中注册的执行程序数量。 | TRUE | 
| spark.dynamicAllocation.executorIdleTimeout | 在 Spark 将其删除之前，执行程序可保持空闲状态的时间长度。这仅适用于开启动态分配的情况。 | 60s | 
| spark.dynamicAllocation.initialExecutors | 开启动态分配时要运行的初始执行程序数量。 | 3 | 
| spark.dynamicAllocation.maxExecutors | 如果开启动态分配，则表示执行程序数量的上限。 | 对于 6.10.0 及更高版本，`infinity` 对于 6.9.0 及更低版本，`100`  | 
| spark.dynamicAllocation.minExecutors | 如果开启动态分配，则表示执行程序数量的下限。 | 0 | 
| spark.emr-serverless.allocation.batch.size | 在每个执行程序分配周期中请求的容器数。每个分配周期之间有一秒的间隔。 | 20 | 
| spark.emr-serverless.driver.disk | Spark 驱动程序磁盘。 | 20G | 
| spark.emr-serverless.driverEnv.[KEY] | 为 Spark 驱动程序添加环境变量的选项。 | NULL | 
| spark.emr-serverless.executor.disk | Spark 执行程序磁盘。 | 20G | 
| spark.emr-serverless.memoryOverheadFactor | 设置要添加到驱动程序和执行程序容器内存的内存开销。 | 0.1 | 
| spark.emr-serverless.driver.disk.type | 附加到 Spark 驱动程序的磁盘类型。 | 标准 | 
| spark.emr-serverless.executor.disk.type | 附加到 Spark 执行程序的磁盘类型。 | 标准 | 
| spark.executor.cores | 每个执行程序使用的核心数。 | 4 | 
| spark.executor.extraJavaOptions | Spark 执行程序的额外 Java 选项。 | NULL | 
| spark.executor.instances | 要分配的 Spark 执行程序容器的数量。 | 3 | 
| spark.executor.memory | 每个执行程序使用的内存量。 | 14G | 
| spark.executorEnv.[KEY] | 向 Spark 执行程序添加环境变量的选项。 | NULL | 
| spark.files | 以逗号分隔的文件列表，这些文件放置在每个执行程序的工作目录中。您可以使用 SparkFiles.get(fileName) 在执行程序中访问这些文件的路径。 | NULL | 
| spark.hadoop.hive.metastore.client.factory.class | Hive 元存储实现类。 | NULL | 
| spark.jars | 添加到驱动程序和执行程序的运行时类路径中的其他 jar 文件。 | NULL | 
| spark.network.crypto.enabled | 开启基于 AES 的 RPC 加密的选项。这包括 Spark 2.2.0 中添加的身份验证协议。 | FALSE | 
| spark.sql.warehouse.dir | 托管数据库和表的默认位置。 | \$1PWD/spark-warehouse 的值 | 
| spark.submit.pyFiles | 以逗号分隔的 .zip、.egg 或  .py 文件列表，这些文件放置在 Python 应用程序的 PYTHONPATH 中。 | NULL | 

下表列出了默认的 Spark 提交参数。


**默认 Spark 提交参数**  

| Key | 说明 | 默认 值 | 
| --- | --- | --- | 
| archives | 以逗号分隔的存档列表，Spark 将其提取到每个执行程序的工作目录中。 | NULL | 
| class | 应用程序的主类（适用于 Java 和 Scala 应用程序）。 | NULL | 
| conf | 任意 Spark 配置属性。 | NULL | 
| driver-cores | 驱动程序使用的核心数。 | 4 | 
| driver-memory | 驱动程序使用的内存量。 | 14G | 
| executor-cores | 每个执行程序使用的核心数。 | 4 | 
| executor-memory | 执行程序使用的内存量。 | 14G | 
| files | 以逗号分隔的文件列表，这些文件放置在每个执行程序的工作目录中。您可以使用 SparkFiles.get(fileName) 在执行程序中访问这些文件的路径。 | NULL | 
| jars | 以逗号分隔的 jar 文件列表，这些文件包含在驱动程序和执行程序的类路径上。 | NULL | 
| num-executors | 要启动的执行程序数。 | 3 | 
| py-files | 以逗号分隔的 .zip、.egg 或 .py 文件列表，这些文件放置在 Python 应用程序的 PYTHONPATH 中。 | NULL | 
| verbose | 开启其他调试输出的选项。 | NULL | 

## 资源配置最佳实践
<a name="spark-configuring-driver-executor-resources"></a>

### 通过 API 配置驱动程序和执行器资源 StartJobRun
<a name="spark-configuring-driver-executor-resources"></a>

**注意**  
Spark 驱动程序和执行器内核以及内存属性（如果已指定）必须在 StartJobRun API 请求中直接指定。

通过这种方式配置资源可确保 EMR Serverless 在运行作业之前分配正确的资源。这与用户脚本中提供的设置（例如 .py 或 .jar 文件）形成对比，这些设置评估得太晚，因为驱动程序和执行程序工作线程有时会在脚本执行开始之前预置。在提交作业时，可通过两种受支持的方式配置这些资源：

#### 选项 1：使用 sparkSubmitParameters
<a name="-spark-option-sparksubmitparameters"></a>

```
"jobDriver": {
 "sparkSubmit": {
    "entryPoint": "s3://your-script-path.py",
    "sparkSubmitParameters": "—conf spark.driver.memory=4g \
    —conf spark.driver.cores=2 \
    —conf spark.executor.memory=8g \
    —conf spark.executor.cores=4"
  }
 }
```

#### 选项 2：使用 configurationOverrides 进行 spark-defaults 分类
<a name="spark-option2configurationoverrides"></a>

```
"configurationOverrides": {
 "applicationConfiguration": [
 {
 "classification": "spark-defaults",
 "properties": {
     "spark.driver.memory": "4g",
     "spark.driver.cores": "2",
     "spark.executor.memory": "8g",
     "spark.executor.cores": "4"
      }
    }
  ]
 }
```

## Spark 示例
<a name="spark-examples"></a>

下面的示例展示了如何使用 `StartJobRun` API 运行 Python 脚本。有关使用此示例的 end-to-end教程，请参阅[开始使用 Amazon EMR Serverless](getting-started.md)。您可以在 [EMR Serverles](https://github.com/aws-samples/emr-serverless-samples/tree/main/examples/pyspark) s 示例存储库中找到有关如何运行 PySpark 作业和添加 Python 依赖关系的其他示例。 GitHub 

```
aws emr-serverless start-job-run \
    --application-id application-id \
    --execution-role-arn job-role-arn \
    --job-driver '{
        "sparkSubmit": {
            "entryPoint": "s3://us-east-1.elasticmapreduce/emr-containers/samples/wordcount/scripts/wordcount.py",
            "entryPointArguments": ["s3://amzn-s3-demo-destination-bucket/wordcount_output"],
            "sparkSubmitParameters": "--conf spark.executor.cores=1 --conf spark.executor.memory=4g --conf spark.driver.cores=1 --conf spark.driver.memory=4g --conf spark.executor.instances=1"
        }
    }'
```

下面的示例展示了如何使用 `StartJobRun` API 运行 Spark JAR。

```
aws emr-serverless start-job-run \
    --application-id application-id \
    --execution-role-arn job-role-arn \
    --job-driver '{
        "sparkSubmit": {
            "entryPoint": "/usr/lib/spark/examples/jars/spark-examples.jar",
            "entryPointArguments": ["1"],
            "sparkSubmitParameters": "--class org.apache.spark.examples.SparkPi --conf spark.executor.cores=4 --conf spark.executor.memory=20g --conf spark.driver.cores=4 --conf spark.driver.memory=8g --conf spark.executor.instances=1"
        }
    }'
```

# 运行 EMR Serverless 作业时使用 Hive 配置
<a name="jobs-hive"></a>

您可以在 `type` 参数设置为 `HIVE` 的情况下在应用程序上运行 Hive 作业。作业必须与适用于 Amazon EMR 发行版的 Hive 版本兼容。例如，当您在 Amazon EMR 发行版 6.6.0 的应用程序上运行作业时，作业必须与 Apache Hive 3.1.2 兼容。有关每个发行版的应用程序版本信息，请参阅 [Amazon EMR Serverless 发行版](release-versions.md)。

## Hive 作业参数
<a name="hive-params"></a>

使用 [`StartJobRun` API](https://docs.aws.amazon.com/emr-serverless/latest/APIReference/API_StartJobRun.html) 运行 Hive 作业时，请指定以下参数。

**Topics**
+ [

### Hive 作业运行时角色
](#hive-defaults-executionRoleArn)
+ [

### Hive 作业驱动程序参数
](#hive-defaults-jobDriver)
+ [

### Hive 配置覆盖参数
](#hive-defaults-configurationOverrides)

### Hive 作业运行时角色
<a name="hive-defaults-executionRoleArn"></a>

使用 **`executionRoleArn`** 指定应用程序用来执行 Hive 作业的 IAM 角色 ARN。此角色必须具有以下权限：
+ 从数据驻留的 S3 存储桶或其他数据来源读取数据
+ 从 Hive 查询文件和 init 查询文件驻留的 S3 存储桶或前缀读取数据
+ 读取和写入 Hive Scratch 目录和 Hive Metastore 仓库目录驻留的 S3 存储桶
+ 写入要写入最终输出的 S3 存储桶
+ 将日志写入 `S3MonitoringConfiguration` 指定的 S3 存储桶或前缀
+ 访问 KMS 密钥（如果使用 KMS 密钥加密 S3 存储桶中的数据）
+ 访问 AWS Glue 数据目录

如果 Hive 作业从/向其他数据来源读取/写入数据，请在此 IAM 角色中指定相应的权限。如果不向 IAM 角色提供这些权限，作业可能会失败。有关更多信息，请参阅[Amazon EMR Serverless 的作业运行时角色](security-iam-runtime-role.md)。

### Hive 作业驱动程序参数
<a name="hive-defaults-jobDriver"></a>

使用 **`jobDriver`** 为作业提供输入。对于要运行的作业类型，作业驱动程序参数只接受一个值。当您指定 `hive` 为作业类型时，EMR Serverless 会将 Hive 查询传递给 `jobDriver` 参数。Hive 作业具有以下参数：
+ **`query`**：这是 Amazon S3 中对要运行的 Hive 查询文件的引用。
+ **`parameters`**：这些是要覆盖的其他 Hive 配置属性。要覆盖属性，请将其作为 `--hiveconf property=value` 传递给此参数。要覆盖变量，请将其作为 `--hivevar key=value` 传递给此参数。
+ **`initQueryFile`**：这是初始化 Hive 查询文件。Hive 会在查询之前运行该文件，并用其初始化表。

### Hive 配置覆盖参数
<a name="hive-defaults-configurationOverrides"></a>

使用 **`configurationOverrides`** 覆盖监控级别和应用程序级别配置属性。该参数接受包含以下两个字段的 JSON 对象：
+ **`monitoringConfiguration`**：使用该字段指定希望 EMR Serverless 作业存储 Hive 作业日志的 Amazon S3 URL（`s3MonitoringConfiguration`）。请务必使用托管应用程序的存储桶以及运行任务的相同 AWS 区域 位置创建此存储桶。 AWS 账户 
+ **`applicationConfiguration`**：您可以在此字段中提供一个配置对象，来覆盖应用程序的默认配置。您可以使用简写语法提供配置，或可引用 JSON 文件中的配置对象。配置对象包含分类、属性和可选的嵌套配置。属性由您希望在该文件中覆盖的设置组成。您可以在一个 JSON 对象中为多个应用程序指定多个分类。
**注意**  
可用的配置分类因特定的 EMR Serverless 发行版而异。例如，自定义 Log4j `spark-driver-log4j2` 和 `spark-executor-log4j2` 的分类仅适用于 6.8.0 及更高版本。

如果在应用程序覆盖和 Hive 参数中传递相同的配置，则 Hive 参数优先。以下列表按优先级从高到低对配置进行排序。
+ 作为 `--hiveconf property=value` 中 Hive 参数的一部分提供的配置。
+ 启动作业时，作为应用程序覆盖的一部分提供的配置。
+ 创建应用程序时，作为 `runtimeConfiguration` 的一部分提供的配置。
+ Amazon EMR 为发行版分配的优化配置。
+ 应用程序的默认开源配置。

有关在应用程序级别声明配置以及在作业运行期间覆盖配置的更多信息，请参阅 [EMR Serverless 的默认应用程序配置](default-configs.md)。

## Hive 作业属性
<a name="hive-defaults"></a>

下表列出了在提交 Hive 作业时配置的必需属性。


**必需 Hive 作业属性**  

| 设置 | 说明 | 
| --- | --- | 
| hive.exec.scratchdir | EMR Serverless 在 Hive 作业执行期间创建临时文件的 Amazon S3 位置。 | 
| hive.metastore.warehouse.dir | Hive 中托管表数据库的 Amazon S3 位置。 | 

下表列出了提交 Hive 作业时可以覆盖的可选 Hive 属性及其默认值。


**可选 Hive 属性和默认值**  

| 设置 | 说明 | 默认 值 | 
| --- | --- | --- | 
| fs.s3.customAWSCredentialsProvider | 您要使用的 AWS 凭证提供商。 | com.amazonaws.auth.de AWSCredentials ProviderChain | 
| fs.s3a.aws.credentials.provider | 您要用于 S3A 文件系统的 AWS 凭证提供程序。 | com.amazonaws.auth.de AWSCredentials ProviderChain | 
| hive.auto.convert.join | 根据输入文件大小，将普通连接自动转换为 mapjoin 的选项。 | TRUE | 
| hive.auto.convert.join.noconditionaltask | 当 Hive 根据输入文件大小将普通连接转换为 mapjoin 时，开启优化的选项。 | TRUE | 
| hive.auto.convert.join.noconditionaltask.size | 低于此大小时，连接会直接转换为 mapjoin。 | 最优值是基于 Tez 任务内存计算的 | 
| hive.cbo.enable | 使用 Calcite 框架开启成本优化的选项。 | TRUE | 
| hive.cli.tez.session.async | 在 Hive 查询编译时启动后台 Tez 会话的选项。设置为 false 时，Tez AM 将在 Hive 查询编译后启动。 | TRUE | 
| hive.compute.query.using.stats | 激活 Hive 以使用元存储中存储的统计数据回答某些查询的选项。对于基本统计数据，将 hive.stats.autogather 设置为 TRUE。要获取更高级的查询集合，请运行 analyze table queries。 | TRUE | 
| hive.default.fileformat | CREATE TABLE 语句的默认文件格式。如果您在 CREATE TABLE 命令中指定 STORED AS [FORMAT]，则可以显式覆盖此设置。 | TEXTFILE | 
| hive.driver.cores | Hive 驱动程序进程使用的核心数。 | 2 | 
| hive.driver.disk | Hive 驱动程序的磁盘大小。 | 20G | 
| hive.driver.disk.type | Hive 驱动程序的磁盘类型。 | 标准 | 
| hive.tez.disk.type | Tez 工作线程的磁盘大小。 | 标准 | 
| hive.driver.memory | 每个 Hive 驱动程序进程使用的内存量。Hive CLI 和 Tez Application Master 均摊此内存，并保留 20% 的余量。 | 6G | 
| hive.emr-serverless.launch.env.[KEY] | 在 Hive 特定进程（如 Hive 驱动程序、Tez AM 和 Tez 任务）中设置 KEY 环境变量的选项。 |  | 
| hive.exec.dynamic.partition | 在 DML/DDL 中开启动态分区的选项。 | TRUE | 
| hive.exec.dynamic.partition.mode | 指定是要使用严格模式还是非严格模式的选项。在严格模式下，至少指定一个静态分区，以免意外覆盖所有分区。在非严格模式下，允许所有分区都是动态的。 | strict | 
| hive.exec.max.dynamic.partitions | Hive 创建的最大动态分区数。 | 1000 | 
| hive.exec.max.dynamic.partitions.pernode | Hive 在每个 mapper 和 reducer 节点中创建的最大动态分区数。 | 100 | 
| hive.exec.orc.split.strategy | 预计为下列值之一：BI、ETL 或 HYBRID。这不是用户级配置。BI 指定您希望在拆分生成上花费的时间比在查询执行上花费的时间更少。ETL 指定您希望在拆分生成上花费更多时间。HYBRID 指定根据启发式方法从上述策略中选择。 | HYBRID | 
| hive.exec.reducers.bytes.per.reducer | 每个 reducer 的大小。默认值为 256MB。如果输入大小为 1G，作业将使用 4 个 reducer。 | 256000000 | 
| hive.exec.reducers.max | 最大 reducer 数。 | 256 | 
| hive.exec.stagingdir | 存储临时文件的目录的名称，Hive 在表位置和 hive.exec.scratchdir 属性中指定的暂存目录位置中创建这些临时文件。 | .hive-staging | 
| hive.fetch.task.conversion | 预计为下列值之一：NONE、MINIMAL 或 MORE。Hive 可以将选定查询转换为单个 FETCH 任务。这样可以最大限度地减少延迟。 | MORE | 
| hive.groupby.position.alias | 使 Hive 在 GROUP BY 语句中使用列位置别名的选项。 | FALSE | 
| hive.input.format | 默认输入格式。如果在使用 CombineHiveInputFormat 时遇到问题，请设置为 HiveInputFormat。 | org.apache.hadoop.hive.ql.io.CombineHiveInputFormat | 
| hive.log.explain.output | 为 Hive 日志中的任何查询开启扩展输出解释的选项。 | FALSE | 
| hive.log.level | Hive 日志记录级别。 | INFO | 
| hive.mapred.reduce.tasks.speculative.execution | 为 reducer 开启推测性启动的选项。仅 Amazon EMR 6.10.x 及更低版本支持。 | TRUE | 
| hive.max-task-containers | 最大并发容器数。将配置的 mapper 内存乘以该值，确定拆分计算和任务抢占使用的可用内存。 | 1000 | 
| hive.merge.mapfiles | 使小文件在仅映射作业结束时合并的选项。 | TRUE | 
| hive.merge.size.per.task | 作业结束时合并文件的大小。 | 256000000 | 
| hive.merge.tezfiles | 在 Tez DAG 结束时开启小文件合并的选项。 | FALSE | 
| hive.metastore.client.factory.class | 生成对象以实现 IMetaStoreClient 接口的工厂类名称。 | com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory | 
| hive.metastore.glue.catalogid | 如果 AWS Glue Data Catalog 充当元存储但运行在与作业 AWS 账户 不同的位置，则为作业运行 AWS 账户 位置的 ID。 | NULL | 
| hive.metastore.uris | 元存储客户端用于连接到远程元存储的 thrift URI。 | NULL | 
| hive.optimize.ppd | 开启谓词下推的选项。 | TRUE | 
| hive.optimize.ppd.storage | 开启对存储处理程序谓词下推的选项。 | TRUE | 
| hive.orderby.position.alias | 使 Hive 在 ORDER BY 语句中使用列位置别名的选项。 | TRUE | 
| hive.prewarm.enabled | 为 Tez 开启容器预热的选项。 | FALSE | 
| hive.prewarm.numcontainers | 为 Tez 预热的容器数量。 | 10 | 
| hive.stats.autogather | 使 Hive 在 INSERT OVERWRITE 命令执行期间自动收集基本统计数据的选项。 | TRUE | 
| hive.stats.fetch.column.stats | 关闭从元数据仓获取列统计数据的选项。当列数很大时，获取列统计数据的开销会很大。 | FALSE | 
| hive.stats.gather.num.threads | partialscan 和 noscan analyze 命令用于分区表的线程数。这仅适用于实现 StatsProvidingRecordReader 的文件格式（如 ORC）。 | 10 | 
| hive.strict.checks.cartesian.product | 开启严格笛卡尔连接检查的选项。这些检查不允许使用笛卡尔乘积（交叉连接）。 | FALSE | 
| hive.strict.checks.type.safety | 开启严格类型安全检查，并关闭 bigint 与 string 和 double 比较的选项。 | TRUE | 
| hive.support.quoted.identifiers | 预期值为 NONE 或 COLUMN。NONE 意味着标识符中只有字母数字和下划线字符有效。COLUMN 意味着列名可以包含任何字符。 | COLUMN | 
| hive.tez.auto.reducer.parallelism | 开启 Tez auto-reducer 并行度功能的选项。Hive 仍会估计数据大小并设置并行度估计。Tez 会对源顶点的输出大小进行采样，并在运行时根据需要调整估计值。 | TRUE | 
| hive.tez.container.size | 每个 Tez 任务进程使用的内存量。 | 6144 | 
| hive.tez.cpu.vcores | 每个 Tez 任务使用的核心数。 | 2 | 
| hive.tez.disk.size | 每个任务容器的磁盘大小。 | 20G | 
| hive.tez.input.format | Tez AM 中拆分生成的输入格式。 | org.apache.hadoop.hive.ql.io.HiveInputFormat | 
| hive.tez.min.partition.factor | Tez 在开启 auto-reducer 并行度时指定的 reducer 下限。 | 0.25 | 
| hive.vectorized.execution.enabled | 开启查询执行的向量化模式的选项。 | TRUE | 
| hive.vectorized.execution.reduce.enabled | 开启查询执行 reduce-side 的向量化模式的选项。 | TRUE | 
| javax.jdo.option.ConnectionDriverName | JDBC 元存储的驱动程序类名称。 | org.apache.derby.jdbc.EmbeddedDriver | 
| javax.jdo.option.ConnectionPassword | 与元存储数据库关联的密码。 | NULL | 
| javax.jdo.option.ConnectionURL | JDBC 元存储的 JDBC 连接字符串。 | jdbc:derby:;databaseName=metastore\$1db;create=true | 
| javax.jdo.option.ConnectionUserName | 与元存储数据库关联的用户名。 | NULL | 
| mapreduce.input.fileinputformat.split.maxsize | 当输入格式为 org.apache.hadoop.hive.ql.io.CombineHiveInputFormat 时，拆分计算时拆分的最大大小。值为 0 表示没有限制。 | 0 | 
| tez.am.dag.cleanup.on.completion | 在 DAG 完成时开启随机排序数据清理的选项。 | TRUE | 
| tez.am.emr-serverless.launch.env.[KEY] | 在 Tez AM 进程中设置 KEY 环境变量的选项。对于 Tez AM，此值将覆盖 hive.emr-serverless.launch.env.[KEY] 值。 |  | 
| tez.am.log.level | EMR Serverless 传递给 Tez 应用程序主进程的根日志记录级别。 | INFO | 
| tez.am.sleep.time.before.exit.millis | EMR Serverless 应在 AM 关闭请求发出后的这段时间后推送 ATS 事件。 | 0 | 
| tez.am.speculation.enabled | 使较慢任务推测性启动的选项。当某些任务因机器故障或速度缓慢而运行较慢时，这有助于减少作业延迟。仅 Amazon EMR 6.10.x 及更低版本支持。 | FALSE | 
| tez.am.task.max.failed.attempts | 在任务失败之前，特定任务可以失败的最大尝试次数。此数字不计入手动终止的尝试次数。 | 3 | 
| tez.am.vertex.cleanup.height | 如果所有从属顶点都已完成，Tez AM 将删除顶点随机排序数据的距离。值为 0 时，此功能关闭。Amazon EMR 6.8.0 及更高版本支持此功能。 | 0 | 
| tez.client.asynchronous-stop | 使 EMR Serverless 在结束 Hive 驱动程序之前推送 ATS 事件的选项。 | FALSE | 
| tez.grouping.max-size | 分组拆分的大小上限（字节）。此限制可防止过大的拆分。 | 1073741824 | 
| tez.grouping.min-size | 分组拆分的大小下限（字节）。此限制可防止过小的拆分。 | 16777216 | 
| tez.runtime.io.sort.mb | Tez 对输出排序时软缓冲区的大小。 | 最优值是基于 Tez 任务内存计算的 | 
| tez.runtime.unordered.output.buffer.size-mb | Tez 不直接写入磁盘时使用的缓冲区大小。 | 最优值是基于 Tez 任务内存计算的 | 
| tez.shuffle-vertex-manager.max-src-fraction | 在 EMR Serverless 为当前顶点安排所有任务之前必须完成的源任务的比例（在 ScatterGather 连接的情况下）。当前顶点上准备安排的任务数量在 min-fraction 和 max-fraction 之间线性缩放。这将为默认值或 tez.shuffle-vertex-manager.min-src-fraction，以较大者为准。 | 0.75 | 
| tez.shuffle-vertex-manager.min-src-fraction | 在 EMR Serverless 为当前顶点安排任务之前必须完成的源任务的比例（在 ScatterGather 连接的情况下）。 | 0.25 | 
| tez.task.emr-serverless.launch.env.[KEY] | 在 Tez 任务进程中设置 KEY 环境变量的选项。对于 Tez 任务，此值将覆盖 hive.emr-serverless.launch.env.[KEY] 值。 |  | 
| tez.task.log.level | EMR Serverless 传递给 Tez 任务的根日志记录级别。 | INFO | 
| tez.yarn.ats.event.flush.timeout.millis | AM 在关闭之前等待事件刷新的最长时间。 | 300000 | 

## Hive 作业示例
<a name="hive-examples"></a>

下面的代码示例展示了如何使用 `StartJobRun` API 运行 Hive 查询。

```
aws emr-serverless start-job-run \
    --application-id application-id \
    --execution-role-arn job-role-arn \
    --job-driver '{
        "hive": {
            "query": "s3://amzn-s3-demo-bucket/emr-serverless-hive/query/hive-query.ql",
            "parameters": "--hiveconf hive.log.explain.output=false"
        }
    }' \
    --configuration-overrides '{
        "applicationConfiguration": [{
            "classification": "hive-site",
            "properties": {
                "hive.exec.scratchdir": "s3://amzn-s3-demo-bucket/emr-serverless-hive/hive/scratch",
                "hive.metastore.warehouse.dir": "s3://amzn-s3-demo-bucket/emr-serverless-hive/hive/warehouse",
                "hive.driver.cores": "2",
                "hive.driver.memory": "4g",
                "hive.tez.container.size": "4096",
                "hive.tez.cpu.vcores": "1"
            }
        }]
    }'
```

您可以在 [EMR Serverless](https://github.com/aws-samples/emr-serverless-samples/tree/main/examples/hive) GitHub 示例存储库中找到有关如何运行 Hive 作业的其他示例。

# EMR Serverless 作业弹性
<a name="jobs-resiliency"></a>

 EMR Serverless 7.1.0 及更高版本包含对作业弹性的支持，可自动重试任何失败的作业，而无需任何手动输入。作业弹性的另一个好处是，如果一个可用区（AZ）出现任何问题，EMR Serverless 会将作业运行转移到其他可用区（AZ）。

要为作业启用作业弹性，请设置作业的重试策略。重试策略可确保 EMR Serverless 在作业失败时自动重启作业。批处理和流处理作业均支持重试策略，因此请根据自己的使用案例自定义作业弹性。下表对比了批处理和流处理作业在作业弹性方面的行为和差异。


|  | 批处理作业 | 流处理作业 | 
| --- | --- | --- | 
| 默认 行为 | 不重新运行作业。 | 始终重试运行作业，因为应用程序会在运行作业时创建检查点。 | 
| 重试点 | 批处理作业没有检查点，因此 EMR Serverless 总是从头开始重新运行作业。 | 流处理作业支持检查点，因此请配置流查询，将运行时状态和进度保存到 Amazon S3 中的检查点位置。EMR Serverless 从检查点恢复作业运行。有关更多信息，请参阅 Apache Spark 文档中的[使用检查点从故障中恢复](https://spark.apache.org/docs/latest/structured-streaming-programming-guide.html#recovering-from-failures-with-checkpointing)。 | 
| 最大重试次数 | 最多允许重试 10 次。 | 流处理作业具有内置的防抖动控制，因此如果作业在一小时后继续失败，应用程序将停止重试作业。一小时内的默认重试次数为 5 次。您可以将重试次数配置为 1 或 10 之间。无法自定义最大尝试次数。值为 1 表示不重试。 | 

当 EMR Serverless 尝试重新运行作业时，还会使用尝试编号对该作业编制索引，以便跟踪作业尝试期间的生命周期。

使用 EMR Serverless API 操作或 AWS CLI 更改工作弹性或访问与工作弹性相关的信息。有关更多信息，请参阅 [EMR Serverless API 指南](https://docs.aws.amazon.com/emr-serverless/latest/APIReference/Welcome.html)。

默认情况下，EMR Serverless 不会重新运行批处理作业。要启用批处理作业重试，请在开始批处理作业运行时配置 `maxAttempts` 参数。`maxAttempts` 参数仅适用于批处理作业。默认值为 1，表示不重新运行作业。可接受的值为 1 到 10（含）。

以下示例演示了如何在启动作业运行时指定最多尝试 10 次。

```
aws emr-serverless start-job-run
 --application-id <APPLICATION_ID> \
 --execution-role-arn <JOB_EXECUTION_ROLE> \
 --mode 'BATCH' \
 --retry-policy '{
    "maxAttempts": 10
 }' \
 --job-driver '{
    "sparkSubmit": {
         "entryPoint": "/usr/lib/spark/examples/jars/spark-examples-does-not-exist.jar",
         "entryPointArguments": ["1"],
         "sparkSubmitParameters": "--class org.apache.spark.examples.SparkPi"
     }
}'
```

如果流处理作业失败，EMR Serverless 会无限期重试。要防止因重复出现无法恢复的故障而导致中断，可使用 `maxFailedAttemptsPerHour` 为流处理作业重试配置防抖动控制。通过该参数，您可以指定在 EMR Serverless 停止重试前一小时内允许的最大失败尝试次数。默认为 5 次。可接受的值为 1 到 10（含）。

```
aws emr-serverless start-job-run
 --application-id <APPPLICATION_ID> \
 --execution-role-arn <JOB_EXECUTION_ROLE> \
 --mode 'STREAMING' \
 --retry-policy '{
    "maxFailedAttemptsPerHour": 7
 }' \
 --job-driver '{
    "sparkSubmit": {
         "entryPoint": "/usr/lib/spark/examples/jars/spark-examples-does-not-exist.jar",
         "entryPointArguments": ["1"],
         "sparkSubmitParameters": "--class org.apache.spark.examples.SparkPi"
     }
}'
```

您还可以使用其他作业运行 API 操作来获取有关作业的信息。例如，将 `attempt` 参数与 `GetJobRun` 操作一起使用，以获取有关特定作业尝试的详细信息。如果不包含 `attempt` 参数，该操作将返回有关最新尝试的信息。

```
aws emr-serverless get-job-run \
    --job-run-id job-run-id \
    --application-id application-id \
    --attempt 1
```

`ListJobRunAttempts` 操作将返回与作业运行相关的所有尝试的信息。

```
aws emr-serverless list-job-run-attempts \
  --application-id application-id \
  --job-run-id job-run-id
```

该`GetDashboardForJobRun`操作创建并返回一个 URL， UIs 用于访问应用程序以运行作业。`attempt` 参数允许您获取特定尝试的 URL。如果不包含 `attempt` 参数，该操作将返回有关最新尝试的信息。

```
aws emr-serverless get-dashboard-for-job-run \
    --application-id application-id \
    --job-run-id job-run-id \
    --attempt 1
```

## 使用重试策略监控作业
<a name="SECTION-jobs-resiliency-monitor-retry-policy"></a>

作业弹性支持还添加了新事件 **EMR Serverless 作业运行重试**。EMR Serverless 在每次重试作业时都会发布此事件。您可以使用此通知跟踪作业的重试次数。有关事件的更多信息，请参阅 [Amazon EventBridge 事件](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-events.html)。

## 使用重试策略记录日志
<a name="SECTION-jobs-resiliency-log-retry-policy"></a>

每次 EMR Serverless 重试作业时，都会生成自己的日志集。为了确保 EMR Serverless 能够在不覆盖任何日志 CloudWatch 的情况下成功将这些日志传送到 Amazon S3 和 Amazon，EMR Serverless 在 S3 日志路径和 CloudWatch 日志流名称的格式中添加了一个前缀，以包含任务的尝试次数。

下面是该格式的一个示例。

```
'/applications/<applicationId>/jobs/<jobId>/attempts/<attemptNumber>/'.
```

这种格式可确保 EMR Serverless 将每次尝试执行任务的所有日志发布到自己在 Amazon S3 中的指定位置和。 CloudWatch有关更多详细信息，请参阅[存储日志](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/logging.html)。

**注意**  
EMR Serverless 仅对所有流处理作业和任何启用重试的批处理作业使用此前缀格式。

# EMR Serverless 的元存储配置
<a name="metastore-config"></a>

*Hive 元存储*是一个集中位置，用于存储表的结构信息，包括架构、分区名称和数据类型。通过 EMR Serverless，请将此表元数据保存在有权访问您的作业的元存储中。

对于 Hive 元存储，您有两个选项：
+  AWS Glue 数据目录
+ 外部 Apache Hive 元存储

## 使用 AWS Glue 数据目录作为元数据库
<a name="glue-metastore"></a>

你可以将 Spark 和 Hive 作业配置为使用 Glue AWS 数据目录作为其元数据库。如果需要持久元存储，或不同应用程序、服务或 AWS 账户应用程序共享元存储，建议使用此配置。有关数据目录的更多信息，请参阅[填充 AWS Glue 数据目录](https://docs.aws.amazon.com/glue/latest/dg/populate-data-catalog.html)。有关 AWS Glue 定价的信息，请参阅 [AWS Glue 定价](https://aws.amazon.com/glue/pricing)。

您可以将 EMR Serverless 作业配置为在与您的应用程序 AWS 账户 相同或不同的应用程序中使用 AWS Glue 数据目录。 AWS 账户

### 配置 AWS Glue 数据目录
<a name="glue-metastore-configure"></a>

要配置数据目录，请选择要使用的 EMR Serverless 应用程序类型。

------
#### [ Spark ]

当你使用 EMR Studio 通过 EMR Serverless Spark 应用程序运行作业时，Glue 数据目录是默认的 AWS 元数据库。

使用 SDKs 或时 AWS CLI，在作业运行的`sparkSubmit`参数`com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory`中将`spark.hadoop.hive.metastore.client.factory.class`配置设置为。下面的示例显示了如何使用 AWS CLI配置数据目录。

```
aws emr-serverless start-job-run \
    --application-id application-id \
    --execution-role-arn job-role-arn \
    --job-driver '{
        "sparkSubmit": {
            "entryPoint": "s3://amzn-s3-demo-bucket/code/pyspark/extreme_weather.py",
            "sparkSubmitParameters": "--conf spark.hadoop.hive.metastore.client.factory.class=com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory --conf spark.driver.cores=1 --conf spark.driver.memory=3g --conf spark.executor.cores=4 --conf spark.executor.memory=3g"
        }
    }'
```

或者，您可以在 Spark 代码中创建新 `SparkSession` 时设置此配置。

```
from pyspark.sql import SparkSession

spark = (
    SparkSession.builder.appName("SparkSQL")
    .config(
        "spark.hadoop.hive.metastore.client.factory.class",
        "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory",
    )
    .enableHiveSupport()
    .getOrCreate()
)

# we can query tables with SparkSQL
spark.sql("SHOW TABLES").show()

# we can also them with native Spark
print(spark.catalog.listTables())
```

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

对于 EMR Serverless Hive 应用程序，数据目录是默认的元存储。也就是说，当你在 EMR Serverless Hive 应用程序上运行作业时，Hive 在数据目录中以与应用程序相同的形式记录元存储信息。 AWS 账户 您不需要虚拟私有云（VPC）即可将数据目录用作元存储。

要访问 Hive 元数据仓表，请添加为 G AWS lue [设置 IAM 权限中概述的必需 G AWS](https://docs.aws.amazon.com/glue/latest/dg/getting-started-access.html) lue 策略。

------

### 为 EMR Serverless AWS 和 Glue 数据目录配置跨账户访问权限
<a name="glue-metastore-cross-account"></a>

要为 EMR Serverless 设置跨账户访问权限，请先登录以下网站： AWS 账户
+ `AccountA`— 这是您创建了 EMR 无服务器应用程序 AWS 账户 的地方。
+ `AccountB`— 包 AWS 账户 含 AWS Glue 数据目录，你想让 EMR Serverless 作业运行访问该目录。

1. 确保 `AccountB` 中的管理员或其他授权身份将资源策略附加到 `AccountB` 中的数据目录。此策略授予 `AccountA` 特定的跨账户权限，以便对 `AccountB` 目录中的资源执行操作。

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

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Action": [
           "glue:GetDatabase",
           "glue:CreateDatabase",
           "glue:GetDataBases",
           "glue:CreateTable",
           "glue:GetTable",
           "glue:UpdateTable",
           "glue:DeleteTable",
           "glue:GetTables",
           "glue:GetPartition",
           "glue:GetPartitions",
           "glue:CreatePartition",
           "glue:BatchCreatePartition",
           "glue:GetUserDefinedFunctions"
         ],
         "Resource": [
           "arn:aws:glue:*:123456789012:catalog"
         ],
         "Sid": "AllowGLUEGetdatabase"
       }
     ]
   }
   ```

------

1. 将 IAM 策略添加到 `AccountA` 中的 EMR Serverless 作业运行时角色，以便该角色可以访问 `AccountB` 中的数据目录资源。

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

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Action": [
           "glue:GetDatabase",
           "glue:CreateDatabase",
           "glue:GetDataBases",
           "glue:CreateTable",
           "glue:GetTable",
           "glue:UpdateTable",
           "glue:DeleteTable",
           "glue:GetTables",
           "glue:GetPartition",
           "glue:GetPartitions",
           "glue:CreatePartition",
           "glue:BatchCreatePartition",
           "glue:GetUserDefinedFunctions"
         ],
         "Resource": [
           "arn:aws:glue:*:123456789012:catalog"
         ],
         "Sid": "AllowGLUEGetdatabase"
       }
     ]
   }
   ```

------

1.  启动作业运行。此步骤略有不同，具体取决于 `AccountA` 的 EMR Serverless 应用程序类型。

------
#### [ Spark ]

   如以下示例所示传递 `sparkSubmitParameters` 中的 `spark.hadoop.hive.metastore.glue.catalogid` 属性。将 *`AccountB-catalog-id`* 替换为 `AccountB` 中数据目录的 ID。

   ```
   aws emr-serverless start-job-run \
   --application-id "application-id" \
   --execution-role-arn "job-role-arn" \
   --job-driver '{
       "sparkSubmit": {
           "entryPoint": "s3://amzn-s3-demo-bucket/scripts/test.py",
            "sparkSubmitParameters": "--conf spark.hadoop.hive.metastore.client.factory.class=com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory --conf spark.hadoop.hive.metastore.glue.catalogid=AccountB-catalog-id --conf spark.executor.cores=1 --conf spark.executor.memory=1g --conf spark.driver.cores=1 --conf spark.driver.memory=1g --conf spark.executor.instances=1"
       }
     }' \
   --configuration-overrides '{
       "monitoringConfiguration": {
       "s3MonitoringConfiguration": {
       "logUri": "s3://amzn-s3-demo-bucket/logs/"
       }
     }
   }'
   ```

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

   如以下示例所示，在 `hive-site` 分类中设置 `hive.metastore.glue.catalogid` 属性。将 *`AccountB-catalog-id`* 替换为 `AccountB` 中数据目录的 ID。

   ```
   aws emr-serverless start-job-run \
   --application-id "application-id" \
   --execution-role-arn "job-role-arn" \
   --job-driver '{
       "hive": {
       "query": "s3://amzn-s3-demo-bucket/hive/scripts/create_table.sql",
       "parameters": "--hiveconf hive.exec.scratchdir=s3://amzn-s3-demo-bucket/hive/scratch --hiveconf hive.metastore.warehouse.dir=s3://amzn-s3-demo-bucket/hive/warehouse"
       }
   }' \
   --configuration-overrides '{
       "applicationConfiguration": [{
           "classification": "hive-site",
           "properties": {
               "hive.metastore.glue.catalogid": "AccountB-catalog-id"
           }
       }]
   }'
   ```

------

### 使用 Glue 数据 AWS 目录时的注意事项
<a name="glue-metastore-considerations"></a>

您可以在 Hive 脚本`ADD JAR`中 JARs 使用添加辅助工具。有关其他注意事项，请参阅[使用 AWS Glue 数据目录时的注意事项](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-hive-metastore-glue.html#emr-hive-glue-considerations-hive)。

# 使用外部 Hive 元存储
<a name="external-metastore"></a>

您可以配置 EMR Serverless Spark 和 Hive 作业，使其连接到外部 Hive 元存储，如 Amazon Aurora 或 Amazon RDS for MySQL。本节介绍了如何设置 Amazon RDS Hive 元存储、配置 VPC 和配置 EMR Serverless 作业以使用外部元存储。

## 创建外部 Hive 元存储
<a name="external-metastore-create"></a>

1. 按照[创建 VPC](https://docs.aws.amazon.com/vpc/latest/userguide/working-with-vpcs.html#Create-VPC) 中的说明，创建具有私有子网的 Amazon Virtual Private Cloud（Amazon VPC）。

1. 使用新的 Amazon VPC 和私有子网创建 EMR Serverless 应用程序。当您使用 VPC 配置 EMR Serverless 应用程序时，首先会为您指定的每个子网预置一个弹性网络接口。然后，将您指定的安全组附加到该网络接口。这样就可以对应用程序进行访问控制。有关如何设置 VPC 的更多详细信息，请参阅 [为 EMR Serverless 应用程序配置 VPC 访问权限以连接数据](vpc-access.md)。

1. 在 Amazon VPC 的私有子网中创建 MySQL 或 Aurora PostgreSQL 数据库。有关如何创建 Amazon RDS 数据库的信息，请参阅[创建 Amazon RDS 数据库实例](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_CreateDBInstance.html)。

1. 按照[修改 Amazon RDS 数据库实例](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.DBInstance.Modifying.html)中的步骤修改 MySQL 或 Aurora 数据库的安全组，允许来自 EMR Serverless 安全组的 JDBC 连接。为从其中一个 EMR Serverless 安全组到 RDS 安全组的入站流量添加规则。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/emr/latest/EMR-Serverless-UserGuide/external-metastore.html)

## 配置 Spark 选项
<a name="external-metastore-spark"></a>

**使用 JDBC**

要将 EMR Serverless Spark 应用程序配置为连接到基于 Amazon RDS for MySQL 或 Amazon Aurora MySQL 实例的 Hive 元存储，请使用 JDBC 连接。在作业运行的 `spark-submit` 参数中传递带有 `--jars` 的 `mariadb-connector-java.jar`。

```
aws emr-serverless start-job-run \
  --application-id "application-id" \
  --execution-role-arn "job-role-arn" \
  --job-driver '{
        "sparkSubmit": {
            "entryPoint": "s3://amzn-s3-demo-bucket/scripts/spark-jdbc.py",
            "sparkSubmitParameters": "--jars s3://amzn-s3-demo-bucket/mariadb-connector-java.jar 
            --conf spark.hadoop.javax.jdo.option.ConnectionDriverName=org.mariadb.jdbc.Driver 
            --conf spark.hadoop.javax.jdo.option.ConnectionUserName=<connection-user-name> 
            --conf spark.hadoop.javax.jdo.option.ConnectionPassword=<connection-password>
            --conf spark.hadoop.javax.jdo.option.ConnectionURL=<JDBC-Connection-string> 
            --conf spark.driver.cores=2
            --conf spark.executor.memory=10G 
            --conf spark.driver.memory=6G 
            --conf spark.executor.cores=4"
        }
    }' \
    --configuration-overrides '{
        "monitoringConfiguration": {
        "s3MonitoringConfiguration": {
            "logUri": "s3://amzn-s3-demo-bucket/spark/logs/"
        }
    }
}'
```

以下代码示例是一个 Spark 入口点脚本，与 Amazon RDS 上的 Hive 元存储交互。

```
from os.path import expanduser, join, abspath
from pyspark.sql import SparkSession
from pyspark.sql import Row
# warehouse_location points to the default location for managed databases and tables
warehouse_location = abspath('spark-warehouse')
spark = SparkSession \
    .builder \
    .config("spark.sql.warehouse.dir", warehouse_location) \
    .enableHiveSupport() \
    .getOrCreate()
spark.sql("SHOW DATABASES").show()
spark.sql("CREATE EXTERNAL TABLE `sampledb`.`sparknyctaxi`(`dispatching_base_num` string, `pickup_datetime` string, `dropoff_datetime` string, `pulocationid` bigint, `dolocationid` bigint, `sr_flag` bigint) STORED AS PARQUET LOCATION 's3://<s3 prefix>/nyctaxi_parquet/'")
spark.sql("SELECT count(*) FROM sampledb.sparknyctaxi").show()
spark.stop()
```

**使用 thrift 服务**

您可以将 EMR Serverless Hive 应用程序配置为连接到基于 Amazon RDS for MySQL 或 Amazon Aurora MySQL 实例的 Hive 元存储。为此，请在现有 Amazon EMR 集群的主节点上运行 thrift 服务器。如果您已经有一个 Amazon EMR 集群，其中包含用于简化 EMR Serverless 作业配置的 thrift 服务器，则此选项是理想之选。

```
aws emr-serverless start-job-run \
  --application-id "application-id" \
  --execution-role-arn "job-role-arn" \
  --job-driver '{
        "sparkSubmit": {
            "entryPoint": "s3://amzn-s3-demo-bucket/thriftscript.py",
            "sparkSubmitParameters": "--jars s3://amzn-s3-demo-bucket/mariadb-connector-java.jar 
            --conf spark.driver.cores=2
            --conf spark.executor.memory=10G 
            --conf spark.driver.memory=6G 
            --conf spark.executor.cores=4"
        }
    }' \
    --configuration-overrides '{
        "monitoringConfiguration": {
        "s3MonitoringConfiguration": {
            "logUri": "s3://amzn-s3-demo-bucket/spark/logs/"
        }
    }
}'
```

以下代码示例是一个入口点脚本（`thriftscript.py`），使用 thrift 协议连接到 Hive 元存储。请注意，需要将 `hive.metastore.uris` 属性设置为从外部 Hive 元存储读取。

```
from os.path import expanduser, join, abspath
from pyspark.sql import SparkSession
from pyspark.sql import Row
# warehouse_location points to the default location for managed databases and tables
warehouse_location = abspath('spark-warehouse')
spark = SparkSession \
    .builder \
    .config("spark.sql.warehouse.dir", warehouse_location) \
    .config("hive.metastore.uris","thrift://thrift-server-host:thift-server-port") \
    .enableHiveSupport() \
    .getOrCreate()
spark.sql("SHOW DATABASES").show()
spark.sql("CREATE EXTERNAL TABLE sampledb.`sparknyctaxi`( `dispatching_base_num` string, `pickup_datetime` string, `dropoff_datetime` string, `pulocationid` bigint, `dolocationid` bigint, `sr_flag` bigint) STORED AS PARQUET LOCATION 's3://<s3 prefix>/nyctaxi_parquet/'")
spark.sql("SELECT * FROM sampledb.sparknyctaxi").show()
spark.stop()
```

## 配置 Hive 选项
<a name="external-metastore-hive"></a>

**使用 JDBC**

如果要在 Amazon RDS MySQL 或 Amazon Aurora 实例上指定外部 Hive 数据库位置，可以覆盖默认的元存储配置。

**注意**  
在 Hive 中，您可以同时对元存储表执行多次写入。如果在两个作业之间共享元存储信息，请确保不要同时写入同一个元存储表，除非写入同一元存储表的不同分区。

在 `hive-site` 分类中设置以下配置以激活外部 Hive 元存储。

```
{
    "classification": "hive-site",
    "properties": {
        "hive.metastore.client.factory.class": "org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClientFactory",
        "javax.jdo.option.ConnectionDriverName": "org.mariadb.jdbc.Driver",
        "javax.jdo.option.ConnectionURL": "jdbc:mysql://db-host:db-port/db-name",
        "javax.jdo.option.ConnectionUserName": "username",
        "javax.jdo.option.ConnectionPassword": "password"
    }
}
```

**使用 thrift 服务器**

你可以将你的 EMR Serverless Hive 应用程序配置为连接基于亚马逊 RDS for MySQL 或 Amazon Aurora My 的 Hive 元存储库。SQLinstance为此，请在现有 Amazon EMR 集群的主节点上运行 thrift 服务器。如果您已经有一个运行 thrift 服务器的 Amazon EMR 集群，希望使用 EMR Serverless 作业配置，则此选项是理想之选。

在 `hive-site` 分类中设置以下配置，以便 EMR Serverless 可以访问远程 thrift 元存储。请注意，必须将 `hive.metastore.uris` 属性设置为从外部 Hive 元存储读取。

```
{
    "classification": "hive-site",
    "properties": {
        "hive.metastore.client.factory.class": "org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClientFactory",
        "hive.metastore.uris": "thrift://thrift-server-host:thirft-server-port"
    }
}
```

# 在 EMR Serv AWS erless 上使用 Glue 多目录层次结构
<a name="external-metastore-glue-multi"></a>

您可以将 EMR 无服务器应用程序配置为使用 Glue 多目录层次结构 AWS 。以下示例展示了如何在 Glue 多目录层次结构中使用 EMR-S Spark。 AWS 

要了解有关多目录层次结构的更多信息，请参阅 [Amazon EMR 上的 G AWS lue 数据目录中使用 Spark 处理多目录层次结构](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-multi-catalog.html)。

## 使用带有 Iceberg 和 Glue 数据目录的 Redshift 托管存储 (RMS) AWS
<a name="emr-serverless-lf-enable-spark-session-glue"></a>

以下内容演示了如何配置 Spark 以与 Iceberg 的 AWS Glue 数据目录集成：

```
aws emr-serverless start-job-run \
    --application-id application-id \
    --execution-role-arn job-role-arn \
    --job-driver '{
        "sparkSubmit": {
            "entryPoint": "s3://amzn-s3-demo-bucket/myscript.py",
            "sparkSubmitParameters": "--conf spark.sql.catalog.nfgac_rms = org.apache.iceberg.spark.SparkCatalog
             --conf spark.sql.catalog.rms.type=glue 
             --conf spark.sql.catalog.rms.glue.id=Glue RMS catalog ID 
             --conf spark.sql.defaultCatalog=rms
             --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions"
        }
    }'
```

集成后来自目录中的表的查询示例：

```
SELECT * FROM my_rms_schema.my_table
```

## 将 Redshift 托管存储 (RMS) 与 Iceberg REST API 和 Glue 数据目录配合使用 AWS
<a name="emr-serverless-lf-enable-spark-session-rest"></a>

以下内容展示了如何将 Spark 配置为与 Iceberg REST 目录配合使用：

```
aws emr-serverless start-job-run \
--application-id application-id \
--execution-role-arn job-role-arn \
--job-driver '{
"sparkSubmit": {
"entryPoint": "s3://amzn-s3-demo-bucket/myscript.py",
    "sparkSubmitParameters": "
    --conf spark.sql.catalog.rms=org.apache.iceberg.spark.SparkCatalog
    --conf spark.sql.catalog.rms.type=rest
    --conf spark.sql.catalog.rms.warehouse=Glue RMS catalog ID
    --conf spark.sql.catalog.rms.uri=Glue endpoint URI/iceberg
    --conf spark.sql.catalog.rms.rest.sigv4-enabled=true
    --conf spark.sql.catalog.rms.rest.signing-name=glue
    --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions"
    }
  }'
```

来自目录中的表的查询示例：

```
SELECT * FROM my_rms_schema.my_table
```

# 使用外部元存储时的注意事项
<a name="external-metastore-considerations"></a>
+ 您可以将与 MariaDB JDBC 兼容的数据库配置为元存储。这些数据库的示例包括 RDS for MariaDB、MySQL 和 Amazon Aurora。
+ 元存储不会自动初始化。如果元存储未使用适合 Hive 版本的架构初始化，请使用 [Hive Schema Tool](https://cwiki.apache.org/confluence/display/Hive/Hive+Schema+Tool)。
+ EMR Serverless 不支持 Kerberos 身份验证。您不能将具有 Kerberos 身份验证的 thrift 元存储服务器与 EMR Serverless Spark 或 Hive 作业一起使用。
+ 您必须配置 VPC 访问才能使用多目录层次结构。

# 从 EMR Serverless 访问另一个 AWS 账户中的 S3 数据
<a name="jobs-s3-access"></a>

您可以从一个 AWS 账户运行 Amazon EMR 无服务器任务，并将其配置为访问属于另一个账户的 Amazon S3 存储桶中的数据。 AWS 本页介绍了如何配置从 EMR Serverless 对 S3 的跨账户访问。

在 EMR Serverless 上运行的任务可以使用 S3 存储桶策略或代入的角色从其他账户访问 Amazon S3 中的数据。 AWS 

## 先决条件
<a name="jobs-s3-access-prerequisites"></a>

要为 Amazon EMR Serverless 设置跨账户访问权限，请在登录两个账户的同时完成任务： AWS 
+ **`AccountA`**：这是您在其中创建 Amazon EMR Serverless 应用程序的 AWS 账户。在设置跨账户访问之前，请在此账户中做好以下准备：
  + Amazon EMR Serverless 应用程序，在其中运行作业。
  + 作业执行角色，拥有在应用程序中运行作业所需的权限。有关更多信息，请参阅[Amazon EMR Serverless 的作业运行时角色](security-iam-runtime-role.md)。
+ **`AccountB`**：该 AWS 账户包含您希望 Amazon EMR Serverless 作业访问的 S3 存储桶。

## 使用 S3 存储桶策略访问跨账户 S3 数据
<a name="jobs-s3-access-how-to-s3-bucket-policy"></a>

要从 account A 访问 account B 中的 S3 存储桶，请将以下策略附加到 account B 中的 S3 存储桶。

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "ExamplePermissions1",
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-bucket-name"
      ]
    },
    {
      "Sid": "ExamplePermissions2",
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject"
      ],
      "Resource": [
        "arn:aws:s3:::my-bucket-name/*"
      ]
    }
  ]
}
```

------

有关使用 S3 存储桶策略进行 S3 跨账户访问的更多信息，请参阅《Amazon Simple Storage Service 用户指南》**中的[示例 2：存储桶所有者授予跨账户存储桶权限](https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-walkthroughs-managing-access-example2.html)。

## 使用代入角色跨账户访问 S3 数据
<a name="jobs-s3-access-how-to-assumed-role"></a>

为 Amazon EMR Serverless 设置跨账户访问权限的另一种方法是使用 () `AssumeRole` 中的 AWS Security Token Service 操作。AWS STS AWS STS 是一项全球 Web 服务，允许您为用户申请临时的、权限有限的证书。您可以使用通过 `AssumeRole` 创建的临时安全凭证对 EMR Serverless 和 Amazon S3 进行 API 调用。

以下步骤说明了如何使用代入角色从 EMR Serverless 跨账户访问 S3 数据：

1. 创建 Amazon S3 存储桶，即 `AccountB` 中的 *cross-account-bucket*。有关更多信息，请参阅《Amazon Simple Storage Service 用户指南》**中的[创建存储桶](https://docs.aws.amazon.com/AmazonS3/latest/gsg/CreatingABucket.html)。如果您希望跨账户访问 DynamoDB，还请在 `AccountB` 中创建 DynamoDB 表。有关更多信息，请参阅《Amazon DynamoDB 开发人员指南》**中的[创建 DynamoDB 表](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-1.html)。

1. 在 `AccountB` 中创建 `Cross-Account-Role-B` IAM 角色，以便可以访问 *cross-account-bucket*。

   1. 登录 AWS 管理控制台 并打开 IAM 控制台，网址为[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。

   1. 选择 **Roles (角色)** 并创建新角色：`Cross-Account-Role-B`。有关如何创建 IAM 角色的更多信息，请参阅《IAM 用户指南》中的[创建 IAM 角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create.html)。

   1. 创建 IAM policy 来指定针对 `Cross-Account-Role-B` 的权限以访问 *cross-account-bucket* S3 存储桶，如以下策略声明所示。然后将 IAM policy 附加到 `Cross-Account-Role-B`。有关更多信息，请参阅《IAM 用户指南》**中的[创建 IAM 策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html)。

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

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Action": [
           "s3:*"
         ],
         "Resource": [
           "arn:aws:s3:::cross-account-bucket",
           "arn:aws:s3:::cross-account-bucket/*"
         ],
         "Sid": "AllowS3"
       }
     ]
   }
   ```

------

   如果需要访问 DynamoDB，请创建 IAM 策略，指定跨账户访问 DynamoDB 表的权限。然后将 IAM policy 附加到 `Cross-Account-Role-B`。有关更多信息，请参阅《IAM 用户指南》**中的 [Amazon DynamoDB：允许访问特定表](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_dynamodb_specific-table.html)。

   以下是允许访问 DynamoDB 表 `CrossAccountTable` 的策略。

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

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Action": [
           "dynamodb:*"
         ],
         "Resource": [
           "arn:aws:dynamodb:*:123456789012:table/CrossAccountTable"
         ],
         "Sid": "AllowDYNAMODB"
       }
     ]
   }
   ```

------

1. 编辑 `Cross-Account-Role-B` 角色的信任关系。

   1. 要配置角色的信任关系，请在 IAM 控制台中为您在步骤 2 中创建的 `Cross-Account-Role-B` 角色选择**信任关系**选项卡。

   1. 选择 **Edit Trust Relationship (编辑信任关系)**。

   1. 添加以下策略文档。这允许 `AccountA` 中的 `Job-Execution-Role-A` 代入 `Cross-Account-Role-B` 角色。

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

****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Action": [
              "sts:AssumeRole"
            ],
            "Resource": "arn:aws:iam::123456789012:role/Job-Execution-Role-A",
            "Sid": "AllowSTSAssumerole"
          }
        ]
      }
      ```

------

1. 授`Job-Execution-Role-A``AccountA`予假设 AWS STS `AssumeRole`权限`Cross-Account-Role-B`。

   1. 在 AWS 账户的 IAM 控制台中`AccountA`，选择`Job-Execution-Role-A`。

   1. 添加以下 `Job-Execution-Role-A` 策略语句以便对 `Cross-Account-Role-B` 角色执行 `AssumeRole` 操作。

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

****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Action": [
              "sts:AssumeRole"
            ],
            "Resource": [
              "arn:aws:iam::123456789012:role/Cross-Account-Role-B"
            ],
            "Sid": "AllowSTSAssumerole"
          }
        ]
      }
      ```

------

## 代入角色示例
<a name="jobs-s3-access-how-to-assumed-role-examples"></a>

使用单个代入角色访问账户中的所有 S3 资源，或者在 Amazon EMR 6.11 及更高版本中，配置多个 IAM 角色，以便在跨账户访问不同的 S3 存储桶时代入。

**Topics**
+ [

### 使用单个代入角色访问 S3 资源
](#jobs-s3-access-how-to-assumed-role-single)
+ [

### 使用多个代入角色访问 S3 资源
](#jobs-s3-access-how-to-assumed-role-multiple)

### 使用单个代入角色访问 S3 资源
<a name="jobs-s3-access-how-to-assumed-role-single"></a>

**注意**  
如果将作业配置为使用单个代入角色，整个作业中的所有 S3 资源都将使用该角色，包括 `entryPoint` 脚本。

如果您想使用单个代入角色访问账户 B 中的所有 S3 资源，请指定以下配置：

1. 将 EMRFS 配置 `fs.s3.customAWSCredentialsProvider` 指定为 `com.amazonaws.emr.AssumeRoleAWSCredentialsProvider`。

1. 对于 Spark，使用 `spark.emr-serverless.driverEnv.ASSUME_ROLE_CREDENTIALS_ROLE_ARN` 和 `spark.executorEnv.ASSUME_ROLE_CREDENTIALS_ROLE_ARN` 指定驱动程序和执行程序的环境变量。

1. 对于 Hive，使用 `hive.emr-serverless.launch.env.ASSUME_ROLE_CREDENTIALS_ROLE_ARN`、`tez.am.emr-serverless.launch.env.ASSUME_ROLE_CREDENTIALS_ROLE_ARN` 和 `tez.task.emr-serverless.launch.env.ASSUME_ROLE_CREDENTIALS_ROLE_ARN` 指定 Hive 驱动程序、Tez 应用程序主进程和 Tez 任务容器的环境变量。

以下示例展示了如何使用代入角色启动具有跨账户访问权限的 EMR Serverless 作业运行。

------
#### [ Spark ]

以下示例展示了如何使用代入角色启动有权跨账户访问 S3 的 EMR Serverless Spark 作业运行。

```
aws emr-serverless start-job-run \
    --application-id application-id \
    --execution-role-arn job-role-arn \
    --job-driver '{
        "sparkSubmit": {
            "entryPoint": "entrypoint_location",
            "entryPointArguments": [":argument_1:", ":argument_2:"],
            "sparkSubmitParameters": "--conf spark.executor.cores=4 --conf spark.executor.memory=20g --conf spark.driver.cores=4 --conf spark.driver.memory=8g --conf spark.executor.instances=1"
        }
    }' \
     --configuration-overrides '{
        "applicationConfiguration": [{
            "classification": "spark-defaults",
            "properties": {
                "spark.hadoop.fs.s3.customAWSCredentialsProvider": "com.amazonaws.emr.AssumeRoleAWSCredentialsProvider",
                "spark.emr-serverless.driverEnv.ASSUME_ROLE_CREDENTIALS_ROLE_ARN": "arn:aws:iam::AccountB:role/Cross-Account-Role-B",
                "spark.executorEnv.ASSUME_ROLE_CREDENTIALS_ROLE_ARN": "arn:aws:iam::AccountB:role/Cross-Account-Role-B"
            }
        }]
    }'
```

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

以下示例展示了如何使用代入角色启动有权跨账户访问 S3 的 EMR Serverless Hive 作业运行。

```
aws emr-serverless start-job-run \
    --application-id application-id \
    --execution-role-arn job-role-arn \
    --job-driver '{
        "hive": {
            "query": "query_location",
            "parameters": "hive_parameters"
        }
    }' \
    --configuration-overrides '{
        "applicationConfiguration": [{
            "classification": "hive-site",
            "properties": {
                "fs.s3.customAWSCredentialsProvider": "com.amazonaws.emr.serverless.credentialsprovider.AssumeRoleAWSCredentialsProvider",
                "hive.emr-serverless.launch.env.ASSUME_ROLE_CREDENTIALS_ROLE_ARN": "arn:aws:iam::AccountB:role/Cross-Account-Role-B",
                "tez.am.emr-serverless.launch.env.ASSUME_ROLE_CREDENTIALS_ROLE_ARN": "arn:aws:iam::AccountB:role/Cross-Account-Role-B",
                "tez.task.emr-serverless.launch.env.ASSUME_ROLE_CREDENTIALS_ROLE_ARN": "arn:aws:iam::AccountB:role/Cross-Account-Role-B"
            }
        }]
    }'
```

------

### 使用多个代入角色访问 S3 资源
<a name="jobs-s3-access-how-to-assumed-role-multiple"></a>

在 EMR Serverless 6.11.0 及更高版本中，配置多个 IAM 角色，以便在访问不同的跨账户存储桶时代入。如果要使用账户 B 中的不同代入角色访问不同的 S3 资源，请在启动作业运行时使用以下配置：

1. 将 EMRFS 配置 `fs.s3.customAWSCredentialsProvider` 指定为 `com.amazonaws.emr.serverless.credentialsprovider.BucketLevelAssumeRoleCredentialsProvider`。

1. 指定 EMRFS 配置 `fs.s3.bucketLevelAssumeRoleMapping`，定义从 S3 存储桶名称到账户 B 中要代入的 IAM 角色的映射。该值的格式为 `bucket1->role1;bucket2->role2`。

例如，使用 `arn:aws:iam::AccountB:role/Cross-Account-Role-B-1` 访问存储桶 `bucket1`，使用 `arn:aws:iam::AccountB:role/Cross-Account-Role-B-2` 访问存储桶 `bucket2`。以下示例展示了如何通过多个代入角色启动具有跨账户访问权限的 EMR Serverless 作业运行。

------
#### [ Spark ]

以下示例展示了如何使用多个代入角色来创建 EMR Serverless Spark 作业运行。

```
aws emr-serverless start-job-run \
    --application-id application-id \
    --execution-role-arn job-role-arn \
    --job-driver '{
        "sparkSubmit": {
            "entryPoint": "entrypoint_location",
            "entryPointArguments": [":argument_1:", ":argument_2:"],
            "sparkSubmitParameters": "--conf spark.executor.cores=4 --conf spark.executor.memory=20g --conf spark.driver.cores=4 --conf spark.driver.memory=8g --conf spark.executor.instances=1"
        }
    }' \
     --configuration-overrides '{
        "applicationConfiguration": [{
            "classification": "spark-defaults",
            "properties": {
                "spark.hadoop.fs.s3.customAWSCredentialsProvider": "com.amazonaws.emr.serverless.credentialsprovider.BucketLevelAssumeRoleCredentialsProvider",
                "spark.hadoop.fs.s3.bucketLevelAssumeRoleMapping": "bucket1->arn:aws:iam::AccountB:role/Cross-Account-Role-B-1;bucket2->arn:aws:iam::AccountB:role/Cross-Account-Role-B-2"
            }
        }]
    }'
```

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

以下示例展示了如何使用多个代入角色来创建 EMR Serverless Hive 作业运行。

```
aws emr-serverless start-job-run \
    --application-id application-id \
    --execution-role-arn job-role-arn \
    --job-driver '{
        "hive": {
            "query": "query_location",
            "parameters": "hive_parameters"
        }
    }' \
    --configuration-overrides '{
        "applicationConfiguration": [{
            "classification": "hive-site",
            "properties": {
                "fs.s3.customAWSCredentialsProvider": "com.amazonaws.emr.serverless.credentialsprovider.AssumeRoleAWSCredentialsProvider",
                "fs.s3.bucketLevelAssumeRoleMapping": "bucket1->arn:aws:iam::AccountB:role/Cross-Account-Role-B-1;bucket2->arn:aws:iam::AccountB:role/Cross-Account-Role-B-2"
            }
        }]
    }'
```

------

# 排查 EMR Serverless 中的错误
<a name="jobs-troubleshoot"></a>

使用以下信息来帮助诊断和修复在使用 Amazon EMR Serverless 时发生的常见问题。

**Topics**
+ [

## 错误：作业失败，因为账户已达到其可同时使用的最大 vCPU 的服务限制。
](#jobs-troubleshoot-allowed-capacity-vcpu)
+ [

## 错误：作业失败，因为应用程序超过 maximumCapacity 设置。
](#jobs-troubleshoot-maxcapacity)
+ [

## 错误：由于应用程序已超过 maximumCapacity，无法分配工作线程，作业失败。
](#jobs-troubleshoot-worker-allocated)
+ [

## 错误：S3 访问被拒绝。请检查作业运行时角色对所需 S3 资源的 S3 访问权限。
](#jobs-troubleshoot-s3)
+ [

## 错误: ModuleNotFoundError: 未命名模块<module>。请参阅用户指南，了解如何将 Python 库与 EMR Serverless 结合使用。
](#jobs-troubleshoot-module)
+ [

## 错误：无法代入执行角色 <role-name>，因为该角色不存在或未设置所需的信任关系。
](#jobs-troubleshoot-runtime-role)

## 错误：作业失败，因为账户已达到其可同时使用的最大 vCPU 的服务限制。
<a name="jobs-troubleshoot-allowed-capacity-vcpu"></a>

此错误表明 EMR Serverless 无法提交作业，因为账户已超出最大容量。增加账户的最大容量。在 [EMR Serverless 服务配额](https://console.aws.amazon.com/servicequotas/home/services/emr-serverless/quotas)查看您的服务限制。

## 错误：作业失败，因为应用程序超过 maximumCapacity 设置。
<a name="jobs-troubleshoot-maxcapacity"></a>

此错误表示 EMR Serverless 无法提交作业，因为应用程序已超出配置的最大容量。增加应用程序的最大容量。

## 错误：由于应用程序已超过 maximumCapacity，无法分配工作线程，作业失败。
<a name="jobs-troubleshoot-worker-allocated"></a>

此错误表明作业无法完成。由于应用程序已超过 maximumCapacity 设置，无法分配工作线程。

## 错误：S3 访问被拒绝。请检查作业运行时角色对所需 S3 资源的 S3 访问权限。
<a name="jobs-troubleshoot-s3"></a>

此错误表示您的作业无法访问 S3 资源。验证作业运行时角色是否有权访问作业需要使用的 S3 资源。要了解有关运行时角色的更多信息，请参阅 [Amazon EMR Serverless 的作业运行时角色](security-iam-runtime-role.md)。

## 错误: ModuleNotFoundError: 未命名模块<module>。请参阅用户指南，了解如何将 Python 库与 EMR Serverless 结合使用。
<a name="jobs-troubleshoot-module"></a>

此错误表明 Python 模块不可用于 Spark 作业。检查依赖的 Python 库是否可用于该作业。有关如何打包 Python 库的更多信息，请参阅[将 Python 库与 EMR Serverless 结合使用](using-python-libraries.md)。

## 错误：无法代入执行角色 <role-name>，因为该角色不存在或未设置所需的信任关系。
<a name="jobs-troubleshoot-runtime-role"></a>

此错误表示您为作业指定的作业运行时角色不存在，或者该角色与 EMR Serverless 权限不存在信任关系。要验证 IAM 角色是否存在，并验证您是否已正确设置该角色的信任策略，请参阅 [Amazon EMR Serverless 的作业运行时角色](security-iam-runtime-role.md) 中的说明。

# 启用 Job 级别成本分配
<a name="jobs-job-level-cost-allocation"></a>

任务级别的成本分配允许在单个任务运行层面为 EMR Serverless 进行精细的计费归因，而不是在应用程序级别汇总所有成本。启用后，您可以在 Cost Explorer 和 “ AWS 成本和使用情况报告” 中按特定任务运行 IDs 和与任务运行关联的标签筛选和跟踪成本，从而更好地了解已提交的作业运行的费用。

## 默认 行为
<a name="jobs-job-level-cost-allocation-default"></a>

默认情况下，未启用任务级别的成本分配。

## 如何启用或禁用该功能
<a name="jobs-job-level-cost-allocation-enable"></a>

您可以在创建应用程序期间配置任务级别的成本分配，也可以针对现有应用程序进行更新。

在创建新应用程序时指定`jobLevelCostAllocation`参数：

```
# Enable job-level cost allocation:
aws emr-serverless create-application \
    --name "my-application" \
    --release-label "emr-7.12.0" \
    --type "SPARK" \
    --job-level-cost-allocation-configuration '{
        "enabled": true
    }'

# Disable job-level cost allocation:
aws emr-serverless create-application \
    --name "my-application" \
    --release-label "emr-7.12.0" \
    --type "SPARK" \
    --job-level-cost-allocation-configuration '{
        "enabled": false
    }'
```

更新现有应用程序的`jobLevelCostAllocationConfiguration`参数：

```
# Enable job-level cost allocation:
aws emr-serverless update-application \
    --application-id <application-id> \
    --job-level-cost-allocation-configuration '{
        "enabled": true
    }'

# Disable job-level cost allocation:
aws emr-serverless update-application \
    --application-id <application-id> \
    --job-level-cost-allocation-configuration '{
        "enabled": false
    }'
```

## 注意事项和限制
<a name="jobs-job-level-cost-allocation-considerations"></a>
+ 启用任务级成本分配不会追溯归因在启用该功能之前完成的任务运行的成本。启用该功能后启动的 Job 运行将具有精细的成本归因。
+ 只有当应用程序处于 “已创建” 或 “已停止” 状态时，才能更新任务级别的成本分配参数。
+ 启用作业级别的成本分配后，成本将归因于单个作业运行而不是应用程序。要查看应用程序级别的汇总成本，您必须对该应用程序内运行的所有作业应用一致的标签（例如应用程序名称或应用程序ID），并在 Cost Explorer 或 “成本和使用率报告” 中按这些标签进行筛选。