目錄
先決條件
在Azure Databricks環境中設置Unity Catalog元存儲
步驟1:爲元存儲創建blob存儲
步驟2:創建Azure Databricks訪問連接器
步驟3:在Azure Databricks帳戶控制檯中創建元存儲
步驟4a:創建catalog和託管表
步驟4b:創建一個外部表
Unity Catalog中的訪問控制
Unity Catalog中的數據血緣
使用“動態”視圖進行行級安全性和列級篩選
先決條件
以下是我們需要考慮在Azure Databricks中使用Unity Catalog的一些先決條件。
Azure Databricks帳戶應在高級計劃中。
第一個Azure Databricks帳戶管理員在首次登錄Azure Databrick帳戶控制檯時必須是Azure Active Directory全局管理員(https://accounts.azuredatabricks.net/login/ ). 首次登錄後,AAD管理員將成爲Azure Databricks全局管理員。AAD管理員可以將Azure Databricks全局管理員權限分配給其他用戶,這些用戶可以在沒有AAD全局管理員參與的情況下進一步執行全局管理員角色。
如果我們有跨多個地區(美國東部/西部)的多個Azure Databricks工作區,則需要爲每個地區提供單獨的元存儲。我們不能在多個地區共享元存儲。例如,如果我們有兩個Azure Databricks工作區,一個在EastUS,另一個在WestUS,我們需要爲每個區域創建兩個元存儲。
在Azure Databricks環境中設置Unity Catalog元存儲
步驟1:爲元存儲創建blob存儲
正常創建一個azure storage blob,但是有一點要注意:層次結構命名空間,必須啓用。
創建一個container,並記錄下其dfs的訪問地址abfss://<container-name>@<storage-account-name>.dfs.core.windows.net/<metastore-name>,例如:abfss://[email protected]/unitycatalogdemo01
步驟2:創建Azure Databricks訪問連接器
從Azure門戶,讓我們創建一個資源Azure Databricks訪問連接器。部署後連接器資源URI將是Azure Databricks的託管標識。從Azure Databricks到其他資源的身份驗證將使用此託管身份進行。記錄下資源ID
在我們在前面部分中創建的元存儲blob,將訪問連接器授予“存儲 Blob 數據參與者”訪問權限。
步驟3:在Azure Databricks帳戶控制檯中創建元存儲
需要注意的是,AAD Global管理員必須首次登錄帳戶控制檯。一旦AAD Global管理員登錄,他們將添加任何用戶或組作爲帳戶管理員,這樣以後帳戶控制檯就可以由添加的用戶進行管理。添加的用戶將成爲Azure Databricks帳戶管理員。
創建高級Azure Databricks工作區。
登錄帳戶控制檯(https://accounts.azuredatabricks.net/)使用任何AAD全局管理帳戶。
轉到用戶管理並添加一個不同的帳戶作爲帳戶管理員。(可選)
創建metastore。謹記一個區域一個metastore。
將元存儲與Azure Databricks工作區連接起來。工作區和mestore在同一個區域的才能關聯起來。如果同一區域中有多個工作區,我們可以將所有工作區都附加到單個元存儲中。通過共享元存儲,我們可以在工作空間中共享對象。
登錄到Azure Databricks工作區時,我們將能夠看到一個默認的catalog “main”,該catalog是在我們將Unity catalog元存儲與Azure Databrick工作區連接時創建的。
步驟4a:創建catalog和託管表
%sql create catalog if not exists myfirstcatalog; create database if not exists myfirstcatalog.mytestDB;
%python #read the sample data into dataframe df_flight_data = spark.read.csv("/databricks-datasets/flights/departuredelays.csv", header=True) df_flight_data.createOrReplaceTempView("temp_tbl")
%sql create table if not exists myfirstcatalog.mytestDB.myFirstManagedTable AS Select * from temp_tbl
步驟4b:創建一個外部表
在一些外部位置(如Azure Blob Storage或ADLS g2帳戶)中以hive或delta格式存在數據。我們想將該表附加到我們的Unity目錄元存儲中。 需要注意的是,Unity Catalog元存儲可能無法直接訪問外部位置。要建立這種訪問,我們需要通過提供實際路徑來創建存儲憑據和外部位置。Unity Catalog將使用訪問連接器管理的身份(access connector for Azure Databricks)來訪問外部位置。我們需要提供對外部存儲位置的訪問連接器授予“存儲 Blob 數據參與者”訪問權限
創建存儲憑據
我們正在使用訪問連接器(託管標識)來創建存儲憑據。我們還可以提供服務主體的方式(不太推薦)。
可將 Unity Catalog 配置爲使用 Azure 託管標識以 Unity Catalog 用戶身份訪問存儲容器。 託管標識爲應用程序提供一個標識,可以在連接到支持 Azure Active Directory (Azure AD) 身份驗證的資源時使用。
可使用 Unity Catalog 中的託管標識來支持兩個主要用例:
作爲連接到元存儲的根存儲帳戶(存儲託管表的位置)的標識。
作爲連接到其他外部存儲帳戶的標識(用於基於文件的訪問或外部表)。
與使用服務主體配置 Unity Catalog 相比,使用託管標識配置 Unity Catalog 具有以下優勢:
你可連接到受存儲防火牆保護的 Azure Data Lake Storage Gen2 帳戶。
託管標識不需要維護憑據或輪換機密。
創建外部位置
在創建外部表之前,我們需要將物理數據位置與之前創建的存儲憑據進行映射。
測試創建外部表
%python #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("abfss://[email protected]/mytestDB/MyFirstExternalTable", recurse=True) df_flight_data.write.format("delta").mode("overwrite").save("abfss://[email protected]/mytestDB/MyFirstExternalTable")%sql create table if not exists myfirstcatalog.mytestDB.MyFirstExternalTable USING DELTA LOCATION 'abfss://[email protected]/mytestDB/MyFirstExternalTable'
Unity Catalog中的訪問控制
以下是Unity Catalog中的安全對象。訪問級別是從父級對象繼承到子級對象的。例如,如果我們提供對目錄的讀取訪問,它將被繼承到層次結構中的最後一個子級(即架構/託管表/視圖…等)。我們可以通過使用SQL命令、Unity catalog CLI或在Data Explorer中管理元存儲對象的權限。 重要提示:在Unity Catalog Metastore中提供的權限不會被繼承。權限可以由metastore管理員授予。
example:授予一個測試用戶訪問特定的表,使用databricks SQL方式操作。
步驟1:讓我們創建一個Azure Databricks組,該組將包含所有對該表具有隻讀權限的用戶(myfirstcatalog.mytestDB.MyFirstExternalTable)。爲此,我們需要導航到Databricks帳戶控制檯組部分。然後我們需要將用戶添加到組中。
授予cluster權限
步驟2:在Azure Databricks中運行GRANT命令。這應該由元存儲管理員運行。
%sql grant USE_CATALOG on catalog myfirstcatalog to group_data_reader; grant USE_SCHEMA on schema myfirstcatalog.mytestDB to group_data_reader; grant select on table myfirstcatalog.mytestDB.MyFirstExternalTable to group_data_reader;
運行後,使用group_data_reader組中的賬戶登錄databricks,就可以看到表了。
Unity Catalog中的數據血緣
可以捕獲在Azure Databricks集羣上執行的任何語言的查詢之間的運行時數據血緣。血緣是從表級別和列級別捕獲的。血緣數據包括與查詢相關的筆記本、工作流和儀表板。 血緣圖與上一節中討論的Unity Catalog共享相同的權限模型。用戶無權訪問的表不會顯示在血緣圖中。
example:創建notebook,執行如下代碼,創建table和引用數據之間的關係表
%sql create catalog lineage_data; CREATE SCHEMA lineage_data.lineagedemo;
%sql CREATE TABLE IF NOT EXISTS lineage_data.lineagedemo.menu ( recipe_id INT, app string, main string, dessert string ); INSERT INTO lineage_data.lineagedemo.menu (recipe_id, app, main, dessert) VALUES (1,"Ceviche", "Tacos", "Flan"), (2,"Tomato Soup", "Souffle", "Creme Brulee"), (3,"Chips","Grilled Cheese","Cheesecake"); CREATE TABLE lineage_data.lineagedemo.dinner AS SELECT recipe_id, concat(app," + ", main," + ",dessert) AS full_menu FROM lineage_data.lineagedemo.menu
%python from pyspark.sql.functions import rand, round df = spark.range(3).withColumn("price", round(10*rand(seed=42),2)).withColumnRenamed("id","recipe_id") df.write.mode("overwrite").saveAsTable("lineage_data.lineagedemo.price") dinner = spark.read.table("lineage_data.lineagedemo.dinner") price = spark.read.table("lineage_data.lineagedemo.price") dinner_price = dinner.join(price, on="recipe_id") dinner_price.write.mode("overwrite").saveAsTable("lineage_data.lineagedemo.dinner_price")
點擊see linage graph,可以顯示table之間的關係以及字段之間的引用關係
%sql -- 複雜的col引用:一個col來自多個col的數據 create table lineage_data.lineagedemo.tbl_col_refNCol as select recipe_id, app, main, dessert, case when recipe_id = 1 then app when recipe_id = 2 then main else dessert end as col3 from lineage_data.lineagedemo.menu
%sql -- 複雜的col引用:一個col來自多個table col的數據 create table lineage_data.lineagedemo.tbl_col_refNCol_byjoin as select a1.recipe_id, a1.full_menu, case when a1.full_menu like '%Sou%' then a2.price else 0.0 end as price from lineage_data.lineagedemo.dinner as a1 left join lineage_data.lineagedemo.price as a2 on ( a1.recipe_id = a2.recipe_id )
%sql -- 複雜的col引用:一個col來自多個table col的數據,並使用聚合函數 create table lineage_data.lineagedemo.tbl_col_refNCol_byjoin_agg as select a1.recipe_id, a1.full_menu, sum(case when a1.full_menu like '%Sou%' then a2.price else 0.0 end) as sum_price from lineage_data.lineagedemo.dinner as a1 left join lineage_data.lineagedemo.price as a2 on ( a1.recipe_id = a2.recipe_id ) group by a1.recipe_id, a1.full_menu
測試無權訪問的表將會被mask起來
%sql grant USE_CATALOG on catalog lineage_data to group_data_reader; grant USE_SCHEMA on schema lineage_data.lineagedemo to group_data_reader; grant select on table lineage_data.lineagedemo.tbl_col_refncol_byjoin_agg to group_data_reader;
使用“動態”視圖進行行級安全性和列級篩選
在Unity Catalog中,我們可以使用動態視圖來配置行和列中的細粒度訪問控制。此外,我們可以根據權限屏蔽數據。 如果當前用戶是特定帳戶級別組的成員,則新的內置函數is_account_group_member(account group)將返回TRUE。建議在針對Unity目錄數據的動態視圖中使用。
Unity Catalog 引入了以下功能,這些功能允許你動態限制哪些用戶可以訪問視圖中的行、列:
current_user():返回當前用戶的電子郵件地址。 is_account_group_member():如果當前用戶是特定帳戶級別組的成員,則返回 TRUE。 建議在針對 Unity Catalog 數據的動態視圖中使用。 is_member():如果當前用戶是特定工作區級別組的成員,則返回 TRUE。 提供此函數是爲了與現有 Hive 元存儲兼容。 請避免將它與針對 Unity Catalog 數據的視圖一起使用,因爲它不評估帳戶級別的組成員身份。
列級別權限
example:普通用戶看到部分關鍵列是打碼的,管理員是可以看到正常數據的。
%sql create view if not exists myfirstcatalog.mytestDB.vw_col_mask_demo1 as select date, case when is_account_group_member("group_data_admin") then delay else '***' end as delay, distance, origin, destination from myfirstcatalog.mytestDB.MyFirstExternalTable; # 授權 grant select on table myfirstcatalog.mytestDB.vw_col_mask_demo1 to group_data_reader;
行級別權限
現在我們將擴展前面的例子。我們有幾個特定於的組,例如,ABE_admin只能看到origin=‘ABE’的數據,類似地,ATL_admin組應該只能看到origin=‘TL’的數據。如果任何用戶不屬於任何組,他們將無法查看數據。group_data_admin組的用戶將能夠看到所有數據。
%sql create view if not exists myfirstcatalog.mytestDB.vw_row_level_demo1 as select date, case when is_account_group_member("group_data_admin") then delay else '***' end as delay, distance, origin, destination from myfirstcatalog.mytestDB.MyFirstExternalTable where case when is_account_group_member("group_data_admin") then true when is_account_group_member("ABE_group") then origin = 'ABE' when is_account_group_member("ATL_group") then origin = 'ATL' else false end
創建ABE_group組,添加一個普通用戶進去,並添加到workspace中。
%sql grant select on table myfirstcatalog.mytestDB.vw_row_level_demo1 to ABE_group;