Unity Catalog 提供了強大的資料發現和治理功能,讓使用者能有效管理和追蹤資料。透過標籤,使用者可以輕鬆搜尋和分類別資料集,而資料血緣功能則可以追蹤資料的來源和轉換過程,方便理解資料的演變歷史。此外,Unity Catalog 的動態檢視功能允許管理員根據使用者的群組成員身份動態控制資料存取許可權,實作更精細的資料治理和安全控制。文章也說明瞭如何在 Unity Catalog 中建立和管理資料目錄以及外部儲存位置,讓使用者能更彈性地管理資料儲存。
資料發現與目錄管理
在Databricks的Unity Catalog中,除了可以對資料集進行註冊和管理外,還可以透過SQL語法來新增、修改或刪除標籤(tags)。以下是一個範例,展示如何在Databricks中建立一個新的筆記本(notebook),並在筆記本的第一個儲存格(cell)中新增SQL陳述式來更新資料集的描述標籤:
ALTER TABLE yellow_taxi_raw
SET TAGS ('description'='未處理的計程車行程資料')
內容解密:
這段SQL陳述式的作用是修改名為yellow_taxi_raw的資料表的描述標籤,將其描述設定為「未處理的計程車行程資料」。這對於資料的管理和查詢非常有幫助,因為它允許使用者在Unity Catalog中對資料集進行更細粒度的標註。
此外,Unity Catalog還支援在欄位層級上新增標籤,這在需要區分不同欄位的資料敏感度時非常有用。例如,可以動態地為某個檢視(view)套用資料遮罩(data mask)。
使用標籤搜尋資料
使用者可以透過在Catalog Explorer的搜尋文字方塊中使用tag:<大小寫敏感的標籤名稱>的語法來搜尋具有特定標籤的檢視、表格或欄位。
資料血緣追蹤
除了資料發現以外,瞭解資料集是如何形成的以及其上游來源是否可信也是非常重要的。資料血緣(Data Lineage)是實作這一目標的一種機制,它允許使用者追蹤Unity Catalog中資料集的來源以及不同欄位的起源。
湖倉表格可能是多個上游表格的結果
此圖示展示了一個下游表格是如何由多個上游表格經過一系列處理(如資料清理、資料型別轉換、欄位轉換或資料豐富化等)後形成的。
檢視資料血緣
在Databricks Data Intelligence Platform中,可以透過多種方式檢視資料血緣:
- 直接從Catalog Explorer中檢視血緣圖(lineage graph)
- 使用Lineage Tracking REST API檢索
- 查詢Unity Catalog中的Lineage Tracking系統表格
操作範例
首先,從GitHub倉函式庫中克隆本章的範例筆記本,並將名為Data Lineage Demo.sql的筆記本匯入到Databricks工作區。然後,將筆記本附加到一個正在執行的全用途叢集(all-purpose cluster)並執行所有儲存格。這個筆記本會產生兩個表格:一個父表格和一個子表格,子表格的欄位是由上游父表格構建而成的。
執行完筆記本並將表格儲存到Unity Catalog後,可以導航到Catalog Explorer,搜尋子表格並點選「檢視血緣圖」按鈕來生成血緣圖。
表格血緣圖可以直接從Catalog Explorer中檢視
此圖示清晰地展示了父表格和子表格之間的關係,以及子表格中的car_description欄位是如何由父表格中的欄位構建而成的。
系統表格的可觀察性
Unity Catalog還提供了系統表格(System Tables)來實作強大的稽核和系統可觀察性。系統表格是一組唯讀的表格,記錄了Databricks工作區內的操作資料。這些表格跨越了Databricks帳戶內的所有工作區,為檢索操作資料提供了一個統一的來源。
表格:系統表格將記錄跨越Databricks Data Intelligence Platform各個部分的操作資訊
系統表格記錄了關於以下幾個方面的可觀察性資訊:
- 系統計費:捕捉了有關所使用的計算資源(如倉函式庫和叢集)的計費資訊。
- 系統存取:包含了來自工作區服務的事件資料,包括作業、工作流程、叢集、筆記本等。
- 表格血緣:捕捉了有關Unity Catalog中表格的讀寫操作資訊。
- 欄位血緣資訊:捕捉了有關Unity Catalog表格中欄位的讀寫操作資訊。
- 計算資源:捕捉了有關叢集的資訊,例如組態變更。
- SQL倉函式庫事件:捕捉了對SQL倉函式庫所做的變更,例如擴充套件事件。
這些系統表格為管理和監控Databricks工作區提供了強大的支援。
Unity Catalog 中的動態檢視與資料治理
在 Databricks 的 Unity Catalog 中,動態檢視是一種特殊的檢視,能夠根據使用者的群組成員身份動態地控制對資料的存取許可權。這使得資料管理員能夠精細地控制不同使用者對資料集的存取。
動態檢視的功能
動態檢視利用內建的 Spark SQL 函式,例如 is_account_group_member()、current_user() 和 is_member(),來評估使用者的群組成員身份。根據使用者的群組成員身份,動態檢視可以限制特定使用者對資料列和欄位的存取。
重要注意事項
- 對於在 Unity Catalog 中建立的動態檢視,建議使用
is_account_group_member()函式來評估使用者的群組成員身份,因為它是在 Databricks 帳戶層級評估群組成員身份。 is_member()函式則是在特定工作區層級評估群組成員身份,可能會導致錯誤或非預期的結果。
實作範例:對醫療保健資料集進行資料遮罩
以下範例示範如何建立動態檢視,以限制對 COVID-19 資料集的存取。首先,定義必要的變數和目錄:
CATALOG_NAME = "building_modern_dapps"
SCHEMA_NAME = "dynamic_views_demo"
PERSISTENT_TABLE_NAME = "covid_us_counties"
COVID_DATASET_PATH = "/databricks-datasets/COVID/covid-19-data/us-counties.csv"
spark.sql(f"CREATE CATALOG IF NOT EXISTS {CATALOG_NAME}")
spark.sql(f"USE CATALOG {CATALOG_NAME}")
spark.sql(f"CREATE SCHEMA IF NOT EXISTS {SCHEMA_NAME}")
spark.sql(f"USE SCHEMA {SCHEMA_NAME}")
建立持久表
covid_df = (spark.read
.option("header", True)
.option("inferSchema", True)
.csv(COVID_DATASET_PATH))
(covid_df.write
.mode("overwrite")
.saveAsTable(f"{CATALOG_NAME}.{SCHEMA_NAME}.{PERSISTENT_TABLE_NAME}"))
建立動態檢視
首先,建立一個動態檢視,以限制對敏感欄位的存取:
RESTRICTED_VIEW_NAME = "covid_us_counties_restricted_vw"
spark.sql(f"""
CREATE OR REPLACE VIEW {RESTRICTED_VIEW_NAME} AS
SELECT
date,
county,
state,
CASE WHEN is_account_group_member('admins')
THEN fips
ELSE concat('***', substring(fips, length(fips)-1, length(fips)))
END AS fips_id,
cases,
CASE WHEN is_account_group_member('admins')
THEN deaths
ELSE 'UNKNOWN'
END AS mortality_cases
FROM {CATALOG_NAME}.{SCHEMA_NAME}.{PERSISTENT_TABLE_NAME}
""")
進一步限制資料列的存取
COL_AND_ROW_RESTRICTED_VIEW_NAME = "covid_us_counties_final_vw"
spark.sql(f"""
CREATE OR REPLACE VIEW {COL_AND_ROW_RESTRICTED_VIEW_NAME} AS
SELECT
date,
county,
state,
CASE WHEN is_account_group_member('admins')
THEN fips
ELSE concat('***', substring(fips, length(fips)-1, length(fips)))
END AS fips_id,
cases,
CASE WHEN is_account_group_member('admins')
THEN deaths
ELSE 'UNKNOWN'
END AS mortality_cases
FROM {CATALOG_NAME}.{SCHEMA_NAME}.{PERSISTENT_TABLE_NAME}
WHERE
CASE WHEN is_account_group_member('admins')
THEN 1=1
ELSE state IN ('Alabama', 'Colorado', 'California', 'Delaware', 'New York', 'Texas', 'Florida')
END
""")
查詢動態檢視
不同群組的使用者查詢動態檢視時,將獲得不同的結果集。例如:
(spark.table(COL_AND_ROW_RESTRICTED_VIEW_NAME)
.groupBy("state", "county")
.agg({"cases": "count"})
.orderBy("state", "county")
).withColumnRenamed("count(cases)", "total_covid_cases").display()
程式碼詳解:
spark.sql(f"CREATE CATALOG IF NOT EXISTS {CATALOG_NAME}"):- 這個指令用於建立一個新的目錄(Catalog),如果該目錄不存在的話。目錄是 Unity Catalog 中的最高層級結構,用於組織資料和資源。
covid_df = (spark.read.option("header", True).option("inferSchema", True).csv(COVID_DATASET_PATH)):- 這段程式碼從指定的 CSV 檔案路徑讀取資料,並將其載入到一個 DataFrame 中。
option("header", True)表示 CSV 檔案包含標題行,而option("inferSchema", True)則指示 Spark 自動推斷資料欄位的資料型別。
- 這段程式碼從指定的 CSV 檔案路徑讀取資料,並將其載入到一個 DataFrame 中。
動態檢視中的
CASE WHEN is_account_group_member('admins'):- 這裡使用了
is_account_group_member函式來檢查當前使用者是否是 ‘admins’ 群組的成員。根據檢查結果,對敏感資料(如fips和deaths)進行不同的處理。如果使用者是 ‘admins’ 成員,則顯示原始資料;否則,對資料進行遮罩處理。
- 這裡使用了
WHERE CASE WHEN is_account_group_member('admins') THEN 1=1 ELSE state IN (...) END:- 這段查詢條件根據使用者的群組成員身份進一步限制傳回的資料列。如果使用者是 ‘admins’ 成員,則傳回所有資料;否則,只傳回特定州的資料。
.withColumnRenamed("count(cases)", "total_covid_cases"):- 在對資料進行分組和聚合後,這個方法將聚合結果中的列名從 “count(cases)” 更改為 “total_covid_cases”,使結果更具可讀性。
圖表翻譯:
此範例中使用的 Plantuml 圖表可用於展示 Unity Catalog 中不同物件之間的關係,以及動態檢視如何根據使用者的群組成員身份傳回不同的結果集。
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333
title 圖表翻譯:
rectangle "查詢" as node1
rectangle "檢查群組成員身份" as node2
rectangle "是" as node3
rectangle "否" as node4
node1 --> node2
node2 --> node3
node3 --> node4
@enduml圖表翻譯: 此圖表展示了當使用者查詢動態檢視時,系統如何根據使用者的群組成員身份來決定傳回的資料內容。如果使用者是 ‘admins’ 群組的成員,則傳回完整的資料;否則,系統會遮罩敏感資料並限制傳回特定的資料列。
管理 Unity Catalog 中的資料位置
在本章中,我們將探討如何使用 Unity Catalog 中的可安全防護物件(securable objects)來有效管理資料儲存位置。這些物件允許管理員為使用者、群組和服務主體授予精細的許可權。我們將介紹六種用於在 Unity Catalog 中儲存資料的可安全防護物件:目錄(catalogs)、架構(schemas)、表格(tables)、卷宗(volumes)、外部位置(external locations)和連線(connections)。我們還將探討如何跨組織內的不同角色和部門有效地管理儲存存取許可權,以確保 Databricks Data Intelligence Platform 中的資料安全性和可稽核性。最後,我們將概述如何在 Unity Catalog 中組織和結構化不同儲存位置中的資料。
在本章中,我們將涵蓋以下主要主題:
- 在 Unity Catalog 中建立和管理資料目錄
- 為 Unity Catalog 中的資料設定預設儲存位置
- 在 Unity Catalog 中建立和管理外部儲存位置
- 實作實驗室 – 為生成式 AI 管道提取檔案文字
技術需求
在 Unity Catalog 中建立和管理資料目錄
目錄是 Unity Catalog 物件模型層次結構中用於儲存資料資產的最高層級容器。一個目錄將包含一個或多個架構(或資料函式庫),而這些架構又可以包含一個或多個表格、檢視、模型、函式或卷宗。
圖 6.1 – 資料在 Unity Catalog 中使用目錄進行隔離
一個常見的問題是“我的工作區應該有多少個目錄?”雖然對於應該為工作區建立的確切目錄數量沒有對或錯的答案,但一個好的經驗法則是根據業務線、邏輯工作環境、團隊或使用案例等自然劃分因素來劃分工作區目錄。此外,您應該考慮具有許可權使用資料資產的使用者和群組的子集,作為決定如何建立目錄隔離的因素。
重點提示
最好不要有太少的目錄,以至於無法在邏輯上區分不同的資料集。同樣,最好也不要在工作區中有太多的目錄,因為這會讓使用者難以導航和發現資料集。您應該旨在找到兩者之間的中間點。
在 Unity Catalog 中建立和管理資料目錄
Metastore 管理員或 Unity Catalog 中的特權使用者可以授予其他使用者在 metastore 中建立額外目錄的權利。例如,以下由 metastore 管理員執行的授權陳述式將授予 Databricks 使用者 jane.smith@example.com 在附加到其 Databricks 工作區的 metastore 中建立新目錄的許可權:
GRANT CREATE CATALOG ON METASTORE TO `jane.smith@example.com`;
此外,對於在 2023 年 11 月 8 日之後建立的 Databricks 工作區,將在 Unity Catalog metastore 中建立一個預設的工作區目錄 <workspace_name>_catalog。預設情況下,工作區中的所有使用者都將具有對此目錄的存取許可權,並且可以建立資料資產。
受控資料與外部資料
當您佈署 Unity Catalog metastore 時,佈署過程的一部分包括在 metastore 層級設定新的預設雲端儲存容器。此雲端儲存容器作為在 Databricks Data Intelligence Platform 上建立的所有資料資產的預設位置。例如,當使用者建立新表格且未在資料定義語言(DDL)陳述式中指定 LOCATION 屬性時,Databricks Data Intelligence Platform 將把表格資料儲存在預設儲存容器中。因此,平台將負責管理此表格的生命週期,包括資料檔案、中繼資料,甚至表格的特性,例如調整表格佈局和檔案大小。這種型別的資料資產被稱為受控表格(managed table),因為 Databricks Data Intelligence Platform 將管理其生命週期。此外,如果表格被刪除,平台將負責移除所有表格中繼資料和資料檔案。
程式碼範例:建立受控表格
CREATE TABLE managed_table (
id INT,
name STRING
);
內容解密:
上述 SQL 陳述式用於建立一個名為 managed_table 的受控表格。此表格包含兩個欄位:id 和 name。由於未指定 LOCATION 屬性,Databricks 將自動在預設儲存容器中儲存此表格的資料。
然而,如果使用者在 DDL 陳述式中提供了 LOCATION 屬性,則會覆寫預設行為。相反,使用者明確指示 Databricks Data Intelligence Platform 將資料儲存在 Unity Catalog 預設儲存容器外部的位置。因此,這種型別的資料資產被稱為外部表格(external table)。Databricks 不會管理表格的效能特性,例如檔案大小或檔案佈局。與受控表格不同,如果外部表格被刪除,只有表格條目會從 Unity Catalog 中移除,而不會移除任何表格中繼資料和資料檔案。相反,表格擁有者需要負責從雲端位置刪除表格檔案,因為他們已經接管了表格生命週期的管理。
程式碼範例:建立外部表格
CREATE TABLE external_table (
id INT,
name STRING
) LOCATION 's3://external-bucket/external-table';
內容解密:
上述 SQL 陳述式用於建立一個名為 external_table 的外部表格。此表格同樣包含兩個欄位:id 和 name。由於指定了 LOCATION 屬性,Databricks 將把此表格的資料儲存在指定的外部位置 s3://external-bucket/external-table 中。因此,使用者需要自行管理此表格的生命週期,包括刪除操作。
一般來說,受控(managed)指的是 Databricks 平台管理生命週期,且資料將儲存在預設儲存容器中;而外部(external)則意味著物件擁有者控制物件生命週期,且資料應儲存在外部儲存位置。