共用方式為


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

重要

此文件已停止更新,可能會包含過時資料。

注意

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

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

重要

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

Hive 中繼存放區設定

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

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

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

where

  • <DNS name>是 Azure SQL 資料庫 的伺服器名稱。
  • <port> 是資料庫的埠。

叢集組態

您必須 set 兩組設定選項,才能將叢集連線到外部後設存放區。

  • Spark 選項 會使用 Hive 中繼存放區版本和中繼存放區用戶端的 JAR 來設定 Spark。
  • Hive 選項 會設定中繼存放區用戶端以連線到外部中繼存放區。

Spark 組態選項

Set spark.sql.hive.metastore.version Hive 中繼存放區的版本,並 spark.sql.hive.metastore.jars,如下所示:

  • Hive 0.13:請勿 setspark.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 及以上版本):setspark.sql.hive.metastore.jarsbuiltin

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

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

  1. 建立叢集,使用 spark.sql.hive.metastore.jars、set 到 mavenspark.sql.hive.metastore.version,以符合中繼存放區的版本。

  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. Set spark.sql.hive.metastore.jars 使用此目錄。 如果您的 init 指令稿將 /dbfs/hive_metastore_jar 複製到 /databricks/hive_metastore_jars/,將 setspark.sql.hive.metastore.jars 複製至 /databricks/hive_metastore_jars/*。 位置結尾必須包含 /*

  6. 重新啟動叢集。

Hive 組態選項

本節說明 Hive 特有的選項。

若要以本機模式連接到外部中繼存放區,請設定set 下列 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 入口網站中 get)。 您不需要在連接字串中包含使用者名稱和密碼,因為這些會由 set、javax.jdo.option.ConnectionUserNamejavax.jdo.option.ConnectionDriverName處理。
  • <mssql-username><mssql-password>指定具有資料庫讀取/寫入存取權的 Azure SQL 資料庫 帳戶的使用者名稱和密碼。

注意

針對生產環境,我們建議您將 sethive.metastore.schema.verification 轉換為 true。 這可防止Hive中繼存放區用戶端在中繼存放區用戶端版本不符合中繼存放區資料庫版本時,隱含修改中繼存放區資料庫 schema。 針對低於Hive 1.2.0的中繼存放區用戶端版本啟用此設定時,請確定中繼存放區用戶端具有中繼存放區資料庫的寫入許可權(以避免HIVE-9749中所述的問題)。

  • 針對 Hive 中繼存放區 1.2.0 和更新版本,sethive.metastore.schema.verification.record.versiontrue 啟用 hive.metastore.schema.verification
  • 針對Hive中繼存放區2.1.1和更高版本,sethive.metastore.schema.verification.record.versiontrue,因為預設情況下它是set到false

使用UI設定外部中繼資料存放區Set

若要使用 Azure Databricks UI 來 set 外部中繼存放區:

  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 命令稿 Set 外部中繼存放區

Init 腳本 可讓您連線到現有的 Hive 中繼存放區,而不需要手動設定必要的設定。

  1. 如果 init 文稿不存在,請建立您要將 init 腳本儲存在中的基底目錄。 下列範例會使用 dbfs:/databricks/scripts
  2. 在筆記本中執行下列代碼段。 代碼段會在 Databricks 檔案系統 (DBFS)/databricks/scripts/external-metastore.sh建立 init 腳本。 或者,您可以使用 DBFS REST API 的 put 作業 來建立 init 腳本。 此 init 文稿會在叢集的每個節點下,將所需的組態選項寫入 JSON 格式00-custom-spark.conf的組態檔/databricks/driver/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 用戶端程式庫將在嘗試存取時,若發現它們不存在,就會在中繼存放區資料庫中自動建立和初始化 tables。

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,這可防止中繼存放區資料庫發生任何意外的結構變更。 因此,即使您 setdatanucleus.autoCreateSchematrue,Hive 用戶端程式庫仍無法建立中繼存放區 tables。 一般而言,此策略對於生產環境更安全,因為它可防止意外升級中繼存放區資料庫。

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