在本章中,我们将深入探讨如何使用Unity Catalog实现湖仓中的有效数据治理。我们将介绍如何在现有的Databricks工作区启用Unity Catalog,实现数据目录管理以便进行数据发现,如何在表、行和列级别实施细粒度的数据访问控制,并追踪数据血缘。通过本章的学习,您将掌握行业最佳实践,获得提升数据安全性和合规性的实际经验。
在本章中,我们将涵盖以下主要主题:
- 理解湖仓中的数据治理
- 在现有的Databricks工作区启用Unity Catalog
- Unity Catalog中的身份联合
- 数据发现与目录管理
- 实践实验 – 数据掩码处理医疗数据集
技术要求
为了跟随本章内容,您需要具有Databricks工作区权限,以创建并启动一个全能集群,从而能够执行本章的附带笔记本。建议将您的Databricks用户提升为账户管理员和元存储管理员,这样您就可以部署一个新的Unity Catalog元存储并将其附加到现有的Databricks工作区。所有代码示例可以从本章的GitHub仓库下载,地址为 github.com/PacktPublis… 。本章将创建并运行若干新笔记本,预计将消耗约5–10个Databricks单位(DBU)。
理解湖仓中的数据治理
湖仓实现通常会利用多个处理引擎来处理不同的用例。然而,每个处理引擎都有自己的数据安全实现,而这些不同的数据安全解决方案往往不能互相集成。大多数湖仓的不足之处在于,由于这些多个安全层的存在,实现一致的、全球性的数据安全策略几乎是不可能的。在构建数据湖仓时,确保湖仓中的数据完全且一致地安全和私密,并且只有正确的用户组才能访问,这一点至关重要。因此,拥有一个简单的数据治理解决方案,涵盖组织湖仓中的所有数据,对组织的成功至关重要。
介绍Databricks Unity Catalog
Unity Catalog是一个集中的数据治理解决方案,它通过将工作区对象的访问策略组织到一个单一的管理“玻璃面板”中,从而简化了湖仓中数据的安全管理。除了访问策略之外,Unity Catalog还特别设计了强大的审计功能,允许管理员捕捉所有用户对工作区对象的访问模式,使得管理员能够观察访问模式、工作区使用情况和计费模式,跨所有Databricks工作区进行分析。此外,Unity Catalog还被设计为让数据专业人员能够在组织内发现数据集,跟踪数据血缘,查看实体关系图,分享策划过的数据集,并监控系统健康状况。Unity Catalog的一个主要优势是,一旦组织的数据进入Unity Catalog,它默认就是安全的——无论是Databricks工作区内部的处理过程,还是与外部的Databricks数据智能平台互动的外部过程,除非数据管理员明确授权,否则都无法访问数据。Unity Catalog的设计跨越了湖仓的边界,从工作区到工作区,并延伸到Databricks工作区之外,位于组织的数据之上,使得一个统一的治理模型可以简单且一致地应用于访问组织湖仓数据的所有方。
然而,拥有一个全球数据和工作区对象安全层并不像今天在Unity Catalog中那样无缝。在这里,我们回顾一下Databricks之前的安全模型中所学到的教训,以及Unity Catalog是如何最终诞生的。
一个值得解决的问题
以前,数据访问控制策略是通过一种名为表访问控制列表(ACL)的机制在每个工作区中定义的。当这些策略得到正确执行时,表ACL提供了一种强大的数据治理解决方案。管理员可以为工作区内的不同用户和组定义数据访问策略,而这些访问策略可以通过Databricks集群在执行访问注册在Hive元存储(HMS)中的底层数据集的Spark代码时得到执行。
然而,表ACL安全模型很快暴露出四个主要问题。第一个问题是,使用表ACL安全模型定义的数据访问策略需要在每个唯一的Databricks工作区中重复定义。大多数组织倾向于为每个逻辑工作环境设置独立的工作区——例如,一个工作区用于开发,另一个工作区用于验收测试,最后一个工作区专门用于运行生产工作负载。除了需要重复定义相同的共享数据访问策略外,如果某个工作区中的数据访问策略发生变化,通常意味着所有工作区中的数据访问策略也需要同步变化。这导致了不必要的维护开销,因为没有一个单一的地方可以轻松定义这些数据访问模式。
第二个问题是,表ACL仅在执行交互式笔记本或自动化作业时,在启用了表ACL的集群上对底层数据进行强制执行。如果没有启用表ACL安全模型的集群,则可以直接访问底层数据集,完全绕过安全模型!虽然可以通过集群策略(第1章中介绍)来缓解这一问题,防止潜在的恶意访问特权数据集,但编写集群策略比较复杂。它们需要了解集群策略模式,并且需要有使用JSON表达配置的经验,这使得在组织中进行扩展变得困难。经常会有用户向组织领导抱怨,表示需要管理员工作区访问权限来启动自己喜欢的集群并完成日常活动。一旦用户获得了管理员工作区访问权限,他们也可以授予其他用户管理员访问权限,形成像雪球效应一样的恶性循环,导致工作区中管理员人数过多。这种不当做法很容易通过使用没有启用表ACL的集群绕过表ACL安全模型,从而导致数据泄露。
此外,由于在共享计算资源上运行Java虚拟机(JVM)语言时的隔离问题,启用表ACL的集群限制了最终用户只能使用SQL或Python编程语言运行工作负载。希望使用Scala、Java或R编程语言执行工作负载的用户,需要被授予使用非表ACL启用集群的例外权限,这为组织的数据治理解决方案打开了巨大的漏洞。
第四个主要问题与HMS的扩展能力有关。Databricks数据智能平台利用HMS在工作区内注册数据集,这使得用户可以从头创建新的数据集,将它们组织到模式中,甚至在整个组织中共享访问权限。然而,随着工作区引入成千上万的用户,这些用户需要同时执行临时查询,同时执行成百上千的定时作业。最终,HMS在面对最具挑战性的工作区时,难以跟上所需的并发水平。
显然,需要进行一次巨大的变革,因此Databricks开始着手从头开始重新设计数据治理解决方案。
Unity Catalog架构概述
Unity Catalog旨在解决的一个主要痛点是实现一个完整的端到端数据治理解决方案,跨越组织的所有工作区,消除在每个Databricks工作区中重新定义数据访问策略的冗余。相反,通过Unity Catalog,数据管理员可以在一个集中位置一次性定义数据访问控制,并确保无论使用何种计算资源或处理引擎与Unity Catalog中的数据集交互,数据访问策略都能始终如一地应用于整个组织。
除了集中式数据治理,Unity Catalog还具有其他几个关键的动因,使其成为现代湖仓数据治理的理想解决方案:
默认安全:用户在没有使用启用Unity Catalog的集群(Unity Catalog集群将在下节中介绍)并且没有获得特定数据集访问权限的情况下,无法从任何形式的计算中读取数据。
友好的管理员界面:Unity Catalog中的数据访问策略与美国国家标准协会(ANSI)SQL紧密集成,允许管理员在熟悉的数据库对象(如目录、数据库、表、函数和视图)上表达数据访问权限。数据访问权限还可以通过Databricks Web应用中的管理员UI或自动化部署工具(如Terraform)进行设置。
数据发现:Unity Catalog使数据管理员能够为数据集打上描述性元数据标签,从而使组织内的用户能够搜索并发现可用的数据集。
强大的审计功能:Unity Catalog自动捕获用户级别的访问模式和数据操作,允许管理员查看和审计用户与湖仓数据交互时的行为。
数据血缘追踪:追踪表和列如何从上游源生成对于确保下游数据集使用受信任的数据源至关重要。Unity Catalog通过其强大的数据血缘API和系统表格使得数据和工作区资产的追踪变得简单。
可观测性:由于Unity Catalog跨多个Databricks工作区,它可以将系统指标和审计事件聚合成一组集中式的只读表格,用于监控和系统可观测性,这些表格被称为系统表(在“使用系统表进行可观测性”部分中有更详细的介绍)。
为了实现一个安全模型,确保数据默认安全,并且没有能力在不通过Unity Catalog的情况下访问数据,Databricks需要根据用户的角色设计不同的集群类型。让我们来看一下Unity Catalog启用工作区中可供用户使用的不同集群类型。
Unity Catalog启用的集群类型
在启用Unity Catalog的工作区中,有三种主要类型的集群:
- 单用户集群:只有一个用户或服务主体可以在此类型的集群上执行笔记本单元格或工作流。此类集群只能执行包含Scala、Java、R、Python和SQL语言的混合工作负载。可以从此类集群查询注册在Unity Catalog中的数据集。
- 共享集群:多个用户或服务主体可以在此类型的集群上执行笔记本单元格或工作流。此类集群仅限于Python、SQL和Scala工作负载。可以从此类集群查询注册在Unity Catalog中的数据集。
- 独立集群:一个或多个用户可以将笔记本附加到此类集群并执行笔记本单元格。然而,此类型的集群无法查询注册在Unity Catalog中的数据集,如果用户尝试查询Unity Catalog中注册的数据集,将导致运行时异常。此类集群可用于读取注册在传统HMS中的数据集。
现在我们已经概述了您可以用来与Unity Catalog中的数据交互的不同计算资源类型,接下来让我们关注数据和其他资产在Unity Catalog中的组织方式,主要是理解Unity Catalog的对象模型。
Unity Catalog对象模型
理解Unity Catalog中的对象模型非常重要,因为它将帮助用户理解哪些对象可以被Unity Catalog保护和治理。此外,它还将帮助元存储管理员设计数据访问策略。
Unity Catalog引入的一个主要变化是三层命名空间的概念。传统上,在HMS中,用户与数据交互时可以使用模式(或数据库)和表名的组合来引用数据集。然而,Unity Catalog增加了一个第三个逻辑容器,称为目录(catalog),它可以包含一个或多个模式。为了引用Unity Catalog中的完全限定数据集,数据工作者需要提供目录名、模式名和表名。
让我们深入了解Unity Catalog的对象模型,从与组织物理数据集相关的对象开始:
元存储(Metastore) :Unity Catalog的“物理”实现。一个特定的云区域最多只能包含一个元存储。
目录(Catalog) :Unity Catalog中数据集的顶层容器。一个目录可以包含一个或多个模式对象的集合。
模式(Schema) :Unity Catalog中的第二层。一个模式可以包含一个或多个表、视图、函数、模型和卷的集合。
表(Table) :包含定义的模式并组织为行和列的数据集的表示。
视图(View) :一个计算数据集,可以是通过连接表、过滤列或应用复杂业务逻辑的结果。此外,视图是只读的,不能对其进行数据写入或使用数据操控语言(DML)语句更新数据。
模型(Model) :一个使用MLflow注册到跟踪服务器的机器学习模型。
函数(Function) :一个自定义的用户定义函数,通常包含复杂的业务逻辑,通常不能仅使用内置的Spark函数实现。
卷(Volume) :为存储结构化、半结构化或非结构化数据设计的数据存储位置(我们将在下一章《掌握Unity Catalog中的数据位置》中详细介绍卷)。
接下来,让我们关注Unity Catalog中的对象,这些对象用于与Databricks数据智能平台之外的数据进行交互:
连接(Connection) :表示一个只读连接,包含访问外部关系型数据库管理系统(RDBMS)或数据仓库中数据的凭据。
存储凭证(Storage credential) :表示访问云存储位置的身份验证凭证。
外部位置(External location) :表示Databricks管理的根存储位置之外的云存储位置。
最后,让我们看一下Unity Catalog对象模型中用于共享和接收数据集的元素,这些元素使用Delta Sharing协议:
提供者(Provider) :表示数据提供者。这个实体创建一个或多个策划数据集的集合,称为共享(share)。数据提供者可以随时撤销对共享数据集的访问。
共享(Share) :一个逻辑分组,包含一个或多个共享数据集,可以与数据接收者共享。
接收者(Recipient) :表示数据接收者。这个实体接收对数据共享的访问权限,并可以查询他们工作区中的数据集。
现在我们已经概述了Unity Catalog的主要构建块,让我们来看一下如何在现有的Databricks工作区启用Unity Catalog,以便管理员可以开始充分利用强大的数据治理解决方案。
在现有Databricks工作区启用Unity Catalog
从2023年11月初开始,所有在Amazon Web Services (AWS) 或 Azure上创建的新Databricks工作区默认启用Unity Catalog,因此如果您的工作区是在此日期后在这两个云提供商上创建的,则无需额外配置。类似地,在创建新的Databricks工作区时,将为您的工作区配置一个单一的区域Unity Catalog元存储。在该区域元存储内,默认目录的名称与工作区相同,并且仅绑定到该工作区(我们将在下一节介绍目录绑定)。此外,所有新创建工作区的用户都将具有对该工作区目录中名为“default”的模式的读写访问权限。
重要说明 一旦Databricks工作区启用了Unity Catalog,工作区管理员将无法禁用Unity Catalog。然而,数据集始终可以迁移回HMS实现,但工作区将始终启用Unity Catalog元存储。
将现有的Databricks工作区升级为Unity Catalog的第一步是部署新的元存储。元存储是Unity Catalog的“物理”实现。管理员需要为每个云区域部署一个元存储。元存储可以通过多种方式部署,但为了简便起见,我们将通过Databricks UI介绍如何部署新的元存储:
首先,确保您已登录到账户控制台,地址为 accounts.cloud.databricks.com 。
在账户控制台中,点击侧边栏中的“Catalog”菜单项,然后点击“Create metastore”按钮,开始部署新的元存储。
为您的元存储输入一个有意义的名称,选择适当的区域,并可选地选择一个默认存储路径,用于存储托管的数据集。
最后,点击“Create”按钮。几分钟后,您的新元存储将在您选择的云区域中部署。
注意 在Databricks中,像目录绑定、网络配置或用户配置等全局配置被集中管理在一个单一的管理员控制台中,有时简称为“账户控制台”。
现在元存储已经部署,剩下的就是选择您希望将该元存储链接到的Databricks工作区,启用Unity Catalog:
在账户控制台中,再次从侧边栏选择“Catalog”菜单项。
接下来,点击新创建的元存储名称,然后点击“Assign to workspaces”按钮。
最后,点击您希望启用Unity Catalog的工作区,并通过点击“Assign”按钮确认您的选择。
恭喜!您已经为现有的Databricks工作区启用了Unity Catalog,您可以开始享受您的湖仓数据将由完整的数据安全解决方案进行治理的安心保障。同样重要的是,一旦将Unity Catalog元存储附加到Databricks工作区,您现在已经为工作区启用了身份联合。
Unity Catalog中的身份联合
无论您是部署了一个全新的Databricks工作区,还是手动将现有工作区升级为使用Unity Catalog,接下来的自然步骤是设置新用户,以便他们登录到Databricks工作区并利用Unity Catalog的优势。
在之前,Databricks中的用户管理是在每个工作区内进行的。Unity Catalog将用户管理整合为一个集中的治理面板——账户控制台。与在工作区级别管理工作区身份不同(如果相同的用户访问多个Databricks工作区时会显得重复),身份管理在账户级别进行。这允许管理员一次定义用户及其权限,并轻松地在全局范围内管理身份角色和权限。
在Unity Catalog之前,工作区管理员需要从身份提供者(如Okta、Ping或Azure Active Directory(AAD))同步组织身份。通过Unity Catalog,身份通过跨域身份管理系统(SCIM)在账户级别进行一次同步。Unity Catalog然后会处理将身份同步到适当工作区的过程,这一过程称为身份联合。这允许组织继续在其身份提供者中管理身份,同时确保更改自动传播到各个Databricks工作区。
事实上,在Databricks数据智能平台中,“管理员”一词是一个多重含义的术语。让我们来看看在启用Unity Catalog的工作区中,不同的管理员角色及其所拥有的权限级别:
账户所有者:最初创建Databricks账户的个人。默认情况下,此用户将有权访问账户控制台,并将作为账户管理员和工作区管理员添加。
账户管理员:一个高级用户,具有访问账户控制台的权限,并能够进行账户级别的更改,例如部署新的Unity Catalog元存储、进行网络配置更改,或向工作区添加用户、组和服务主体。此用户有权限授予额外的账户管理员和元存储管理员。
元存储管理员:一个具有管理权限的用户,能够进行元存储级别的更改,例如更改目录所有权、授权用户创建或删除新目录,或配置通过Delta Sharing协议共享的新数据集等。此用户没有访问账户控制台的权限。
工作区管理员:一个具有管理权限的用户,能够进行工作区级别的配置更改,包括创建集群策略和实例池、创建新集群和DBSQL仓库,或配置工作区外观设置等。此用户没有访问账户控制台的权限。
要开始为新工作区用户配置权限,您需要登录到账户控制台,地址为 accounts.cloud.databricks.com/login 。然而,只有账户所有者(最初创建Databricks组织的个人)或账户管理员才能访问管理员控制台。
开始为新工作区用户配置的第一步是启用单点登录(SSO)。您可以通过导航到账户控制台的“设置”菜单并提供您组织身份提供者的详细信息来完成此操作。输入配置详细信息后,点击“测试SSO”按钮,验证连接是否成功。
在身份提供者集成验证成功后,下一步是将用户和组分配到适当的Databricks工作区。如果只有一个Databricks工作区,那么这将是一个简单的操作。然而,如果有多个Databricks工作区,您的组织需要决定谁有权访问特定的工作区。您可以通过导航到账户控制台,然后从菜单项中点击“用户管理”选项卡,将用户分配到适当的工作区,既可以按用户级别,也可以按组级别。
接下来,让我们看看如何在您的组织中促进安全的数据探索。
数据发现与目录管理
数据标签是有用的数据目录构造,允许数据管理员将描述性元数据与数据集和其他可安全管理的对象(如目录、卷或机器学习模型)链接到Unity Catalog中。通过将描述性标签附加到数据集和其他可安全管理的对象,您组织中的用户可以搜索和发现可能有助于他们日常活动的数据资产。这有助于促进团队间的协作,通过避免重新创建类似的数据资产来节省时间和资源,从而完成特定活动。Unity Catalog支持在以下数据对象上使用标签:目录、数据库、表、卷、视图和机器学习模型。
让我们来看一个示例,如何为我们现有的出租车旅行数据集应用描述性标签,以便让您组织中的用户更容易搜索、发现并使用我们在Unity Catalog中发布的数据集。标签可以通过多种方式轻松地添加到Unity Catalog中的表格中。最简单的方法是通过Databricks数据智能平台中的“Catalog Explorer”直接在UI中进行。从Catalog Explorer开始,搜索在前一章实践中创建的目录,该目录存储了来自我们的DLT管道的数据,包含在我们的yellow_taxi_raw数据集中。接下来,展开模式并选择yellow_taxi_raw数据集,以查看数据集详情。最后,点击“Add tags”按钮,开始添加标签数据。
标签以键值对的形式添加,其中键作为唯一标识符,例如类别,而值包含您希望分配给可安全管理对象的内容。在这个例子中,我们希望添加一些标签来标记数据集的数据敏感性,以及一个标签来标识数据集的所有者。添加您自己选择的标签,然后点击“Save tags”按钮,将更改保存到数据集。
同样,标签数据也可以使用SQL语法添加、修改或删除。在下一个示例中,在Databricks的工作区主目录中创建一个新的笔记本,并在笔记本的第一个单元格中添加以下SQL语句。在这个例子中,我们将更新数据集的描述标签:
ALTER TABLE yellow_taxi_raw
SET TAGS ('description'='Unprocessed taxi trip data')
最后,标签支持更细粒度的管理,可以添加到Unity Catalog中的数据集的列级别。这在您希望区分列的数据敏感性时非常有用,以便可以动态地为Unity Catalog中的视图应用数据掩码。
相反,用户可以通过在Catalog Explorer的搜索文本框中使用以下语法来搜索已应用标签的视图、表格或列:tag:<case_sensitive_name_of_tag>。
正如您所看到的,标签在促进数据集的可发现性方面非常有用,帮助用户在Unity Catalog中区分不同的数据集。
除了发现组织中的数据集外,了解数据集是如何形成的以及上游源是否受信任同样至关重要。数据血缘就是一种方法,帮助用户准确了解他们在Unity Catalog中发现的数据集是如何形成的,以及不同列的来源。
使用血缘追踪数据集关系
随着数据通过数据管道在湖仓中被转换,组织的数据集内容可以通过各种过程经历一系列演变。这些过程可能包括数据清洗、数据类型转换、列转换或数据丰富等。正如您所想,数据可能与最初从源头摄取时有很大差异。对于下游的数据消费者来说,能够验证数据集的有效性非常重要。数据血缘是进行此类验证的一种机制,它允许用户追溯表格和列的来源,从而确保使用的是来自受信任源的数据。
数据血缘可以通过Databricks数据智能平台中的多种机制进行查看:
- 通过Catalog Explorer直接查看血缘图
- 使用血缘追踪REST API进行检索
- 查询Unity Catalog中的血缘追踪系统表
让我们看看如何追踪下游表中几个列的来源,找到它们的上游源头。如果您还没有这样做,您可以从GitHub仓库克隆本章的示例笔记本,仓库地址为:github.com/PacktPublis… 。首先,导入名为“Data Lineage Demo.sql”的示例笔记本到您的Databricks工作区。将笔记本附加到正在运行的全能集群,并执行所有笔记本单元格。该笔记本将生成两个表——一个父表和一个子表,子表的列是从上游的父表构建的。
执行完笔记本并将表保存到Unity Catalog后,通过点击左侧导航菜单中的“Catalog”菜单项进入Catalog Explorer。从Catalog Explorer中,输入子表的名称并在搜索文本框中查找子表。点击子表以查看表格详情。最后,点击蓝色按钮“See lineage graph”生成血缘图。您会注意到,图表清晰地描绘了两个数据资产之间的关系——父表和子表。接下来,点击子表中名为“car_description”的列。您会看到血缘图会更新,清楚地展示了父表中哪些列被用来构建下游子表中的这一列。
事实上,得益于Unity Catalog的统一特性,数据血缘可以用于跨多个工作区追踪数据关系。此外,数据血缘将实时捕捉关系信息,以便用户无论使用哪个Databricks工作区,都能始终获得最新的数据集关系视图。
使用系统表进行可观测性
强大的审计和系统可观测性是Unity Catalog的另一个核心优势,并通过Databricks中的系统表实现。系统表是一组只读表,位于Databricks工作区中,用于捕捉有关您Databricks工作区内活动的操作数据。此外,系统表记录了Databricks账户内所有工作区的数据,作为单一的事实来源,用于检索与Databricks工作区相关的操作数据。
系统表记录了关于您Databricks工作区以下方面的可观测性信息(有关可用系统表的最新列表,请访问 docs.databricks.com/en/admin/sy… ):
| 类别 | 服务 | 描述 |
|---|---|---|
| 系统计费 | 可计费使用情况 | 捕获有关使用的计算资源(如数据仓库和集群)的计费信息 |
| 定价 | 历史定价变更 | 捕获系统服务定价(或库存单位(SKU))的历史变更 |
| 系统访问 | 系统审计 | 包含来自工作区服务(如作业、工作流、集群、笔记本、版本库、密钥等)的事件数据 |
| 表血缘 | 捕获有关Unity Catalog表的读写数据 | |
| 列血缘信息 | 捕获有关Unity Catalog表中列的读写数据 | |
| 计算 | 集群 | 捕获集群的配置信息,例如随着时间的推移的配置变更 |
| 节点类型信息 | 包含集群节点类型的硬件信息 | |
| SQL仓库事件 | 捕获SQL仓库的变更,如扩展事件 | |
| 系统存储 | 预测优化 | 捕获数据处理过程中发生的预测I/O优化 |
| 市场 | 市场漏斗事件 | 捕获市场分析信息,如数据集列表的展示次数和漏斗数据 |
| 市场列表事件 | 记录有关数据集列表的市场消费者信息 |
表 5.1 - 系统表将记录Databricks数据智能平台各个部分的操作信息
与Unity Catalog中的所有表一样,系统表默认不可访问。相反,元存储管理员需要为这些表授予适当用户和组读取权限(SELECT权限)。例如,为了授予部门领导在工作日跟踪其数据仓库扩展事件的权限,元存储管理员需要显式地授予组dept_leads查询SQL仓库系统表的权限:
GRANT SELECT ON system.compute.warehouse_events TO dept_leads
正如您所想象的那样,活跃的Databricks工作区将在一天内记录大量事件,随着时间的推移,这些表可能会变得非常庞大。为了防止可观测性信息积累到产生大量云存储账单的程度,系统信息将仅在Databricks账户中保留最多一年。
对于需要保留多年审计信息的用例,您需要设置一个二次处理过程,将系统信息复制到长期存档系统中。例如。追踪数据集的变更对于确保湖仓中强大的可观测性至关重要。Unity Catalog的另一个强大优势是,它的可观测性不仅限于数据集,还涵盖了所有可以在Unity Catalog治理下进行保护的对象。
追踪其他资产的血缘
如前所述,Unity Catalog实现了对组织数据资产的统一治理解决方案,这不仅限于表格。通过Unity Catalog,您可以追踪其他数据资产的血缘,如工作流、笔记本和机器学习模型等。
接下来,让我们关注Unity Catalog如何通过评估给定Databricks用户的用户和组权限,动态生成查询的不同结果集。
细粒度数据访问
动态视图是Databricks数据智能平台中的一种特殊视图类型,它为数据管理员提供了控制数据集内数据细粒度访问的能力。例如,管理员可以根据用户的组成员身份指定某个特定个人可以访问的行和列。Databricks数据智能平台引入了几种内置函数,用于在特定用户查询视图内容时动态评估组成员身份:
current_user():返回查询视图的用户的电子邮件地址is_member():返回一个布尔值(True或False),表示查询视图的用户是否是Databricks工作区级别组的成员is_account_group_member():返回一个布尔值(True或False),表示查询视图的用户是否是Databricks账户级别组的成员(与工作区级别组相对)
重要说明 对于在Unity Catalog中的表格和视图上创建的动态视图,建议使用is_account_group_member()函数来评估用户对组的成员身份,因为它将在Databricks账户级别评估组成员身份。另一方面,is_member()函数会评估用户对特定工作区的本地组的成员身份,可能会提供错误或意外的结果。
此外,动态视图还使数据管理员能够模糊处理特定列的值,以防止敏感数据被意外泄露。使用内置的Spark SQL函数,如concat()、regexp_extract(),甚至lit(),是保护Databricks平台上最敏感数据集内容的简单而强大的工具。
在下一部分,我们将探讨如何利用动态视图允许数据科学团队的成员对敏感数据集进行临时数据处理,同时保护包含个人可识别信息(PII)数据的列内容。
实践示例 – 数据掩码处理医疗数据集
在这个示例中,我们将创建一个动态视图,限制对数据集中特定行和列的访问。我们将使用位于Databricks数据集中的COVID示例数据集,路径为 /databricks-datasets/COVID/covid-19-data/us-counties.csv。该数据集包含2020年全球大流行期间美国县的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}")
接下来,我们需要在Unity Catalog中定义一个持久化表对象,用于创建视图。让我们从使用示例的美国县COVID数据集开始创建一个新表:
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}"));
接下来,让我们查询新创建的表格。在此查询中,由于我们没有指定任何筛选条件,因此返回所有的列和行:
spark.table(f"{CATALOG_NAME}.{SCHEMA_NAME}.{PERSISTENT_TABLE_NAME}").display()
接下来,我们将创建一个动态视图,动态评估查询用户在Unity Catalog中的组成员身份。在这个例子中,我们希望在用户不是管理员组的成员时,限制对某些列的访问。基于组成员身份,我们可以授予用户访问权限或限制对数据的访问。
我们还将利用一个内置的Spark SQL函数,对敏感数据列应用简单但强大的数据掩码,使得只有管理员组的特权成员才能查看文本内容:
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}
""")
在上面的视图定义中,我们限制了对美国县COVID数据集中某些列的访问。使用动态视图,我们还可以使用查询谓词限制对特定行的访问。在最终的视图定义中,我们将根据用户是否为管理员组的成员,限制某个用户可以查看哪些美国州:
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
""")
现在,其他组的成员可以执行临时数据探索和其他数据实验。然而,我们不会意外地暴露任何敏感的医疗数据。例如,假设有一个名为 data-science 的组。这个组可以查询动态视图,但结果将与管理员组成员查询该视图时的结果不同。例如,以下聚合会根据用户是管理员组成员还是数据科学组成员返回不同的结果集:
(spark.table(COL_AND_ROW_RESTRICTED_VIEW_NAME)
.groupBy("state", "county")
.agg({"cases": "count"})
.orderBy("state", "county")
).withColumnRenamed("count(cases)", "total_covid_cases").display()
我们将得到以下结果:
到现在为止,您应该能够意识到Databricks数据智能平台中动态视图的强大功能。通过几个内置函数,我们可以在多个用户和组与组织的数据交互过程中实施强大的数据治理。
总结
在本章中,我们讨论了湖仓数据治理的具体挑战,以及Unity Catalog如何解决这些挑战。我们还讲解了如何在现有的Databricks工作区中启用Unity Catalog,以及元存储管理员如何与外部数据源建立连接。最后,我们介绍了如何在湖仓中发现和管理数据资产,以及如何通过为数据资产附加元数据标签来创建一个可搜索且组织良好的数据目录。
在下一章中,我们将探讨如何使用Unity Catalog有效管理输入和输出数据位置。您将学习如何在组织内的不同角色和部门之间治理数据访问,确保Databricks数据智能平台中的数据安全性和可审计性。