다음을 통해 공유


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의 경우 JDK(Java Development Kit)입니다.
  • 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.class 파일을 만드는 PrintArgs.java 파일을 컴파일합니다.

    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!]
    

    참고 항목

    no main manifest attribute, in PrintArgs.jar 오류가 발생하면 MANIFEST.MF 파일 끝에 줄 바꿈을 추가한 다음 JAR을 다시 만들고 실행해 보세요.

  8. 볼륨에 PrintArgs.jar을 업로드합니다. Unity Catalog 볼륨에 파일 업로드를 참조하세요.

스칼라 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단계. JAR을 실행할 Azure Databricks 작업 만들기

  1. Azure Databricks 방문 페이지로 이동하여 다음 중 하나를 수행합니다.
    • 사이드바에서 워크플로 아이콘 워크플로를 클릭하고 작업 만들기 단추(을)를 클릭합니다.
    • 사이드바에서 새 아이콘새로 만들기를 클릭하고 메뉴에서 작업을 선택합니다.
  2. 작업 탭에 나타나는 작업 대화 상자에서 작업 이름 추가…를 작업 이름(예: JAR example)으로 바꿉니다.
  3. 작업 이름에 작업 이름을 입력합니다(예: Java의 경우 java_jar_task, Scala의 경우 scala_jar_task).
  4. 형식으로 JAR을 선택합니다.
  5. Main 클래스에 대해 이 예에서는 Java의 경우 PrintArgs를 입력하고 Scala의 경우 example.PrintArgs를 입력합니다.
  6. 클러스터의 경우 호환되는 클러스터를 선택합니다. Java 및 Scala 라이브러리 지원을 참조하세요.
  7. 종속 라이브러리의 경우 + 추가를 클릭합니다.
  8. 종속 라이브러리 추가 대화 상자에서 볼륨이 선택된 상태로 이전 단계에서 JAR(PrintArgs.jar 또는 PrintArgs-assembly-0.1.0-SNAPSHOT.jar)을 볼륨 파일 경로로 업로드한 위치를 입력하거나 JAR을 필터링하거나 검색하여 찾습니다. 이 폴더를 선택합니다.
  9. 추가를 클릭합니다.
  10. 이 예의 경우 매개 변수["Hello", "World!"]를 입력합니다.
  11. 추가를 클릭합니다.

4단계: 작업 실행 및 작업 실행 세부 정보 보기

지금 실행 버튼를 클릭하여 워크플로를 실행합니다. 실행 세부 정보를 보려면 트리거된 실행 팝업에서 실행 보기를 클릭하거나 작업 실행 보기에서 실행에 대한 시작 시간 열의 링크를 클릭합니다.

실행이 완료되면 작업에 전달된 인수를 포함하여 출력이 출력 패널에 표시됩니다.

JAR 작업에 대한 출력 크기 제한

stdout으로 내보내진 로그 출력과 같은 작업 출력에는 20MB 크기 제한이 적용됩니다. 총 출력 크기가 더 크면 실행이 취소되고 '실패'로 표시됩니다.

이 제한을 초과하지 않도록 방지하려면 spark.databricks.driver.disableScalaOutput Spark 구성을 true로 설정하여 stdout이 드라이버에서 Azure Databricks로 반환되지 않도록 방지할 수 있습니다. 기본적으로 플래그 값은 false입니다. 플래그는 Scala JAR 작업 및 Scala Notebook에 대한 셀 출력을 제어합니다. 플래그가 사용하도록 설정되면 Spark에서 작업 실행 결과를 클라이언트에 반환하지 않습니다. 플래그는 클러스터의 로그 파일에 기록되는 데이터에 영향을 미치지 않습니다. 이 플래그를 설정하면 Notebook 결과가 사용하지 않도록 설정되므로 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)

Azure Databricks에서 Spark 컨테이너의 수명을 관리하는 방식으로 인해 종료 후크가 안정적으로 실행되지 않습니다.

JAR 작업 매개 변수 구성

JSON 문자열 배열을 사용하여 매개 변수를 JAR 작업에 전달합니다. 작업 API의 새 작업 만들기 작업(POST /jobs/create)에 전달된 요청 본문의 spark_jar_task 개체를 참조하세요. 이러한 매개 변수에 액세스하려면 main 함수에 전달된 String 배열을 검사합니다.

라이브러리 종속성 관리

Spark 드라이버에는 재정의할 수 없는 특정 라이브러리 종속성이 있습니다. 작업이 충돌하는 라이브러리를 추가하는 경우 Spark 드라이버 라이브러리 종속성이 우선합니다.

드라이버 라이브러리 종속성의 전체 목록을 가져오려면 동일한 Spark 버전으로 구성된 클러스터(또는 검사하려는 드라이버가 있는 클러스터)에 연결된 Notebook 내에서 다음 명령을 실행합니다.

%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 작업을 만들고 실행하는 방법에 대한 자세한 내용은 워크플로 예약 및 오케스트레이션을 참조하세요.