azure databricks使用external hive metastore跨工作區共享元數據

image-20230330123458853

爲什麼要使用external hive metastore

  1. 可以跨workspace的共享元數據,不用每次創建workspace的時候都重複的把元數據重建一次。

  2. 更好的元數據集中管理,Create once, use everywhere。

  3. 爲災難恢復(DR)做好爲準備,並降低複雜性。(PAAS一樣會存在意外的,不要以爲不會,所以DR是必須的)

  4. 可以更好控制元數據存儲DB的一些配置,比如常見的字符集問題導致視圖不能使用非ascii碼而無法查詢出數據

    image-20230330113713032

    image-20230330113747426

    image-20230330113652807

  5. 元數據存儲在自己的數據庫中,可以和其它的產品(數據治理或者資產軟件)做整合。

實現環境

azure china

創建azure SQL

步驟1:創建數據庫服務器

image-20230330114920046

image-20230330114942835

底部輸入服務器管理員賬號名和密碼

image-20230330115240732

image-20230330115346953

後面的配置默認或者按需自己設置即可,最後點擊創建

步驟2:配置網絡和private endpoint

image-20230330120126120

後面把所有databricks的子網都加進去來

image-20230330120207132

步驟3:創建數據庫用於存儲hive metadata

image-20230330121831787

image-20230330214319263

配置數據庫:我這是測試,創建一個簡單的即可

image-20230330122015966

排序規則要注意:如果你有中文comment、視圖中有中文,這裏不要用默認的,建議選擇Chinese_PRC_CI_AS,可以防止中文亂碼,比如開頭說的視圖亂碼問題導致無法查詢出數據的問題。

image-20230330231628222

其它默認配置,點擊創建即可。

image-20230330214559650

注意:如果使用severless並且設置了自動啓停,不建議開啓replicas服務,因爲可能導致會一直有鏈接,從而導致自動啓停無法生效的,就會一直計費

創建hive metadata元數據

步驟1:下載hive建表語句腳本。

此處下載用於創建 Hive 元數據的 DDL 腳本。由於我使用的databricks runtime是11.3,因此我選擇了2.3.9版本。

具體的差異可以參閱下微軟官網:外部 Apache Hive 元存儲 - Azure Databricks | Microsoft Learn

image-20230330123959664

步驟2:執行建表語句

找到建表語句,copy內容,到db中執行即可。

image-20230330124302443

image-20230330124644361

步驟3:創建hive db獨立的讀寫賬號

用管理員賬號登錄到server上,選擇master數據庫,執行如下SQL

 -- master db執行,創建Login
CREATE LOGIN hivedbadmin WITH password='xxx';
CREATE USER hivedbadmin FOR LOGIN hivedbadmin WITH DEFAULT_SCHEMA=[dbo]

image-20230330214734559

在hive metadata db上創建用戶和授權

 -- hiveextmetadatadb 上執行,創建user並授權db_owner角色
CREATE USER hivedbadmin FROM LOGIN hivedbadmin;

EXEC sp_addrolemember 'db_owner', 'hivedbadmin';

image-20230330214821693

驗證登錄

如果服務器禁止了公網訪問,則需要添加白名單IP到database的fire rule裏面,否則會一直報錯說登錄失敗

 -- master DB執行
EXEC [sys].[sp_set_database_firewall_rule] N'Allow Azure', '120.235.19.25', '120.235.19.25';

-- 注意:sp_set_firewall_rule是服務器級別的,服務器級別和database級別是獨立的

image-20230330145350604

image-20230330215044153

image-20230330215100955

databricks集羣配置

我們需要分別創建兩個workspace。

image-20230330145605355

我們測試兩個hive version的,一個是2.3.7,這個配套Databricks Runtime7.0-9.X使用。一個是2.3.9.這個配套Databricks Runtime 10.0 及更高版本

兩個workspace都配置訪問同一個key vault,用於訪問sql的賬號密碼,key vault自行配置

image-20230330151251684

image-20230330151423733

Hive 2.3.7 (Databricks Runtime 7.0 - 9.x)

注意:

  • databricks 運行時版本 9.1,因此按照微軟官網的建議,將 hive 版本設置爲 2.3.7:spark.sql.hive.metastore.version 2.3.7

  • spark.sql.hive.metastore.jars builtin,對於2.3.7我測試是不行的,要先設置成maven,執行任意sql命令,讓他下載jar包,然後把jar包放到dbfs固定地方,然後用init script把jar包cp到本地,然後把builtin換成這個jar的路徑,具體可以參考我歷史的文章:【原創】Databricks 更改hive metastore version - John.Xiong - 博客園 (cnblogs.com)

  • 對於密碼,可以使用機密。我們需要提供如下配置值:spark.hadoop.javax.jdo.option.ConnectionPassword {{secrets/xxxscope/xxxsecretname}}

    • 以明文形式提供了密碼,不建議這樣做。

  • hive metadata db不要有-(橫線),我測試會報錯,建議最好就是一連串的字母。

