在 Azure Databricks 作業中使用 JAR
Java 封存或 JAR 檔案格式是以熱門的 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.java
和PrintArgs.class
檔案相同的資料夾中,建立名為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!]
注意
如果您 get 錯誤
no main manifest attribute, in PrintArgs.jar
,請務必將新建行新增至MANIFEST.MF
檔案的結尾,然後再嘗試創建並運行 JAR。上傳
PrintArgs.jar
至磁碟區。 請參閱 將檔案上傳至 Unity Catalog 磁碟區。
建立 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 Catalog 磁碟區。
步驟 3. 建立 Azure Databricks 作業以執行 JAR
- 移至您的 Azure Databricks 登陸頁面,並執行下列其中一項:
- 按下側邊欄中的 [工作流程],然後按下 。
- 在側邊欄中,點擊 新增,然後從選單中選擇 select作業。
- 在 [工作] 索引標籤上出現的 [工作] 對話方塊中,以您的作業名稱取代 [新增工作名稱...],例如
JAR example
。 - 針對 [工作名稱],輸入工作的名稱,例如 Java 的
java_jar_task
或 Scala 的scala_jar_task
。 - 針對 Type,selectJAR。
- 針對 [主類別],在此範例中,輸入 Java 的
PrintArgs
或 Scala 的example.PrintArgs
。 - 針對 叢集的情況,select 是一個相容的叢集。 請參閱 Java 和 Scala 程式庫支援。
- 針對 [相依程式庫],按下 [+ 新增]。
- 在 [新增相依連結庫] 對話框中,選取 [Volumes],where 輸入您在上 Volumes 一個步驟中上傳 JAR 的位置
PrintArgs.jar
或PrintArgs-assembly-0.1.0-SNAPSHOT.jar
,或篩選或瀏覽以尋找 JAR。 Select執行。 - 按一下新增。
- 針對 Parameters,在此範例中,輸入
["Hello", "World!"]
。 - 按一下新增。
步驟 4:執行作業並檢視作業執行詳細資料
按下 以執行工作流程。 若要查看執行的
執行完成時,輸出會顯示在 [輸出] 面板中,包括傳遞至工作的引數。
JAR 作業的輸出大小限制
作業輸出,例如發出至 stdout 的記錄輸出,受限於 20 MB 的大小 limit。 如果總輸出的大小較大,將會取消執行,並標示為失敗。
若要避免遇到此 limit,您可以將 spark.databricks.driver.disableScalaOutput
Spark 組態設定為 true
,防止 stdout 從驅動程式傳回至 Azure Databricks。 根據預設,此值為 false
。 旗標可控制 Scala JAR 作業和 Scala 筆記本的儲存格輸出。 如果已啟用旗標,Spark 不會將作業執行結果傳回用戶端。 旗標不會影響在叢集記錄檔中寫入的資料。 Databricks 建議只針對 JAR 作業的作業叢集設定此旗標,因為那會停用筆記本結果。
建議:使用共用的 SparkContext
因為 Azure Databricks 是受管理的服務,因此可能需要一些程式碼變更,以確保 Apache Spark 作業能夠正確執行。 JAR 作業程式必須使用共享之 SparkContext
API 來 getSparkContext
。 因為 Azure Databricks 會初始化 SparkContext
,因此叫用 new SparkContext()
的程式將會失敗。 若要 getSparkContext
,請只使用 Azure Databricks 所建立的共用 SparkContext
:
val goodSparkContext = SparkContext.getOrCreate()
val goodSparkSession = SparkSession.builder().getOrCreate()
使用共用的 SparkContext
時,您也應該避免使用數種方法。
- 不要呼叫
SparkContext.stop()
。 - 請勿在
System.exit(0)
應用程式結尾呼叫sc.stop()
或Main
。 這可能會導致未定義的行為。
建議:使用 try-finally
區塊進行作業清除
請考慮包含兩個部分的 JAR:
-
jobBody()
,其中包含作業的主要部分。 -
jobCleanup()
必須在jobBody()
之後執行,不論該函式成功或傳回例外狀況。
例如,jobBody()
建立 tables,jobCleanup()
刪除這些 tables。
確保呼叫清除方法的安全方法是在程式碼中放置 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 作業 parameters
將 parameters 以 JSON 字串陣列傳遞至 JAR 作業。 請參閱傳遞至作業 API 中[建立新作業]spark_jar_task
操作 () 之要求本文中的 POST /jobs/create
物件。 若要存取到這些 parameters,請檢查傳遞至 main
函式的 String
陣列。
套件組合程式庫相依性
Spark 驅動程式具有無法覆寫的特定程式庫相依性。 如果您的作業新增衝突的程式庫,Spark 驅動程式程式庫相依性優先。
若要 get 驅動程式函式庫依賴項的完整 list,請在連接至具有相同 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 作業,請參閱排程和協調工作流程。