

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

# 將 Apache Spark 程式遷移至 AWS Glue
<a name="glue-author-migrate-apache-spark"></a>

Apache Spark 是在大型資料集上執行的分散式運算工作負載的開放原始碼平台。 AWS Glue 利用 Spark 的功能，為 ETL 提供最佳化的體驗。您可以將 Spark 程式遷移至 AWS Glue ，以利用我們的功能。 AWS Glue 提供與 Amazon EMR 上 Apache Spark 預期的相同效能增強功能。

## 執行 Spark 程式碼
<a name="glue-author-migrate-apache-spark-run"></a>

原生 Spark 程式碼可在開箱即用 AWS Glue 的環境中執行。指令碼通常是透過反覆變更一段程式碼來開發，這樣的工作流程很適合互動式工作階段。不過，現有的程式碼更適合在 AWS Glue 任務中執行，這可讓您排程和一致地取得每個指令碼執行的日誌和指標。您可以透過主控台上傳和編輯現有指令碼。

1. 取得指令碼的來源。在此範例中，您將使用 Apache Spark 儲存庫中的範例指令碼。[二值化器範例](https://github.com/apache/spark/blob/master/examples/src/main/python/ml/binarizer_example.py) 

1. 在 AWS Glue 主控台中，展開左側導覽窗格，然後選取 **ETL** > **任務** 

   在 **Create job** (建立任務) 面板中，選取 **Spark script editor** (Spark 指令碼編輯器)。**Options** (選項) 區段將會出現。在 **Options** (選項) 下，選取 **Upload and edit an existing script** (上傳並編輯現有的指令碼)。

   **File upload** (檔案上傳) 區段將會出現。在 **File upload** (檔案上傳) 下，按一下 **Choose file** (選擇檔案)。您的系統文件選擇器將會出現。導覽到您儲存 `binarizer_example.py` 的位置中，選取它並確認。

   **Create** (建立 )按鈕會出現在 **Create job** (建立任務) 面板的標頭。按一下該按鈕。  
![\[已選取具有 Spark 指令碼編輯器窗格的 AWS Glue Studio 任務頁面。\]](http://docs.aws.amazon.com/zh_tw/glue/latest/dg/images/migrate-apache-spark-01-upload-job.png)

1. 您的瀏覽器將導覽至指令碼編輯器。在標頭上，按一下 **Job details** (任務詳細資訊) 索引標籤。設定**名稱**和 **IAM 角色**。如需 IAM AWS Glue 角色的相關指導，請參閱 [設定 的 IAM 許可 AWS Glue](set-up-iam.md)。

   選用 - 將 **Requested number of workers** (請求的工作者數目) 設定為 `2`，並將 **Number of retries** (重試次數) 設定為 `1`。這些選項在執行生產任務時非常重要，但是在測試功能時，關閉這些選項可以簡化您的體驗。

   在標題列中，按一下 **Save** (儲存)，然後點選 **Run** (執行)  
![\[具有依照指示設定選項的任務詳細資訊頁面。\]](http://docs.aws.amazon.com/zh_tw/glue/latest/dg/images/migrate-apache-spark-02-job-details.png)

1. 導覽至 **Runs** (執行) 索引標籤。您會看到與您任務執行對應的面板。請稍候幾分鐘，頁面應該會自動重新整理，並在 **Run status** (執行狀態) 下顯示 **Succeeded** (成功)。  
![\[具有成功任務執行的任務執行頁面。\]](http://docs.aws.amazon.com/zh_tw/glue/latest/dg/images/migrate-apache-spark-03-job-runs.png)

1. 您需要檢查輸出，以確認 Spark 指令碼按預期執行。此 Apache Spark 範例指令碼應該將字串寫入至輸出串流。您可以透過導覽至成功任務執行面板中 **Cloudwatch logs** (CloudWatch 日誌) 下的 **Output logs** (輸出日誌) 找到該資料。請注意，任務執行運行 ID (在 **Id** 標籤下產生的 id) 以 `jr_` 開頭 。

   這會開啟 CloudWatch 主控台，將 設定為視覺化預設 AWS Glue 日誌群組 的內容`/aws-glue/jobs/output`，篩選成任務執行 ID 的日誌串流內容。每個工作者都會產生日誌串流，並在 **Log streams** (日誌串流) 下顯示為資料列。每個工作者應執行請求的程式碼。您需要開啟所有日誌串流來找出正確的工作者。找到正確的工作者之後，您應該會看到指令碼的輸出，如下圖所示：  
![\[具有 Spark 程式輸出的 CloudWatch 主控台頁面。\]](http://docs.aws.amazon.com/zh_tw/glue/latest/dg/images/migrate-apache-spark-04-log-output.png)

## 移轉 Spark 程式所需的常見程序
<a name="glue-author-migrate-apache-spark-migrate"></a>

### 評估 Spark 版本支援
<a name="glue-author-migrate-apache-spark-migrate-versions"></a>

 AWS Glue 發行版本定義任務可用的 Apache Spark 和 Python 版本 AWS Glue 。您可以在 找到我們的 AWS Glue 版本及其支援的內容[AWS Glue 版本](release-notes.md#release-notes-versions)。您可能需要更新 Spark 程式，以便與較新版本的 Spark 相容，才能存取部分 AWS Glue 功能。

### 包含第三方程式庫
<a name="glue-author-migrate-apache-spark-third-party-libraries"></a>

許多現有的 Spark 程式將具有相依性 (在私有和公有成品上)。 AWS Glue 支援 Scala 任務的 JAR 樣式相依性和 Python 任務的 Wheel 和來源純 Python 相依性。

**Python** - 如需 Python 相依性的相關資訊，請參閱 [搭配 Glue 使用 Python AWS 程式庫](aws-glue-programming-python-libraries.md)

 AWS Glue 環境中提供常見的 Python 相依性，包括常見的 [Pandas](https://pandas.pydata.org/) 程式庫。相依性包含在 AWS Glue 2.0 以上的版本中。如需有關所提供模組的詳細資訊，請參閱 [Python 模組已在 Glue AWS 中提供](aws-glue-programming-python-libraries.md#glue-modules-provided)。如果您需要提供的任務具有預設包含不同版本的相依性，您可以使用 `--additional-python-modules`。如需任務引數的相關資訊，請參閱 [在 Glue AWS 任務中使用任務參數](aws-glue-programming-etl-glue-arguments.md)。

您可以為額外的 Python 相依性提供 `--extra-py-files` 任務引數。如果您要從 Spark 程式移轉任務，這個參數就是一個不錯的選擇，因為其在功能上等同於 PySpark 中的 `--py-files` 旗標，並且受到相同限制。如需有關 `--extra-py-files` 參數的詳細資訊，請參閱 [包括 Python 檔案與 PySpark 原生功能](aws-glue-programming-python-libraries.md#extra-py-files-support)

對於新任務，您可以使用 `--additional-python-modules` 任務引數來管理 Python 相依性。使用此引數可以獲得更完善的相依性管理體驗。此參數支援 Wheel 樣式相依性，包含具有與 Amazon Linux 2 相容的原生程式碼繫結的相依性。

**Scala**

您可以為額外的 Scala 相依性提供 `--extra-jars` 任務引數。相依性必須在 Amazon S3 中託管，且引數值應為以逗號分隔的 Amazon S3 路徑清單，並不含空格。您可能會發現在託管和設定相依性之前重新綁定相依性，以便更輕鬆地管理組態。 AWS Glue JAR 相依性包含 Java 位元組碼，可從任何 JVM 語言產生。您可以使用其他 JVM 語言 (例如 Java) 來撰寫自訂相依性。

### 管理資料來源憑證
<a name="glue-author-migrate-apache-spark-credential-management"></a>

現有的 Spark 程式可能帶有複雜或自訂組態，以從其資料來源中提取資料。 AWS Glue 連線支援常見的資料來源身分驗證流程。如需有關 AWS Glue 連線的詳細資訊，請參閱 [連線至資料](glue-connections.md)。

AWS Glue 連線有助於以兩種主要方式將您的任務連線至各種類型的資料存放區：透過方法呼叫我們的程式庫，並在 AWS 主控台中設定**其他網路連線**。您也可以從任務中呼叫 AWS SDK，從連線擷取資訊。

 **方法呼叫** – AWS Glue 連線與 AWS Glue Data Catalog 緊密整合，這項服務可讓您策劃資料集的相關資訊，而可與 AWS Glue 連線互動的方法也反映了這一點。如果您有想要重複使用的現有身分驗證組態，對於 JDBC 連線，您可以透過 上的 `extract_jdbc_conf`方法存取 AWS Glue 連線組態`GlueContext`。如需詳細資訊，請參閱[extract\$1jdbc\$1conf](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-extract_jdbc_conf) 

**主控台組態** – AWS Glue 任務使用相關聯的 AWS Glue 連線來設定與 Amazon VPC 子網路的連線。如果您直接管理您的安全資料，您可能需要在 AWS 主控台中提供`NETWORK`類型 **其他網路連線** 來設定路由。如需有關 AWS Glue 連線 API 的詳細資訊，請參閱 [Connections API](aws-glue-api-catalog-connections.md)

如果您的 Spark 程式具有自訂或不常見的身分驗證流程，則可能需要以實作方式來管理安全素材。如果 AWS Glue 連線似乎不適合，您可以在 Secrets Manager 中安全地託管安全資料，並透過任務中提供的 boto3 或 AWS SDK 存取它們。

### 設定 Apache Spark
<a name="glue-author-migrate-apache-spark-spark-configuration"></a>

複雜的移轉通常會改變 Spark 組態，以因應其工作負載。現代版本的 Apache Spark 允許使用 `SparkSession`. AWS Glue 3.0\$1 任務設定執行期組態，並提供 `SparkSession`，可修改以設定執行期組態。[Apache Spark 組態](https://spark.apache.org/docs/latest/configuration.html)。調校 Spark 很複雜， AWS Glue 不保證支援設定所有 Spark 組態。如果您的遷移需要大量的 Spark 層級組態，請聯絡 支援。

### 設定自訂組態
<a name="glue-author-migrate-apache-spark-custom-configuration"></a>

遷移的 Spark 程式可能設計為採用自訂組態。 AWS Glue 允許透過任務引數在任務和任務執行層級上設定組態。如需任務引數的相關資訊，請參閱 [在 Glue AWS 任務中使用任務參數](aws-glue-programming-etl-glue-arguments.md)。您可以透過我們的程式庫在任務內容中存取任務引數。 AWS Glue 提供公用程式函數，以在任務上設定的引數與任務執行上設定的引數之間提供一致的檢視。請在 Python 中參閱 [使用 `getResolvedOptions` 存取參數](aws-glue-api-crawler-pyspark-extensions-get-resolved-options.md)，並在 Scala 中參閱 [AWS Glue Scala GlueArgParser API](glue-etl-scala-apis-glue-util-glueargparser.md)。

### 移轉 Java 程式碼
<a name="glue-author-migrate-apache-spark-java-code"></a>

如同 [包含第三方程式庫](#glue-author-migrate-apache-spark-third-party-libraries) 中所說明，您的相依性可以包含由 JVM 語言 (例如 Java 或 Scala) 產生的類別。您的相依性可以包含 `main` 方法。您可以在相依性中使用 `main`方法做為 Scala AWS Glue 任務的進入點。這可以讓您在 Java 中寫入 `main` 方法，或重複使用封裝至您自身程式庫標準的 `main` 方法。

若要使用來自相依性的 `main` 方法，請執行以下操作：清除提供預設 `GlueApp` 物件的編輯窗格內容。在相依性中提供完全合格的類別名稱，以作為具有金鑰 `--class` 的任務引數。然後，您應該能夠觸發任務執行。

您無法設定引數 AWS Glue 傳遞至 `main`方法的順序或結構。如果您現有的程式碼需要讀取 中設定的組態 AWS Glue，這可能會導致與先前的程式碼不相容。如果您使用 `getResolvedOptions`，也無法擁有能夠呼叫此方法的適當位置。考慮直接從 AWS Glue產生的主要方法來叫用您的相依性。下列 AWS Glue ETL 指令碼顯示此範例。

```
import com.amazonaws.services.glue.util.GlueArgParser

object GlueApp {
  def main(sysArgs: Array[String]) {
    val args = GlueArgParser.getResolvedOptions(sysArgs, Seq("JOB_NAME").toArray)
    
    // Invoke static method from JAR. Pass some sample arguments as a String[], one defined inline and one taken from the job arguments, using getResolvedOptions
    com.mycompany.myproject.MyClass.myStaticPublicMethod(Array("string parameter1", args("JOB_NAME")))
    
    // Alternatively, invoke a non-static public method.
    (new com.mycompany.myproject.MyClass).someMethod()
  }
}
```