在第1個workspace創建cluster:wk1-cluster9.1-2.3.7,選擇9.1 LTS runtime,在spark config中設置如下:

spark.hadoop.javax.jdo.option.ConnectionDriverName com.microsoft.sqlserver.jdbc.SQLServerDriver
spark.hadoop.javax.jdo.option.ConnectionURL jdbc:sqlserver://aaslab-sql.database.chinacloudapi.cn:1433;database=hiveextmetadatadb;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.chinacloudapi.cn;loginTimeout=30;
spark.hadoop.javax.jdo.option.ConnectionUserName {{secrets/aaslab-kv1/hive-metastore-db-user}}
spark.hadoop.javax.jdo.option.ConnectionPassword {{secrets/aaslab-kv1/hive-metastore-db-userpwd}}
spark.sql.hive.metastore.jars /databricks/hive_metastore_jars/*
spark.sql.hive.metastore.version 2.3.7

image-20230330220038737

/databricks/hive_metastore_jars/*,是因爲我提前jar包下載下來了,具體參考注意中說的文章。

在init scripts中要配置下那個cp jar的腳本

image-20230330223805823

 %python
 dbutils.fs.put("/databricks/scripts/hive-metastore-init","""
 #!/bin/bash
 sleep 10s
 mkdir -p /databricks/hive_metastore_jars && cp -r /dbfs/lib/hive_metastore_jars/* /databricks/hive_metastore_jars
 """, True)

創建mount

%python
storageAccountName = "storage account"
fileSystemName = "blob container"
appID = "xxx"
tenantID = "xxx"


configs = {"fs.azure.account.auth.type": "OAuth",
          "fs.azure.account.oauth.provider.type": "org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider",
          "fs.azure.account.oauth2.client.id": appID,
          "fs.azure.account.oauth2.client.secret": dbutils.secrets.get(scope="aaslab-kv1",key="aas-lab-sp-secret"),
          "fs.azure.account.oauth2.client.endpoint": "https://login.partner.microsoftonline.cn/{0}/oauth2/token".format(tenantID)}

dbutils.fs.mount(
  source = "abfss://{0}@{1}.dfs.core.chinacloudapi.cn/".format(fileSystemName, storageAccountName),
  mount_point = "/mnt/aaslabdw",
  extra_configs = configs)

創建db和table

%python
spark.sql("create database if not exists mytestDB")
#read the sample data into dataframe
df_flight_data = spark.read.csv("/databricks-datasets/flights/departuredelays.csv", header=True)
#create the delta table to the mount point that we have created earlier
dbutils.fs.rm("/mnt/aaslabdw/mytestDB/flight_data", recurse=True)
df_flight_data.write.format("delta").mode("overwrite").save("/mnt/aaslabdw/mytestDB/flight_data")
spark.sql("drop table if exists mytestDB.flight_data")
spark.sql("create table if not exists mytestDB.flight_data using delta location '/mnt/aaslabdw/mytestDB/flight_data'")

查詢數據

image-20230330234222766

image-20230330234559702

view也不會亂碼

image-20230330234305318

在第2個workspace創建cluster:wk2-cluster9.1-2.3.7,選擇9.1 LTS runtime,在spark config中設置如下,當然也是要按照注意那裏引用的文章中的一樣先下載下來jar,再配置纔可以的。(當然也可以直接把workspace1的那些jar通過dbfs cli下載下來,直接傳到2的dbfs上也可以的,更快)

啓用後可以直接看到db、table等元數據了,但是瀏覽table時候會報錯,報路徑不存在。

image-20230331001029412

執行一樣的mount命令,mount一樣的路徑到workspace2即可。

正確在space2讀取到數據

image-20230331001636261

最後把spark config和init scripts等保持了space1中cluster1一樣即可。

Hive 2.3.9(Databricks Runtime 10.0 及更高版本)

類似的操作,只是把spark.sql.hive.metastore.version設置爲2.3.9,也是先maven下載,再配置固定的jars路徑。

注意:如果同一個workspace下有多個cluster是不同版本的hive version,jars存儲的路徑要分開下。

例如workspace2裏面創建了一個2.3.9的hive版本的cluster,我還是要訪問同樣的元數據,我需要下載2.3.9的jar到一個新的dbfs目錄,防止衝突,然後init script也是從新的jars目錄copy到cluster VM的目錄上

%python
dbutils.fs.put("/databricks/scripts/hive-metastore-init-239","""
#!/bin/bash
sleep 10s
mkdir -p /databricks/hive_metastore_jars_239 && cp -r /dbfs/lib/hive_metastore_jars_239/* /databricks/hive_metastore_jars_239
""", True)

image-20230331013404575

image-20230331013501045

遇到的錯誤

1、org.apache.spark.sql.AnalysisException: org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient

ans:對應的jar包版本應該不對,需要maven下載後按照上面的來配置。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章