外部 Apache Hive 中繼存放區 (舊版)

本文說明如何設定 Azure Databricks 叢集以連線到現有的外部 Apache Hive 中繼存放區。 其提供建議中繼存放區設定和叢集設定需求的相關信息,後面接著設定叢集以連線到外部中繼存放區的指示。 如需 Databricks Runtime 中包含的 Hive 連結庫版本,請參閱相關的 Databricks Runtime 版本版本 資訊

重要

  • 雖然 SQL Server 可作為 Hive 2.0 和更新版本的基礎中繼存放區資料庫,但本文中的範例會使用 Azure SQL 資料庫。
  • 如需Hive中繼存放區與 HDInsight 相容性的詳細資訊,請參閱 在 Azure HDInsight 中使用外部元數據存放區。
  • 如果您使用 適用於 MySQL 的 Azure 資料庫 做為外部中繼存放區,則必須在伺服器端資料庫組態中將 屬性的值lower_case_table_names從 1 (預設值) 變更為 2。 如需詳細資訊,請參閱 標識符區分大小寫

注意

使用外部中繼存放區是舊版數據控管模型。 Databricks 建議您升級至 Unity 目錄。 Unity 目錄藉由提供集中位置來管理和稽核帳戶中多個工作區的數據存取,藉此簡化數據的安全性和控管。 請參閱 什麼是 Unity 目錄?

Hive 中繼存放區設定

叢集內執行的中繼存放區用戶端會使用 JDBC 直接連線到您的基礎中繼存放區資料庫。

若要測試從叢集到中繼存放區的網路連線,您可以在筆記本內執行下列命令:

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

where

  • <DNS name>是 Azure SQL 資料庫 的伺服器名稱。
  • <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.jarsbuiltin

  • 針對所有其他Hive版本,Azure Databricks建議您下載中繼存放區 JAR,並使用下載中繼存放區 jar 中所述的程式,將設定設為spark.sql.hive.metastore.jars指向所下載的 JAR,並指向它們

下載中繼存放區 jar 並指向它們

  1. 建立設定為 mavenspark.sql.hive.metastore.version符合中繼存放區版本的叢集spark.sql.hive.metastore.jars

  2. 當叢集執行時,搜尋驅動程序記錄,並尋找如下的一行:

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

    目錄 <path> 是叢集驅動程序節點中下載的 JAR 位置。

    或者,您可以在 Scala 筆記本中執行下列程式代碼,以列印 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. 執行 %sh cp -r <path> /dbfs/hive_metastore_jar [以叢集的資訊取代 <path> ] ,將此目錄複製到驅動程序節點中透過 DBFS 用戶端呼叫 hive_metastore_jar 的 DBFS 根目錄中。

  4. 建立 init 腳本 ,以複製到 /dbfs/hive_metastore_jar 節點的本機文件系統,請務必讓 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

where

  • <mssql-connection-string>是 JDBC 連接字串 (您可以在 Azure 入口網站 中取得)。 您不需要在 連接字串 中包含使用者名稱和密碼,因為這些會由 javax.jdo.option.ConnectionUserNamejavax.jdo.option.ConnectionDriverName設定。
  • <mssql-username><mssql-password>指定具有資料庫讀取/寫入存取權的 Azure SQL 資料庫 帳戶的使用者名稱和密碼。

注意

針對生產環境,我們建議您將 設定 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.versiontruefalse

使用 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 文稿不存在,請建立您要將 init 腳本儲存在中的基底目錄。 下列範例會使用 dbfs:/databricks/scripts
  2. 在筆記本中執行下列代碼段。 代碼段會在 Databricks 檔案系統 (DBFS)建立 init 腳本/databricks/scripts/external-metastore.sh。 或者,您可以使用 DBFS REST API 的 put 作業 來建立 init 腳本。 此 init 文稿會在叢集的每個節點下,將所需的組態選項寫入 JSON 格式/databricks/driver/conf/的組態檔00-custom-spark.conf,每當名稱指定為 <cluster-name> 開頭的叢集時。 Azure Databricks 會在 檔案中提供預設 Spark /databricks/driver/conf/spark-branch.conf 組態。 目錄中的 /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,這可防止中繼存放區資料庫發生任何意外的結構變更。 因此,即使您將 設定 datanucleus.autoCreateSchematrue,Hive 用戶端連結庫也無法建立中繼存放區數據表。 一般而言,此策略對於生產環境更安全,因為它可防止意外升級中繼存放區資料庫。

如果您要使用 datanucleus.autoCreateSchema 協助初始化中繼存放區資料庫,請務必將 設定 datanucleus.fixedDatastorefalse。 此外,您可能想要在初始化中繼存放區資料庫之後翻轉這兩個旗標,為您的生產環境提供更好的保護。