在 Azure Databricks 作業中使用 JAR
Java 封存或 [JAR](https://en.wikipedia.org/wiki/JAR_(file_format) 檔格式是以熱門的 ZIP 檔案格式為基礎,用來將許多 Java 或 Scala 檔案匯總成一個。 使用 JAR 工作,您可以確保 Azure Databricks 作業中 Java 或 Scala 程式代碼的快速且可靠安裝。 本文提供建立 JAR 的範例,以及執行在 JAR 中封裝之應用程式的作業。 在這裡範例中,您將:
- 建立定義範例應用程式的 JAR 專案。
- 將範例檔案組合成 JAR。
- 建立作業以執行 JAR。
- 執行作業並檢視結果。
開始之前
您需要下列專案才能完成此範例:
- 針對 Java JAR,Java 開發工具套件 (JDK) 。
- 針對 Scala JAR,JDK 和 sbt。
步驟 1:建立範例的本機目錄
建立本機目錄以儲存範例程式代碼和產生的成品,例如 databricks_jar_test
。
步驟 2:建立 JAR
完成下列指示,以使用Java或 Scala 來建立 JAR。
建立 Java JAR
databricks_jar_test
從資料夾建立名為PrintArgs.java
的檔案,其中包含下列內容:import java.util.Arrays; public class PrintArgs { public static void main(String[] args) { System.out.println(Arrays.toString(args)); } }
編譯檔案
PrintArgs.java
,這會建立 檔案PrintArgs.class
:javac PrintArgs.java
(選擇性)執行編譯的程式:
java PrintArgs Hello World! # [Hello, World!]
在與 和
PrintArgs.class
檔案相同的資料夾中PrintArgs.java
,建立名為META-INF
的資料夾。在
META-INF
資料夾中,使用下列內容來建立名為MANIFEST.MF
檔案。 請務必在此檔案結尾新增換行符:Main-Class: PrintArgs
從資料夾的
databricks_jar_test
根目錄中,建立名為PrintArgs.jar
的 JAR:jar cvfm PrintArgs.jar META-INF/MANIFEST.MF *.class
(選擇性)若要測試它,請從資料夾的
databricks_jar_test
根目錄執行 JAR:java -jar PrintArgs.jar Hello World! # [Hello, World!]
注意
如果您收到錯誤
no main manifest attribute, in PrintArgs.jar
,請務必將換行符新增至檔案結尾MANIFEST.MF
,然後再嘗試建立並執行 JAR。上傳
PrintArgs.jar
至磁碟區。 請參閱 將檔案上傳至 Unity 目錄磁碟區。
建立 Scala JAR
databricks_jar_test
從資料夾中,使用下列內容建立名為build.sbt
的空白檔案:ThisBuild / scalaVersion := "2.12.14" ThisBuild / organization := "com.example" lazy val PrintArgs = (project in file(".")) .settings( name := "PrintArgs" )
databricks_jar_test
從資料夾,建立資料夾結構src/main/scala/example
。在
example
資料夾中,使用下列內容建立名為PrintArgs.scala
的檔案:package example object PrintArgs { def main(args: Array[String]): Unit = { println(args.mkString(", ")) } }
編譯程式:
sbt compile
(選擇性)執行編譯的程式:
sbt "run Hello World\!" # Hello, World!
在
databricks_jar_test/project
資料夾中,使用下列內容建立名為assembly.sbt
的檔案:addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.0.0")
從資料夾的
databricks_jar_test
根目錄執行assembly
命令,這會在資料夾下target
產生 JAR:sbt assembly
(選擇性)若要測試它,請從資料夾的
databricks_jar_test
根目錄執行 JAR:java -jar target/scala-2.12/PrintArgs-assembly-0.1.0-SNAPSHOT.jar Hello World! # Hello, World!
上傳
PrintArgs-assembly-0.1.0-SNAPSHOT.jar
至磁碟區。 請參閱 將檔案上傳至 Unity 目錄磁碟區。
步驟 3. 建立 Azure Databricks 作業以執行 JAR
- 移至您的 Azure Databricks 登陸頁面,並執行下列其中一項:
- 在提要欄位中,按兩下
[工作流程],然後按下 。
- 在提要欄位中,按兩下
[新增 ],然後從功能表中選取 [作業 ]。
- 在提要欄位中,按兩下
- 在 [工作] 索引標籤上出現的 [工作] 對話框中,以您的作業名稱取代 [新增工作名稱...],例如
JAR example
。 - 針對 [ 工作名稱],輸入工作的名稱,例如
java_jar_task
Java 或scala_jar_task
Scala。 - 針對 [ 類型],選取 [JAR]。
- 針對Main類別,在此範例中,輸入
PrintArgs
Java或example.PrintArgs
Scala。 - 針對 [ 叢集],選取兼容的叢集。 請參閱 Java 和 Scala 連結庫支援。
- 針對 [ 相依連結庫],按兩下 [ + 新增]。
- 在 [ 新增相依連結庫 ] 對話框中,選取 [磁碟 區],輸入您在上一個步驟中將 JAR (
PrintArgs.jar
或PrintArgs-assembly-0.1.0-SNAPSHOT.jar
) 上傳至 磁碟區檔案路徑的位置,或篩選或瀏覽以尋找 JAR。 選取該連結。 - 按一下新增。
- 針對 [參數],在此範例中,輸入
["Hello", "World!"]
。 - 按一下新增。
步驟 4:執行作業並檢視作業執行詳細數據
按兩下 即可執行工作流程。 若要檢視執行的詳細數據,請按兩下 [觸發的執行] 彈出視窗中的 [檢視執行],或按下作業執行檢視中執行之 [開始時間] 資料行中的連結。
執行完成時,輸出會顯示在 [輸出 ] 面板中,包括傳遞至工作的自變數。
JAR 作業的輸出大小限制
作業輸出,例如發出至 stdout 的記錄輸出,受限於 20 MB 的大小限制。 如果總輸出的大小較大,則會取消執行並標示為失敗。
若要避免遇到此限制,您可以將Sparktrue
組態設為 spark.databricks.driver.disableScalaOutput
,以防止從驅動程式傳回 stdout 至 Azure Databricks。 根據預設,旗標值為 false
。 旗標可控制 Scala JAR 作業和 Scala 筆記本的數據格輸出。 如果已啟用 旗標,Spark 不會將作業執行結果傳回給用戶端。 旗標不會影響在叢集記錄檔中寫入的數據。 Databricks 建議只針對 JAR 作業的作業叢集設定此旗標,因為它會停用筆記本結果。
建議:使用共用 SparkContext
因為 Azure Databricks 是受控服務,因此可能需要一些程式碼變更,以確保 Apache Spark 作業能夠正確執行。 JAR 作業程式必須使用共用 SparkContext
API 來取得 SparkContext
。 因為 Azure Databricks 會初始化 SparkContext
,因此叫 new SparkContext()
用的程式將會失敗。 若要取得 SparkContext
,請只使用 Azure Databricks 所建立的共用 SparkContext
:
val goodSparkContext = SparkContext.getOrCreate()
val goodSparkSession = SparkSession.builder().getOrCreate()
使用共用 SparkContext
時,您也應該避免使用數種方法。
- 請不要呼叫
SparkContext.stop()
。 - 請勿在應用程式結尾
Main
呼叫System.exit(0)
或sc.stop()
。 這可能會導致未定義的行為。
建議:使用 try-finally
區塊進行作業清除
請考慮包含兩個部分的 JAR:
jobBody()
,其中包含作業的主要部分。jobCleanup()
必須在 之後jobBody()
執行,不論該函式成功或傳回例外狀況。
例如, jobBody()
建立數據表並 jobCleanup()
卸除這些數據表。
確保呼叫清除方法的安全方法是在程式碼中放置區塊 try-finally
:
try {
jobBody()
} finally {
jobCleanup()
}
您 不應該 嘗試使用 sys.addShutdownHook(jobCleanup)
或下列程式代碼清除:
val cleanupThread = new Thread { override def run = jobCleanup() }
Runtime.getRuntime.addShutdownHook(cleanupThread)
由於 Spark 容器的存留期在 Azure Databricks 中管理的方式,因此無法可靠地執行關機攔截。
設定 JAR 作業參數
您可以使用 JSON 字串數位將參數傳遞至 JAR 作業。 spark_jar_task
請參閱傳遞至作業 API 中建立新作業作業 (POST /jobs/create
) 的要求本文中的 物件。 若要存取這些參數,請檢查傳入函main
式的String
陣列。
管理連結庫相依性
Spark 驅動程式具有無法覆寫的特定連結庫相依性。 如果您的作業新增衝突的連結庫,Spark 驅動程式連結庫相依性優先。
若要取得驅動程式連結庫相依性的完整清單,請在附加至具有相同 Spark 版本的叢集的筆記本中執行下列命令(或具有您要檢查之驅動程式的叢集):
%sh
ls /databricks/jars
當您定義 JAR 的連結庫相依性時,Databricks 建議將 Spark 和 Hadoop 列為 provided
相依性。 在 Maven 中,新增 Spark 和 Hadoop 作為提供的相依性:
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>2.3.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>1.2.1</version>
<scope>provided</scope>
</dependency>
在 中 sbt
,新增 Spark 和 Hadoop 作為提供的相依性:
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.3.0" % "provided"
libraryDependencies += "org.apache.hadoop" %% "hadoop-core" % "1.2.1" % "provided"
提示
根據您執行的版本,為您的相依性指定正確的 Scala 版本。
後續步驟
若要深入瞭解如何建立和執行 Azure Databricks 作業,請參閱 建立和執行 Azure Databricks 作業。
意見反映
https://aka.ms/ContentUserFeedback。
即將推出:我們會在 2024 年淘汰 GitHub 問題,並以全新的意見反應系統取代並作為內容意見反應的渠道。 如需更多資訊,請參閱:提交及檢視以下的意見反映: