외부 Apache Hive 메타스토어(레거시)

이 문서에서는 기존 외부 Apache Hive 메타스토어에 연결하도록 Azure Databricks 클러스터를 설정하는 방법을 설명합니다. 권장 메타스토어 설정 및 클러스터 구성 요구 사항에 대한 정보와 외부 메타스토어에 연결하도록 클러스터를 구성하는 방법을 알아볼 수 있습니다. Databricks 런타임에 포함된 Hive 라이브러리 버전은 관련 Databricks 런타임 버전 릴리스 정보를 참조하세요.

Important

  • SQL Server는 Hive 2.0 이상의 기본 메타스토어 데이터베이스로 작동하지만 이 문서 전체의 예제에서는 Azure SQL Database를 사용합니다.
  • HDInsight와의 Hive 메타스토어 호환성에 대한 자세한 내용은 Azure HDInsight의 외부 메타데이터 저장소 사용을 참조하세요.
  • Azure Database for MySQL을 외부 메타스토어로 사용하는 경우, 서버 쪽 데이터베이스 구성에서 lower_case_table_names 속성의 값을 1(기본값)에서 2로 변경해야 합니다. 자세한 내용은 Identifier Case Sensitivity(식별자 대/소문자 구분)를 참조하세요.

참고 항목

외부 메타스토어 사용은 레거시 데이터 거버넌스 모델입니다. Databricks는 Unity 카탈로그로 업그레이드하는 것이 좋습니다. Unity 카탈로그는 계정의 여러 작업 영역에서 데이터 액세스를 관리하고 감사하는 중앙 위치를 제공하여 데이터의 보안 및 거버넌스를 간소화합니다. Unity 카탈로그란?을 참조하세요.

Hive 메타스토어 설정

클러스터 내에서 실행되는 메타스토어 클라이언트는 JDBC를 사용하여 기본 메타스토어 데이터베이스에 직접 연결됩니다.

클러스터에서 메타스토어로의 네트워크 연결을 테스트하려면 Notebook 내에서 다음 명령을 실행하면 됩니다.

%sh
nc -vz <DNS name> <port>

라는 설치 관리자 실행 파일에 포함됩니다. 여기서

  • <DNS name>은 Azure SQL Database의 서버 이름입니다.
  • <port>는 데이터베이스의 포트입니다.

클러스터 구성

클러스터를 외부 메타스토어에 연결하려면 두 가지 구성 옵션 세트를 설정해야 합니다.

  • Spark 옵션은 메타스토어 클라이언트의 Hive 메타스토어 버전 및 JAR을 사용하여 Spark를 구성합니다.
  • Hive 옵션은 메타스토어 클라이언트가 외부 메타스토어에 연결하도록 구성합니다.

Spark 구성 옵션

spark.sql.hive.metastore.version을 다음과 같이 Hive 메타스토어의 버전 및 spark.sql.hive.metastore.jars로 설정합니다.

  • Hive 0.13: spark.sql.hive.metastore.jars를 설정하지 않습니다.

    참고 항목

    Hive 1.2.0 및 1.2.1은 Databricks Runtime 7.0 이상의 기본 제공 메타스토어가 아닙니다. Databricks Runtime 7.0 이상에서 Hive 1.2.0 또는 1.2.1을 사용하려면 메타스토어 jar을 다운로드하고 가리키기에서 설명하는 절차를 따르세요.

  • Hive 2.3.7(Databricks Runtime 7.0 - 9.x) 또는 Hive 2.3.9(Databricks Runtime 10.0 이상): spark.sql.hive.metastore.jars을(를) builtin(으)로 설정합니다.

  • 다른 모든 Hive 버전의 경우, Azure Databricks는 메타스토어 jar을 다운로드하고 가리키기에서 설명하는 절차에 따라 메타스토어 JAR을 다운로드하고 구성 spark.sql.hive.metastore.jars가 다운로드된 JAR을 가리키도록 설정할 것을 권장합니다.

