共用方式為


在 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

  1. databricks_jar_test 資料夾中,使用下列內容來建立名為 PrintArgs.java 檔案:

    import java.util.Arrays;
    
    public class PrintArgs {
      public static void main(String[] args) {
        System.out.println(Arrays.toString(args));
      }
    }
    
  2. 編譯檔案 PrintArgs.java ,這會建立 檔案 PrintArgs.class

    javac PrintArgs.java
    
  3. (選擇性) 執行編譯的程式:

    java PrintArgs Hello World!
    
    # [Hello, World!]
    
  4. 在與 PrintArgs.javaPrintArgs.class 檔案相同的資料夾中,建立名為 META-INF 的資料夾。

  5. META-INF 資料夾中,使用下列內容來建立名為 MANIFEST.MF 檔案。 請務必在此檔案結尾加入新行:

    Main-Class: PrintArgs
    
  6. databricks_jar_test 資料夾的根目錄中,建立名為 PrintArgs.jar 的 JAR:

    jar cvfm PrintArgs.jar META-INF/MANIFEST.MF *.class
    
  7. (選擇性) 若要測試,請從資料夾的 databricks_jar_test 根目錄執行 JAR:

    java -jar PrintArgs.jar Hello World!
    
    # [Hello, World!]
    

    注意

    如果您 get 錯誤 no main manifest attribute, in PrintArgs.jar,請務必將新建行新增至 MANIFEST.MF 檔案的結尾,然後再嘗試創建並運行 JAR。

  8. 上傳 PrintArgs.jar 至磁碟區。 請參閱 將檔案上傳至 Unity Catalog 磁碟區

建立 Scala JAR

  1. databricks_jar_test 資料夾中,使用下列內容來建立名為 build.sbt 的空白檔案:

    ThisBuild / scalaVersion := "2.12.14"
    ThisBuild / organization := "com.example"
    
    lazy val PrintArgs = (project in file("."))
      .settings(
        name := "PrintArgs"
      )
    
  2. databricks_jar_test 資料夾建立資料夾結構 src/main/scala/example

  3. example 資料夾中,使用下列內容來建立名為 PrintArgs.scala 檔案:

    package example
    
    object PrintArgs {
      def main(args: Array[String]): Unit = {
        println(args.mkString(", "))
      }
    }
    
  4. 編譯該程式:

    sbt compile
    
  5. (選擇性) 執行編譯的程式:

    sbt "run Hello World\!"
    
    # Hello, World!
    
  6. databricks_jar_test/project 資料夾中,使用下列內容來建立名為 assembly.sbt 檔案:

    addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.0.0")
    
  7. databricks_jar_test 資料夾的根目錄執行 assembly 命令,這會在資料夾下 target 產生 JAR:

    sbt assembly
    
  8. (選擇性) 若要測試,請從資料夾的 databricks_jar_test 根目錄執行 JAR:

    java -jar target/scala-2.12/PrintArgs-assembly-0.1.0-SNAPSHOT.jar Hello World!
    
    # Hello, World!
    
  9. 上傳 PrintArgs-assembly-0.1.0-SNAPSHOT.jar 至磁碟區。 請參閱 上傳檔案至 Unity Catalog 磁碟區

步驟 3. 建立 Azure Databricks 作業以執行 JAR

  1. 移至您的 Azure Databricks 登陸頁面,並執行下列其中一項:
    • 按下側邊欄中的 工作流程圖示 [工作流程],然後按下 [建立作業] 按鈕
    • 在側邊欄中,點擊 新增圖示新增,然後從選單中選擇 select作業
  2. 在 [工作] 索引標籤上出現的 [工作] 對話方塊中,以您的作業名稱取代 [新增工作名稱...],例如 JAR example
  3. 針對 [工作名稱],輸入工作的名稱,例如 Java 的 java_jar_task 或 Scala 的 scala_jar_task
  4. 針對 Type,selectJAR
  5. 針對 [主類別],在此範例中,輸入 Java 的 PrintArgs 或 Scala 的 example.PrintArgs
  6. 針對 叢集的情況,select 是一個相容的叢集。 請參閱 Java 和 Scala 程式庫支援
  7. 針對 [相依程式庫],按下 [+ 新增]
  8. 在 [新增相依連結庫] 對話框中,選取 [Volumes],where 輸入您在上 Volumes 一個步驟中上傳 JAR 的位置PrintArgs.jarPrintArgs-assembly-0.1.0-SNAPSHOT.jar,或篩選或瀏覽以尋找 JAR。 Select執行。
  9. 按一下新增
  10. 針對 Parameters,在此範例中,輸入 ["Hello", "World!"]
  11. 按一下新增

步驟 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 作業,請參閱排程和協調工作流程