

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 設定 Spark
<a name="emr-spark-configure"></a>

您可以使用組態類別來設定 [Amazon EMR 上的 Spark](https://aws.amazon.com/elasticmapreduce/details/spark/)。如需有關組態分類的詳細資訊，請參閱 [設定應用程式](emr-configure-apps.md)。

在 Amazon EMR 上適用於 Spark 的組態分類包括下列項目：
+ **`spark`** – 將 `maximizeResourceAllocation` 屬性設為 true 或 false。設為 true 時，Amazon EMR 會自動根據叢集硬體組態設定 `spark-defaults` 屬性。如需詳細資訊，請參閱[使用 `maximizeResourceAllocation`](#emr-spark-maximizeresourceallocation)。
+ **`spark-defaults`** – 設定 `spark-defaults.conf` 檔案中的值。如需詳細資訊，請參閱 Spark 文件中的 [Spark 組態](https://spark.apache.org/docs/latest/configuration.html)。
+ **`spark-env`** – 設定 `spark-env.sh` 檔案中的值。如需詳細資訊，請參閱 Spark 文件中的[環境變數](https://spark.apache.org/docs/latest/configuration.html#environment-variables)。
+ **`spark-hive-site`** – 為 Spark 設定 `hive-site.xml` 中的值。
+ **`spark-log4j`** – (Amazon EMR 6.7.x 版及更早版本) 設定 `log4j.properties` 檔案中的值。如需詳細資訊，請參閱 Github 上的 [log4j.properties.template](https://github.com/apache/spark/blob/branch-3.2/conf/log4j.properties.template) 檔案。
+ **`spark-log4j2`** – (Amazon EMR 6.8.0 版及更高版本) 設定 `log4j2.properties` 檔案中的值。如需詳細資訊，請參閱 Github 上的 [log4j2.properties.template](https://github.com/apache/spark/blob/v3.3.0/conf/log4j2.properties.template) 檔案。
+ **`spark-metrics`** – 設定 `metrics.properties` 檔案中的值。如需了解設定和詳細資訊，請參閱 Github 上的 [metrics.properties.template](https://github.com/apache/spark/blob/master/conf/metrics.properties.template) 檔案和 Spark 文件中的[指標](https://spark.apache.org/docs/latest/monitoring.html#metrics)。

**注意**  
如果您要從其他平台將 Spark 工作負載遷移到 Amazon EMR，則建議您在新增自訂組態前使用 [Amazon EMR 設定的 Spark 預設值](#spark-defaults) 測試您的工作負載。大多數客戶在使用我們的預設設定後會經歷效能提升。

**Topics**
+ [Amazon EMR 設定的 Spark 預設值](#spark-defaults)
+ [設定 Amazon EMR 6.1.0 上的 Spark 垃圾回收](#spark-gc-config)
+ [使用 `maximizeResourceAllocation`](#emr-spark-maximizeresourceallocation)
+ [設定節點除役行為](#spark-decommissioning)
+ [Spark ThriftServer 環境變數](#spark-thriftserver)
+ [變更 Spark 預設設定](#spark-change-defaults)
+ [從 Apache Log4j 1.x 遷移至 Log4j 2.x](#spark-migrate-logj42)

## Amazon EMR 設定的 Spark 預設值
<a name="spark-defaults"></a>

下表顯示了 Amazon EMR 在 `spark-defaults` 中設定預設值時將如何影響應用程式。


**Amazon EMR 設定的 Spark 預設值**  

| 設定 | 說明 | 預設值 | 
| --- | --- | --- | 
| spark.executor.memory | 每個執行器程序要使用的記憶體量。例如：`1g`、`2g`。 | 此設定由叢集中的核心和任務執行個體類型決定。 | 
| spark.executor.cores | 每個執行器上要使用的核心數。 | 此設定由叢集中的核心和任務執行個體類型決定。 | 
| spark.dynamicAllocation.enabled | 若為 true，請使用動態資源分配，依據工作負載的情況擴增及縮減應用程式，從而擴展註冊執行器的數量。 | `true` (使用 Amazon EMR 4.4.0 及更高版本) Amazon EMR 會自動設定 Spark 隨機顯示服務。  | 
| spark.sql.hive.advancedPartitionPredicatePushdown.enabled | 若為 true，將啟用進階分割區述詞下推至 Hive 中繼存放區。 | true | 
| spark.sql.hive.stringLikePartitionPredicatePushdown.enabled | 下推 `startsWith`、`contains` 和 `endsWith` 篩選條件至 Hive 中繼存放區。 Glue 不支援為 `startsWith`、`contains` 或 `endsWith` 下推述詞。如果您使用的是 Glue 中繼存放區，且因為這些函數的述詞下推而發生錯誤，請將此組態設定為 `false`。  | true | 

## 設定 Amazon EMR 6.1.0 上的 Spark 垃圾回收
<a name="spark-gc-config"></a>

使用 `spark.driver.extraJavaOptions` 和 `spark.executor.extraJavaOptions` 設定自訂的垃圾回收組態會導致 Amazon EMR 6.1 的驅動程式或執行器啟動失敗，因為垃圾回收組態與 Amazon EMR 6.1.0 發生衝突。對於 Amazon EMR 6.1.0，透過 `spark.driver.defaultJavaOptions` 和 `spark.executor.defaultJavaOptions` 設定預設的垃圾回收組態。此組態僅套用至 Amazon EMR 6.1.0。與垃圾回收不相關之 JVM 選項，例如設定記錄的選項 (`-verbose:class`)，仍可透過 `extraJavaOptions` 設定。如需詳細資訊，請參閱 [Spark 應用程式屬性](https://spark.apache.org/docs/latest/configuration.html#application-properties)。

## 使用 `maximizeResourceAllocation`
<a name="emr-spark-maximizeresourceallocation"></a>

若要設定您的執行器，以便在叢集中每個節點上利用可用的最大資源，請在您的 `spark` 組態分類中將 `maximizeResourceAllocation` 設定為 `true`。`maximizeResourceAllocation` 專屬於 Amazon EMR。當您啟用 `maximizeResourceAllocation` 時，Amazon EMR 會計算在核心執行個體群組中，執行個體上執行器可用的最大運算和記憶體資源。然後，它會依據計算的最大值設定對應的 `spark-defaults` 設定。

Amazon EMR 會根據核心執行個體機群中的執行個體類型，計算執行器可用的最大運算和記憶體資源。由於每個執行個體機群在機群中都有不同的執行個體類型和大小，因此 Amazon EMR 使用的執行器組態可能不適合您的叢集，因此在使用資源配置上限時，我們不建議使用預設設定。為您的執行個體機群叢集設定自訂設定。

**注意**  
您不應該在叢集上搭配其他分散式應用程式 (例如 HBase) 來使用 `maximizeResourceAllocation` 選項。Amazon EMR 針對分散式應用程式使用自訂 YARN 組態，這可能會與 `maximizeResourceAllocation` 發生衝突並導致 Spark 應用程式失敗。

以下是 `maximizeResourceAllocation` 設定為 `true` 的 Spark 組態類別範例。

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


**當 `spark-defaults`啟用時，設定 `maximizeResourceAllocation` 中的組態設定**  

| 設定 | 說明 | Value | 
| --- | --- | --- | 
| spark.default.parallelism | 使用者未設定時，轉換 (如加入、reduceByKey，並平行處理) 傳回的 RDD 中的分割預設數量。 | YARN 容器可用的 CPU 核心 2X 數。 | 
| spark.driver.memory | 用於驅動程式程序 (也就是 SparkContext) 的記憶體數量。(例如 1g，2g)。 | 設定是以叢集中的執行個體類型為基礎來設定。然而，由於 Spark 驅動程式應用程式可能會在主執行個體或其中一個核心執行個體上執行 (例如分別在 YARN 用戶端和叢集模式中執行)，此會以這兩種執行個體群組中較小型的執行個體類型為依據來設定。 | 
| spark.executor.memory | 每個執行器程序要使用的記憶體量。(例如 1g，2g) | 設定是以叢集中的核心和任務執行個體類型為基礎來設定。 | 
| spark.executor.cores | 每個執行器上要使用的核心數。 | 設定是以叢集中的核心和任務執行個體類型為基礎來設定。 | 
| spark.executor.instances |  執行器數。 | 設定是以叢集中的核心和任務執行個體類型為基礎來設定。除非 `spark.dynamicAllocation.enabled` 同時明確設定設為 true，否則請如此設定。 | 

## 設定節點除役行為
<a name="spark-decommissioning"></a>

使用 Amazon EMR 5.9.0 版及更高版本時，Amazon EMR 上的 Spark 包含一組功能，可協助確保 Spark 從容地處理由於手動調整或自動擴展政策請求而終止的節點。Amazon EMR 在 Spark 實作列入拒絕清單機制，該 Spark 是根據 YARN 的除役機制而建置。此機制有助於確保不會在停用的節點上排定任何新任務的時程，同時讓已經在執行中的任務得以完成。此外，若混洗區塊在節點終止時遺失，有功能可幫助您更快地恢復 Spark 任務。重新計算程序的觸發速度更快，且已最佳化，重新計算速度更快，階段重試數更少，同時因為遺失混洗區塊而造成的擷取故障可避免任務失敗。

**重要**  
在 Amazon EMR 5.11.0 版中已新增 `spark.decommissioning.timeout.threshold` 設定，以改善在您使用 Spot 執行個體時的 Spark 彈性。當節點在較舊的版本中使用 Spot 執行個體時，執行個體會因為出價而終止，Spark 可能無法從容地處理終止。任務可能會失敗，且混洗重新計算可能需要耗費大量時間。因此，如果您使用的是 Spot 執行個體，建議您使用 5.11.0 版或更高版本。


**Spark 節點除役設定**  

| 設定 | 說明 | 預設值 | 
| --- | --- | --- | 
| `spark.blacklist.decommissioning.enabled` | 當設定為 `true` 時，Spark 會將在 YARN 中狀態為 `decommissioning` 的節點列入拒絕清單。Spark 不會在該節點上執行的執行者上排定新任務的時程。允許讓已執行的任務得以完成。 | `true` | 
| `spark.blacklist.decommissioning.timeout` | 節點狀態為 `decommissioning` 且列入拒絕清單的時間。在預設情況下，這個值會設為 1 小時，此值同樣是 `yarn.resourcemanager.decommissioning.timeout` 的預設值。為了確保節點在整個除役期間都是列入拒絕清單的狀態，將這個值設為等於或大於 `yarn.resourcemanager.decommissioning.timeout`。停用逾時過期後，節點會轉換至 `decommissioned` 狀態，而 Amazon EMR 可終止節點的 EC2 執行個體。如果任何任務在逾時過期後仍在執行中，他們在其他節點上執行的執行器上會遺失或遭移除或重新排程。 | `1h` | 
| `spark.decommissioning.timeout.threshold` | 在 Amazon EMR 5.11.0 版或更高版本中可供使用。以秒為單位指定。節點轉換至除役狀態時，如果主機在等於或小於此值的期間內除役，Amazon EMR 不僅會將節點列入拒絕清單，還會清除主機狀態 (如 `spark.resourceManager.cleanupExpiredHost` 中所指定)，而不會等待節點轉換至除役狀態。這可讓 Spark 用有效地處理 Spot 執行個體的終止，因為 Spot 執行個體會在 20 秒逾時內停用 (不論 `yarn.resourcemanager.decommissioning.timeout` 值為何)，而使得其他節點沒有足夠的時間來讀取混洗檔案。 | `20s` | 
| `spark.resourceManager.cleanupExpiredHost` | 當設定為 `true`，Spark 會取消註冊狀態為 `decommissioned` 之節點上執行器中存放的所有快取資料與混洗區塊。這可加快復原程序。 | `true` | 
| `spark.stage.attempt.ignoreOnDecommissionFetchFailure` | 設定為 `true` 有助於避免 Spark 在階段中失敗與在最終的任務失敗，因為從停用節點中擷取的失敗過多。無法從狀態為 `decommissioned` 的節點中擷取混洗區塊將不會計入連續擷取故障數上限。 | true | 

## Spark ThriftServer 環境變數
<a name="spark-thriftserver"></a>

Spark 會將 Hive Thrift 伺服器連接埠環境變數 (`HIVE_SERVER2_THRIFT_PORT`) 設為 10001。

## 變更 Spark 預設設定
<a name="spark-change-defaults"></a>

您可以在 `spark-defaults.conf` 中使用 `spark-defaults` 組態分類，或使用 `spark` 組態分類中的 `maximizeResourceAllocation` 變更預設值。

以下程序示範如何使用 CLI 或主控台修改設定。

**若要使用 CLI 建立 spark.executor.memory 設定為 2g 的叢集**
+ 使用以下命令，建立已安裝 Spark 且 `spark.executor.memory` 設為 2g 的叢集，該命令會參考存放於 Amazon S3 的檔案 `myConfig.json`。

  ```
  aws emr create-cluster --release-label {{emr-7.13.0}} --applications Name=Spark \
  --instance-type m5.xlarge --instance-count 2 --service-role EMR_DefaultRole_V2 --ec2-attributes InstanceProfile=EMR_EC2_DefaultRole --configurations https://s3.amazonaws.com/amzn-s3-demo-bucket/myfolder/myConfig.json
  ```
**注意**  
包含 Linux 行接續字元 (\\) 是為了提高可讀性。它們可以在 Linux 命令中移除或使用。對於 Windows，請將其移除或取代為插入符號 (^)。

  `myConfig.json`:

  ```
  [
      {
        "Classification": "spark-defaults",
        "Properties": {
          "spark.executor.memory": "2G"
        }
      }
    ]
  ```

**若要使用主控台建立 spark.executor.memory 設定為 2g 的叢集**

1. 導覽至新的 Amazon EMR 主控台，然後從側邊導覽選取**切換至舊主控台**。如需有關切換至舊主控台時預期情況的詳細資訊，請參閱[使用舊主控台](https://docs.aws.amazon.com/emr/latest/ManagementGuide/whats-new-in-console.html#console-opt-in)。

1. 選擇 **Create cluster (建立叢集)**，然後選擇 **Go to advanced options (前往進階選項)**。

1. 選擇 **Spark (Spark)**。

1. 在 **Edit software settings (編輯軟體設定)**，將 **Enter configuration (輸入組態)** 保持為選取的狀態，然後輸入以下組態：

   ```
   classification=spark-defaults,properties=[spark.executor.memory=2G]
   ```

1. 選取其他選項，選擇 ****，然後選擇 **Create cluster (建立叢集)**。

**若要設定 maximizeResourceAllocation**
+ 使用 建立已安裝 Spark 並`maximizeResourceAllocation`設為 true 的叢集， AWS CLI參考`myConfig.json`存放在 Amazon S3 中的檔案 。

  ```
  aws emr create-cluster --release-label {{emr-7.13.0}} --applications Name=Spark \
  --instance-type m5.xlarge --instance-count 2 --service-role EMR_DefaultRole_V2 --ec2-attributes InstanceProfile=EMR_EC2_DefaultRole --configurations https://s3.amazonaws.com/amzn-s3-demo-bucket/myfolder/myConfig.json
  ```
**注意**  
包含 Linux 行接續字元 (\\) 是為了提高可讀性。它們可以在 Linux 命令中移除或使用。對於 Windows，請將其移除或取代為插入符號 (^)。

  `myConfig.json`:

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

**注意**  
對於 Amazon EMR 版本 5.21.0 及更高版本，您可以覆寫叢集組態，並且為執行中叢集的每個執行個體群組，指定額外組態分類。您可以使用 Amazon EMR 主控台、 AWS Command Line Interface (AWS CLI) 或 AWS SDK 來執行此操作。如需詳細資訊，請參閱[為執行中叢集的執行個體群組提供組態](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-configure-apps-running-cluster.html)。

## 從 Apache Log4j 1.x 遷移至 Log4j 2.x
<a name="spark-migrate-logj42"></a>

[Apache Spark](https://aws.amazon.com/emr/features/spark/) 3.2.x 版及更早版本使用舊版 Apache Log4j 1.x 和 `log4j.properties` 檔案，設定 Spark 程序中的 Log4j。Apache Spark 3.3.0 版及更高版本使用 Apache Log4j 2.x 和 `log4j2.properties` 檔案，設定 Spark 程序中的 Log4j。

如果您已使用低於 6.8.0 的 Amazon EMR 版本設定 Apache Spark Log4j，則必須先移除舊版 `spark-log4j` 組態分類並遷移至 `spark-log4j2` 組態分類和金鑰格式，然後才能升級至 Amazon EMR 6.8.0 或更高版本。在 Amazon EMR 6.8.0 版及更高版本中，舊版 `spark-log4j` 分類會導致叢集建立失敗，並發生 `ValidationException` 錯誤。您不需要為與 Log4j 不相容性相關的失敗付費，但您必須移除已停用的 `spark-log4j` 組態分類才能繼續。

如需有關從 Apache Log4j 1.x 遷移至 Log4j 2.x 的詳細資訊，請參閱 Github 上的[《Apache Log4j 遷移指南》](https://logging.apache.org/log4j/2.x/manual/migration.html)和 [Spark Log4j 2 範本](https://github.com/apache/spark/blob/master/conf/log4j2.properties.template)。

**注意**  
藉由 Amazon EMR，Apache Spark 使用 `log4j2.properties` 檔案，而非《[Apache Log4j 遷移指南](https://logging.apache.org/log4j/2.x/manual/migration.html)》中所述的 .xml 檔案。此外，我們不建議使用 Log4j 1.x 橋接方法來轉換為 Log4j 2.x。