메타스토어 jar을 다운로드하고 가리키기

  1. spark.sql.hive.metastore.jarsmaven으로 설정하고 spark.sql.hive.metastore.version을 메타스토어의 버전과 일치하도록 설정하여 클러스터를 만듭니다.

  2. 클러스터가 실행 중일 때 드라이버 로그를 검색하여 다음과 같은 줄을 찾습니다.

    17/11/18 22:41:19 INFO IsolatedClientLoader: Downloaded metastore jars to <path>
    

    디렉터리 <path>는 클러스터의 드라이버 모드에서 다운로드한 JAR의 위치입니다.

    또는 Scala Notebook에서 다음 코드를 실행하여 JAR의 위치를 출력할 수 있습니다.

    import com.typesafe.config.ConfigFactory
    val path = ConfigFactory.load().getString("java.io.tmpdir")
    
    println(s"\nHive JARs are downloaded to the path: $path \n")
    
  3. <path>를 클러스터의 정보로 바꾸어서 %sh cp -r <path> /dbfs/hive_metastore_jar을 실행하여 드라이버 노드에서 DBFS 클라이언트를 통해 이 디렉터리를 DBFS 루트의 hive_metastore_jar 디렉터리에 복사합니다.

  4. /dbfs/hive_metastore_jar을 노드의 로컬 파일 시스템으로 복사하는 init 스크립트를 만듭니다. 이때 init 스크립트가 DBFS 클라이언트에 액세스하기 전에 몇 초 동안 대기하도록 해야 합니다. 이렇게 하면 클라이언트가 준비됩니다.

  5. 이 디렉터리를 사용하려면 spark.sql.hive.metastore.jars를 설정합니다. init 스크립트가 /dbfs/hive_metastore_jar/databricks/hive_metastore_jars/로 복사하는 경우 spark.sql.hive.metastore.jars/databricks/hive_metastore_jars/*로 설정합니다. 이 위치는 뒤에 /*를 포함해야 합니다.

  6. 클러스터를 다시 시작합니다.

Hive 구성 옵션

이 섹션에서는 Hive와 관련된 옵션에 대해 설명합니다.

로컬 모드를 사용하여 외부 메타스토어에 연결하려면 다음과 같은 Hive 구성 옵션을 설정합니다.

# JDBC connect string for a JDBC metastore
javax.jdo.option.ConnectionURL <mssql-connection-string>

# Username to use against metastore database
javax.jdo.option.ConnectionUserName <mssql-username>

# Password to use against metastore database
javax.jdo.option.ConnectionPassword <mssql-password>

# Driver class name for a JDBC metastore
javax.jdo.option.ConnectionDriverName com.microsoft.sqlserver.jdbc.SQLServerDriver

라는 설치 관리자 실행 파일에 포함됩니다. 여기서

  • <mssql-connection-string>은 (Azure Portal에서 확인할 수 있는) JDBC 연결 문자열입니다. 연결 문자열에 사용자 이름과 암호를 설정할 필요는 없습니다. 사용자 이름과 암호는 javax.jdo.option.ConnectionUserNamejavax.jdo.option.ConnectionDriverName에 의해 설정됩니다.
  • <mssql-username><mssql-password>는 데이터베이스에 대한 읽기/쓰기 권한을 갖는 Azure SQL Database 계정의 사용자 이름 및 암호를 지정합니다.

참고 항목

프로덕션 환경에서는 hive.metastore.schema.verificationtrue로 설정하는 것이 좋습니다. 이렇게 하면 메타스토어 클라이언트 버전이 메타스토어 데이터베이스 버전과 일치하지 않는 경우에도 Hive 메타스토어 클라이언트가 메타스토어 데이터베이스 스키마를 암시적으로 수정하지 않습니다. Hive 1.2.0보타 낮은 메타스토어 클라이언트 버전에 대해 이 설정을 사용하도록 설정할 때는 (HIVE-9749에서 설명하는 문제를 방지하기 위해) 메타스토어 클라이언트가 메타스토어 데이터베이스에 대한 쓰기 권한을 가져야 합니다.

  • Hive 메타스토어 1.2.0 이상의 경우, hive.metastore.schema.verification.record.versiontrue로 설정하여 hive.metastore.schema.verification을 사용하도록 설정합니다.
  • Hive 메타스토어 2.1.1 이상의 경우, hive.metastore.schema.verification.record.version이 기본적으로 false로 설정되어 있으므로 true로 설정합니다.

UI를 사용하여 외부 메타스토어 설정

Azure Databricks UI를 사용하여 외부 메타스토어를 설정하려면 다음을 수행합니다.

  1. 사이드바의 클러스터 단추를 클릭합니다.

  2. 클러스터 만들기를 클릭합니다.

  3. 다음 Spark 구성 옵션을 입력합니다.

    # Hive-specific configuration options.
    # spark.hadoop prefix is added to make sure these Hive specific options propagate to the metastore client.
    # JDBC connect string for a JDBC metastore
    spark.hadoop.javax.jdo.option.ConnectionURL <mssql-connection-string>
    
    # Username to use against metastore database
    spark.hadoop.javax.jdo.option.ConnectionUserName <mssql-username>
    
    # Password to use against metastore database
    spark.hadoop.javax.jdo.option.ConnectionPassword <mssql-password>
    
    # Driver class name for a JDBC metastore
    spark.hadoop.javax.jdo.option.ConnectionDriverName com.microsoft.sqlserver.jdbc.SQLServerDriver
    
    # Spark specific configuration options
    spark.sql.hive.metastore.version <hive-version>
    # Skip this one if <hive-version> is 0.13.x.
    spark.sql.hive.metastore.jars <hive-jar-source>
    
  4. 컴퓨팅 구성 참조의 지침에 따라 클러스터 구성을 계속합니다.

  5. 클러스터 만들기를 클릭하여 클러스터를 만듭니다.

init 스크립트를 사용하여 외부 메타스토어 설정

init 스크립트를 사용하면 필요한 구성을 수동으로 설정하지 않고도 기존 Hive 메타스토어에 연결할 수 있습니다.

  1. init 스크립트를 저장할 기본 디렉터리를 만듭니다(디렉터리가 없는 경우). 다음 예제에서는 dbfs:/databricks/scripts을(를) 사용합니다.
  2. Notebook에서 다음 코드 조각을 실행합니다. 이 코드 조각은 DBFS(Databricks File System)에 init 스크립트 /databricks/scripts/external-metastore.sh를 만듭니다. 또는 DBFS REST API의 put 작업을 사용하여 init 스크립트를 만들 수도 있습니다. 이 init 스크립트는 이름이 <cluster-name>으로 지정된 클러스터가 시작될 때마다 클러스터의 모든 노드 내에서 /databricks/driver/conf/에 JSON과 비슷한 형식의 구성 파일 00-custom-spark.conf에 필요한 구성 옵션을 씁니다. Azure Databricks는 /databricks/driver/conf/spark-branch.conf 파일에 기본 Spark 구성을 제공합니다. /databricks/driver/conf 디렉터리의 구성 파일은 알파벳 역순으로 적용됩니다. 00-custom-spark.conf 파일의 이름을 변경하려면 변경된 이름이 spark-branch.conf 앞에 오도록 지정해야 합니다.

Scala

dbutils.fs.put(
    "/databricks/scripts/external-metastore.sh",
    """#!/bin/sh
      |# Loads environment variables to determine the correct JDBC driver to use.
      |source /etc/environment
      |# Quoting the label (i.e. EOF) with single quotes to disable variable interpolation.
      |cat << 'EOF' > /databricks/driver/conf/00-custom-spark.conf
      |[driver] {
      |    # Hive specific configuration options.
      |    # spark.hadoop prefix is added to make sure these Hive specific options will propagate to the metastore client.
      |    # JDBC connect string for a JDBC metastore
      |    "spark.hadoop.javax.jdo.option.ConnectionURL" = "<mssql-connection-string>"
      |
      |    # Username to use against metastore database
      |    "spark.hadoop.javax.jdo.option.ConnectionUserName" = "<mssql-username>"
      |
      |    # Password to use against metastore database
      |    "spark.hadoop.javax.jdo.option.ConnectionPassword" = "<mssql-password>"
      |
      |    # Driver class name for a JDBC metastore
      |    "spark.hadoop.javax.jdo.option.ConnectionDriverName" = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
      |
      |    # Spark specific configuration options
      |    "spark.sql.hive.metastore.version" = "<hive-version>"
      |    # Skip this one if <hive-version> is 0.13.x.
      |    "spark.sql.hive.metastore.jars" = "<hive-jar-source>"
      |}
      |EOF
      |""".stripMargin,
    overwrite = true
)

Python

contents = """#!/bin/sh
# Loads environment variables to determine the correct JDBC driver to use.
source /etc/environment
# Quoting the label (i.e. EOF) with single quotes to disable variable interpolation.
cat << 'EOF' > /databricks/driver/conf/00-custom-spark.conf
[driver] {
    # Hive specific configuration options.
    # spark.hadoop prefix is added to make sure these Hive specific options will propagate to the metastore client.
    # JDBC connect string for a JDBC metastore
    "spark.hadoop.javax.jdo.option.ConnectionURL" = "<mssql-connection-string>"

    # Username to use against metastore database
    "spark.hadoop.javax.jdo.option.ConnectionUserName" = "<mssql-username>"

    # Password to use against metastore database
    "spark.hadoop.javax.jdo.option.ConnectionPassword" = "<mssql-password>"

    # Driver class name for a JDBC metastore
    "spark.hadoop.javax.jdo.option.ConnectionDriverName" = "com.microsoft.sqlserver.jdbc.SQLServerDriver"

    # Spark specific configuration options
    "spark.sql.hive.metastore.version" = "<hive-version>"
    # Skip this one if <hive-version> is 0.13.x.
    "spark.sql.hive.metastore.jars" = "<hive-jar-source>"
    }
EOF
"""

dbutils.fs.put(
    file = "/databricks/scripts/external-metastore.sh",
    contents = contents,
    overwrite = True
)
  1. init 스크립트를 사용하여 클러스터를 구성합니다.
  2. 클러스터를 다시 시작합니다.

문제 해결

(올바르지 않은 init 스크립트 설정으로 인해) 클러스터가 시작되지 않음

외부 메타스토어를 설정하기 위한 init 스크립트로 인해 클러스터 만들기가 실패하는 경우 init 스크립트를 구성하여 로그를 사용하여 init 스크립트를 디버그합니다.

SQL 문의 오류: InvocationTargetException

  • 전체 예외 스택 추적의 오류 메시지 패턴.

    Caused by: javax.jdo.JDOFatalDataStoreException: Unable to open a test connection to the given database. JDBC url = [...]
    

    외부 메타스토어 JDBC 연결 정보가 잘못 구성되었습니다. 구성된 호스트 이름, 포트, 사용자 이름, 암호 및 JDBC 드라이버 클래스 이름을 확인합니다. 또한 사용자 이름에 메타스토어 데이터베이스에 액세스할 수 있는 올바른 권한이 있는지 확인합니다.

  • 전체 예외 스택 추적의 오류 메시지 패턴.

    Required table missing : "`DBS`" in Catalog "" Schema "". DataNucleus requires this table to perform its persistence operations. [...]
    

    외부 메타스토어 데이터베이스가 올바르게 초기화되지 않았습니다. 메타스토어 데이터베이스를 만들었고 JDBC 연결 문자열에 올바른 데이터베이스 이름을 입력했는지 확인합니다. 그런 다음 아래의 두 가지 Spark 구성 옵션을 사용하여 새 클러스터를 시작합니다.

    datanucleus.schema.autoCreateTables true
    datanucleus.fixedDatastore false
    

    이렇게 하면 Hive 클라이언트 라이브러리가 메타스토어 데이터베이스에 액세스하려고 시도했는데 데이터베이스가 없는 것으로 확인되면 자동으로 테이블을 만들고 초기화하려고 시도합니다.

SQL 문의 오류: AnalysisException: org.apache.hadoop.hive.metastore.HiveMetastoreClient를 인스턴스화할 수 없습니다

전체 예외 스택 추적의 오류 메시지:

The specified datastore driver (driver name) was not found in the CLASSPATH

클러스터가 올바르지 않은 JDBC 드라이버를 사용하도록 구성되었습니다.

datanucleus.autoCreateSchema를 true로 설정해도 예상대로 작동하지 않음

기본적으로, Databricks는 datanucleus.fixedDatastoretrue로 설정하는데, 이는 메타스토어 데이터베이스에 대한 우발적인 구조적 변경을 방지합니다. 따라서 Hive 클라이언트 라이브러리는 사용자가 datanucleus.autoCreateSchematrue로 설정하더라도 메타스토어 테이블을 만들 수 없습니다. 이 전략은 메타스토어 데이터베이스를 실수로 업그레이드하는 일을 방지하므로 일반적으로 프로덕션 환경에서 보다 안전합니다.

메타스토어 데이터베이스를 초기화하는 데 datanucleus.autoCreateSchema를 사용하려면 datanucleus.fixedDatastorefalse로 설정해야 합니다. 또한 메타스토어 데이터베이스를 초기화한 후 두 플래그를 모두 대칭 이동하면 프로덕션 환경에 더 나은 보호를 제공할 수 있습니다.