“技术;多用户计算机”(Technology; The Multi-User Computers)
《纽约时报》1984 年 8 月 23 日纸质版刊登了题为“Technology; The Multi-User Computers”的文章。文中引述财富系统(Fortune Systems)董事长 James S. Campbell 的话:“直到现在,世人其实还不真正相信 Unix 和多用户系统。现在他们会相信了。 ”
快进到 2006 年,AWS 通过推出 S3 并紧随其后发布 弹性云计算(EC2) ,宣布了首个云平台,它们成为众多现代云端应用的骨干。2008 年,Google Cloud 上线并发布 App Engine。同年,微软宣布其云计算操作系统 Windows Azure。自那以后,云计算的发展推动数据平台向云端迁移,如今所有主要的数据处理平台都生于云、长于云,Databricks 也不例外。
当你把最有价值、最敏感的数据托付给云平台时,同样需要把信任延伸到那些帮助你释放数据全部潜力的云端数据处理平台。当你了解数据平台实施的治理标准时,信任便得以建立。本章旨在当你使用 Unity Catalog 满足治理需求时,进一步增强你对 Databricks 平台 的信任。
在 Nexa Boutique,数据治理是第一优先,这也在其选择 Unity Catalog 作为其 数据智能平台(Data Intelligence Platform) 的治理方案时发挥了核心作用。Nexa 的数据架构师认识到:metastore 只是云端数据平台治理拼图中的一块。计算引擎对用户数据执行细粒度访问控制(FGAC)的能力,同样是打造安全数据平台的关键。由多个计算引擎处理数据会使 FGAC 的落地更加复杂,难以维持一致的治理标准。Databricks 数据智能平台 + Unity Catalog 的突出之处在于:无论终端用户如何消费数据,它都能在所有计算引擎上提供一致的治理能力。理解 Unity Catalog 的计算基础设施(包括其能力与限制)让 Nexa 的数据架构师更易于做出决定。本章将探讨 Databricks 如何精心设计其计算选项,并由 Unity Catalog 统一治理,以建立并维持用户信任。
在设计数据治理方案时,有两大要素:metastore 与 计算引擎。这里我们讨论实现数据治理的不同架构模式及其复杂性。Databricks 提供多种风格的计算选项,包括经典架构与无服务器(serverless) 。我们将在此先介绍支持 Unity Catalog 的经典计算选项,并说明如何将它们用于你的计算需求。无服务器计算是一种强大的选择,同样支持 Unity Catalog 的访问控制。我们将探讨其架构,并明确在哪些特定场景下无服务器最为适配。
落地治理:一个由两部分组成的问题(Implementing Governance: A Two-Part Problem)
正如 Nexa 的数据架构师所指出,仅在 metastore 内定义访问控制不足以确保有效的数据治理。所有与数据交互的计算引擎都必须严格遵循并执行在 metastore 中指定的访问控制。这一要求在技术上颇具挑战。Databricks 提供不同的计算类型,包括:经典通用计算、无服务器通用计算、SQL Warehouse Pro 与 SQL Warehouse 无服务器。在这些计算之上,用户还会通过多种编程语言与接口访问数据,包括 SQL、Python、Scala、R 以及基于 API 的远程执行——这使得在不同工具与计算引擎间实现统一的治理框架变得复杂。
设计数据治理方案时,将其拆分为两大组件会更有帮助:
- Metastore
作为集中式存储库,保存关于数据的全部访问控制与元数据。 - 计算引擎(Compute Engine)
负责执行访问控制,确保 FGAC(如行级过滤与列级遮蔽)得到一致应用。
第二个组件——计算引擎——是最大挑战所在。若在计算引擎上执行访问控制是一件易事,那么集中式治理几乎就已解决。但事实并非如此。在计算引擎上执行访问控制的复杂性,正是难以实现集中式治理的根源。最直接的数据治理实现方式,是为用户分配专用计算资源来运行单一语言,类似传统 RDBMS,允许他们与该计算交互,如 图 4-1 所示。
图 4-1. 最直接的隔离式治理实现
当一个 metastore 被多个计算引擎类型共享,且数据通过不同编程语言访问时,难度会迅速增加:每个计算引擎都必须一致且可靠地执行访问控制,而不论终端用户如何消费数据。这需要一个值得信赖、与既定治理标准兼容的计算层,否则就会损害治理方案的完整性。要实现完全隔离的数据处理,其复杂度会随三大因素呈指数级上升:
- 用户数量
- 支持的编程语言种类
- 参与的计算引擎数量
虽然存储层架构与处理能力等因素也会影响性能,但上面这三点对实现隔离式数据处理的整体复杂度影响最大。若将复杂度绘图,你会得到类似 图 4-2 的趋势。
图 4-2. 随着用户、计算与语言增加,复杂度(用数字表示以便理解)上升
在企业级环境中,为每位用户部署专用计算资源不可扩展,成本会迅速攀升。为缓解这一点,计算引擎必须支持多用户,通过共享资源降低成本。迈向这一目标的下一步,是实现进程隔离,即将每个用户的进程彼此隔离,且与他人隔离,包括处理期间生成的临时文件,如 图 4-3 所示。虽说这种架构复杂,但理解起来相对直观;它同样类似许多 RDBMS 系统,因为仅支持单一查询语言,并被众多云数据处理工具广泛支持。
图 4-3. 通过进程隔离来实现计算资源共享
一个有效的数据平台必须容纳多种编程语言,因为不同组织的具体需求差异很大。当在运行不同语言的计算引擎上,从中央 metastore 强制治理时,复杂度会进一步增加。一个推荐做法是:为每种语言部署专用计算引擎,以适配不同用户画像,如 图 4-4 所示。
然而,按用户专用计算又回到了最初的挑战:如何在执行多种编程语言的多样化用户画像之间安全地共享计算资源。最复杂的实现可以视为这样的架构:一个通用计算引擎同时支持多语言接口并启用多租户以共享计算资源。就数据治理而言,这要求在计算引擎内隔离用户、用户代码与进程,并阻止对进程在处理中写入的共享临时路径的访问。
图 4-4. 支持多语言与多计算引擎的治理实现
图 4-5 展示了类似实现。在该场景中,多个拥有不同角色与需求的用户,从共享的 metastore 访问并处理数据,同时使用各自偏好的语言:有的用 Python,有的用 Scala,还有的依赖更传统的基于 SQL 的数仓访问。共享的 metastore 作为中央存储库,管理所有表的元数据,并无视语言差异为这些用户的请求提供服务。鉴于多个用户进程共享同一计算资源,隔离是头等大事:必须将每个进程置于沙箱,以防未经授权访问他人数据集,确保敏感数据的安全与完整性。在处理期间,大多数数据引擎会把数据写到临时位置;必须保护这些数据的完整性与安全性,因为若对这些临时路径的访问未受控制,敏感信息就可能暴露给未授权用户。Unity Catalog 连同 由 Lakeguard 驱动的共享计算架构正是为解决这种计算共享难题而生,使其成为面向多用户 Apache Spark 集群的企业级数据治理工具。
图 4-5. 在共享计算上支持多语言的治理实现
Nexa Boutique 的数据平台服务于多种用户画像:数据工程师、数据科学家、数据分析师、AI 工程师与业务用户;平台内不同团队对编程语言也有各自偏好。例如,需求规划团队的数据工程师偏爱 Python 构建数据摄取流水线;而仓储运营团队的数据工程师更偏好 Scala。数据分析师依赖 SQL 构建 Power BI 仪表板;数据科学家通常使用 Python、R 与 MATLAB 的组合进行预测分析与 ML 建模。
在引入 Databricks 与 Unity Catalog 之前,各应用团队在其数据平台上使用不同的治理工具,导致治理破碎。用户对数据湖底层文件的直接访问更是削弱了表级访问控制,使问题雪上加霜。跨域团队的数据共享繁琐低效:数据往往被复制到多个应用中,而每个应用都有自己独立的治理框架与工具集。图 4-6 展示了 Nexa 在采用 Databricks 与 Unity Catalog 之前治理不足的模型。尤其是,数据治理与基于这些数据构建的 ML 模型等关键资产相互割裂,导致不一致与低效。过去,常见做法是对用于训练 ML 模型的表无限制地开放底层数据文件的访问,这带来了安全与数据完整性风险。
图 4-6. 多工具与多访问方式导致破碎的治理模型
Unity Catalog 通过解决两个关键组件来应对治理挑战:
- 区域级 metastore:跨不同计算引擎共享对象时,集中处理其元数据;
- Unity Catalog Lakeguard:隔离用户与进程,在不同计算引擎与编程语言间执行 FGAC。
第 2 章已简述其架构——我们看到 Spark Connect 如何实现用户隔离,而 Lakeguard 如何在 Spark 集群中实现进程与代码隔离。接下来我们将更深入地了解 Unity Catalog 中的计算选项,并认识如何为你的工作负载选择合适的计算。
Databricks 的经典计算(Classic Compute in Databricks)
Databricks 在你的云账户内为计算资源采用经典计算架构,以处理驻留在该处的数据。也就是说,当你在自己的云账户中(如 Amazon S3、Azure Blob Storage 或 GCS)存放数据并运行 Databricks 工作负载时,Databricks 会在你的云账户中自动部署并托管经典计算资源(例如集群)来执行工作负载。
经典计算架构在为 Spark 集群微调基础设施方面提供了灵活性:既可为 driver 与 worker 节点指定实例类型,也可微调 Spark 参数以优化成本与性能。在保持灵活的同时,经典计算架构仍通过 Unity Catalog 支持数据治理,并对数据执行细粒度访问控制(FGAC) 。在经典计算中,Unity Catalog 以两种模式工作:**standard / shared access(标准/共享访问模式)**与 dedicated / single-user(专用/单用户访问模式) 。图 4-7 展示了 Databricks 的经典计算架构,计算实例托管在 Nexa Boutique 的云账户中。
图 4-7. 经典计算架构
Standard / Shared Access(标准/共享访问)
在构建受治理的数据平台时,在完全隔离用户的前提下共享计算资源是基石。实现此类系统并不容易,Unity Catalog 的 standard compute 也不例外:它的工程实现相当复杂,并且为了达成这一目标,对平台核心的数据处理引擎进行了重构,同时停止支持了旧架构中的部分特性。因此,许多遗留功能需要迁移到 Unity Catalog 标准计算所支持的格式。第 2 章已提到,基于 DataFrame API 的 Spark Connect 支持的用户隔离,使得RDD API 在标准计算中停止支持。任何无法在隔离环境中运行、或可能破坏 Unity Catalog 治理标准的进程,均无法在标准访问模式下工作。就当前而言(撰写时点),标准计算存在一些限制;部分会随时间修复,另一些(如对 RDD 的支持)则不太可能实现。
标准模式支持终端用户使用多种编程语言,包括:
- Python
- SQL
- Scala
在 Databricks 工作区中创建通用计算(all-purpose compute)时,用户可在高级设置中选择访问模式,如 图 4-8 所示。
图 4-8. 在 Databricks 工作区中创建计算资源
提示(TIP)
在使用 Unity Catalog 时,应将标准访问模式作为默认计算模式。该模式可覆盖你大多数工作负载(分布式机器学习除外,因此 ML DBR 在标准模式中不可用)。Databricks 的标准计算架构与前文讨论的“多语言、多用户”复杂架构类似,但在为 Apache Spark 这种分布式处理引擎构建治理能力时,需要更多实现细节。由于其 driver + 多个 worker 的分布式实现,传统 Spark 架构需要在 driver 上对应用进行隔离,同时在 worker 节点的 executor 上对执行的进程进行隔离,如 图 4-9 所示。
图 4-9. 在 Apache Spark 集群中基于共享 metastore 的治理
传统上,Apache Spark 并未以强用户隔离为前提而设计,更适合单用户或单应用并拥有对底层基础设施的高权限场景。一旦被不同用户共享,这种不受限的访问会带来数据安全风险。正是这种“共享但不受限”的架构促使 Databricks 打造出更强隔离、可在不同用户或应用间共享且不牺牲数据安全的 Spark 计算。传统 Spark 架构中,Spark 引擎与应用共用 driver 节点的 JVM。而在标准访问模式中,运行于 driver 节点的各进程对 driver JVM 的访问受限;每个进程与其代码在 driver 侧都在独立 JVM 中隔离运行。类似地,在 worker 节点上,包含 UDF 在内的各进程也在不接触 executor JVM的前提下隔离运行。Spark 写入中间结果的临时路径也被阻断了相互访问,从而更为安全。
标准集群中的 Unity Catalog Lakeguard
Apache Spark 是开源的数据处理引擎,被从创业公司到大型企业的各类数据平台广泛采用。多家云与数据平台都提供其托管版 Spark。那么,标准访问模式的 Spark 集群为何优于其他方案?它的独到之处在哪里?
Unity Catalog 的标准访问模式 Spark 计算引擎,在 Lakeguard 的支持下,在 driver 与 executor 节点之间为用户、代码与进程提供完全隔离。第 2 章我们看到,Spark Connect + 容器化的组合,如何在标准集群中实现隔离并提升数据治理。下面用实际例子说明标准访问模式的工作方式。
Nexa Boutique 高度重视客户反馈与产品评论,并快速响应以确保满意度并降低流失风险。公司利用情感分析模型从客户反馈中挖掘洞察,并据此推动内部流程优化,直击负向情绪集中之处。
市场团队会主动与客户沟通解决问题。customer 表启用了 FGAC:市场团队可以查看邮箱与地址等字段,其他用户则不可见。借助 Lakeguard,市场团队可以在隔离环境中查询该表,同时限制未授权用户访问,保证标准集群内的数据安全。
在 Nexa,市场团队与需求规划团队都访问 Unity Catalog 中的 customer 表,但在该表上被授予的权限不同。市场团队使用 SQL 查询;需求规划团队在 Databricks 笔记本中使用 PySpark 读取同一数据。需求规划团队不应看到客户邮箱与地址,因此管理员使用 Unity Catalog 的列遮蔽(masking)函数进行隐藏。该函数就像一个过滤器:对于非市场团队用户隐藏敏感信息,而对市场团队用户放行。示例如下:
CREATE FUNCTION email_mask(email STRING) RETURN CASE
WHEN is_member('marketing-team') THEN email
ELSE 'REDACTED'
END;
ALTER TABLE customer
ALTER COLUMN email
SET MASK email_mask;
遮蔽函数会按访问该表的用户实时生效。当需求规划团队用户运行 PySpark 笔记本时,计算集群会从云存储取回相关文件,应用过滤与遮蔽,最终返回被遮蔽的数据。尽管该用户无权看到未遮蔽的邮箱与地址列,底层取数仍会把这些列读入;但不用担心,Lakeguard 的容器化隔离确保数据在以非 root 用户运行的容器内处理。需求规划团队只会看到被遮蔽的邮箱与地址列。
另一方面,市场团队在同一集群中发起 SQL 查询,但运行在与他人隔离的容器中。由于市场团队有权访问未遮蔽数据,Unity Catalog 函数不会额外遮蔽。完成相应过滤后,Lakeguard 将明文结果返回给市场团队用户。
Lakeguard 的隔离机制保证两方进程互不干扰,也无法访问彼此的数据或 Spark 临时输出路径。这样,需求规划团队的进程就不可能从市场团队的数据中获取未遮蔽的邮箱与地址,从而严格执行数据治理与访问控制。流程如 图 4-10 所示。
图 4-10. 标准集群上的细粒度数据访问
Unity Catalog 的护栏与服务凭据(Service Credentials)
关于 Unity Catalog 计算,Nexa 的数据架构师有一个关键问题:能否用 Unity Catalog 之外的凭据绕过其访问控制?在 Databricks on AWS 的工作区中,你可以为 Spark 集群关联一个 IAM 策略允许的 instance profile,从而读取 S3 数据桶中的数据;你也可以用该 profile 集成其他 AWS 服务(如 SNS),并通过 Boto3(AWS SDK for Python)扩展能力。若用户可以通过 UC 之外的凭据突破 Unity Catalog 的护栏,后果不堪设想:获准使用 Spark 集群的用户可能借外部凭据读取存储层数据,进而访问未授权数据。
为防此事,Unity Catalog 将对已在 UC 中注册的外部位置(external location)的访问限定为 UC 内管理的存储凭据。例如,在 Databricks on AWS 工作区中,你可以将 IAM 角色注册为 UC 的 storage credential;随后使用该存储凭据,将某个 S3 bucket 注册为 external location。但如果尝试在没有 READ FILES 权限的情况下访问该 external location,Unity Catalog 会阻止访问——即使你使用一个对同一 S3 bucket 拥有更大读写权限的外部 instance profile。换言之,Unity Catalog 的访问控制优先于任何外部权限。
再看 Unity Catalog 共享访问模式下的网络与文件系统访问限制:文档明确指出“你无法连接到实例元数据服务(IMDS)、其他 EC2 实例或 Databricks VPC 中的任何其他服务”。当 instance profile 附加到 EC2 实例时,可以通过访问 http://169.254.169.254/latest/meta-data/iam/security-credentials/<iam_role_name>/ 调用 IMDS 获取临时凭据。由于 Unity Catalog 不对直接附在集群上的 instance profile提供 FGAC,故在标准访问模式下不允许此类基于 instance profile 的认证(见 图 4-11)。
图 4-11. 不支持基于 instance profile 的外部云服务访问
Nexa 在 Databricks on AWS 的工作区中原本使用 Amazon SNS 向客户发送营销活动数据。但在 Unity Catalog 的标准访问模式集群中,这一做法不受支持。此外,Unity Catalog 不支持在 Declarative Pipelines 中使用 instance profile 与 Amazon Kinesis 进行认证(Kinesis 承载来自 POS 系统的交易数据)。云管理员起初为应急,在 UC 标准集群中发放长生命周期访问令牌,并存放于 Databricks secrets 中。此权宜之计虽可用,但仍需更优雅的方案。
定义:Lakeflow Declarative Pipelines
Lakeflow Declarative Pipelines(原 Delta Live Tables)是 Databricks 中用于构建数据处理工作负载的声明式框架。它可自动处理编排、依赖、数据质量与监控,帮助你专注于业务转换逻辑。
Unity Catalog 引入了服务凭据(service credentials) ,提供类似存储凭据的、由 UC 治理的外部云服务访问凭据。服务凭据将集群层的 instance profile 或托管身份(MI) “上移”到中心 UC metastore进行统一管理。共享标准模式集群的用户可被逐一授予使用某个服务凭据的权限,从而消除数据治理顾虑。
借助服务凭据,在 Unity Catalog 标准模式集群中可重新启用与 SNS 与 Kinesis 的连接,而无需长生命周期的密钥。图 4-12 展示了服务凭据实现的架构,它支持与外部云服务安全互联。
图 4-12. 服务凭据实现安全的外部云服务连接
如图所示,只有 User1 拥有 UC 中注册的服务凭据的使用权限;User2 未获授权,因此无法访问 AWS SNS 或 Kinesis。将 IAM 角色注册为 UC 的服务凭据后,若管理员已授予你对该服务凭据的 ACCESS 权限,你可以用它创建 boto3 会话来连接 SNS,例如:
import boto3
credential = dbutils.credentials.getServiceCredentialsProvider('your-service-credential')
boto3_session = boto3.Session(
botocore_session=credential,
region_name='your-aws-region'
)
sm = boto3_session.client('sns')
在 Azure Databricks 中,你也可以将 **托管身份(MI)**注册为服务凭据,并用于 Azure SDK 的认证,例如:
from azure.keyvault.secrets import SecretClient # 仅作 Azure SDK 示例
credential = dbutils.credentials.getServiceCredentialsProvider('your-service-credential')
vault_url = "https://your-keyvault-name.vault.azure.net/"
client = SecretClient(vault_url=vault_url, credential=credential)
标准访问模式的限制(Limitations of standard access mode)
由于新架构与 Unity Catalog 的治理规范,与基于 HMS 的 Databricks 计算相比,标准访问模式存在若干限制。截止目前(撰写时点),这些限制仍然存在;随着 Databricks 持续改进 Unity Catalog,其中部分限制有望被移除。
专用/单用户访问(Dedicated or Single User Access)
专用访问模式采用传统 Apache Spark 架构:被指派到该计算资源的用户获得提升的访问权限。在 Databricks 中,专用模式支持 ML runtimes,能够运行大多数 ML 与 AI 工作负载。第 2 章已展示过专用模式集群的架构,以及无服务器层如何为表与视图提供 FGAC。在专用模式中不提供 Spark Connect 与基于容器的隔离,计算资源仅供被指派的单个用户访问。专用模式类似我们先前讨论的“最直接的隔离式治理实现”,只是 Databricks 基于 Apache Spark 的实现在同一计算引擎中支持多种编程语言。
在 Nexa,管理员将专用模式集群明确指定给 ML 与 AI 工作负载,以及使用 R 语言的数据科学家。与标准模式相比,专用模式支持更多语言与特性,包括:
- Python
- Scala
- R
- SQL
- Machine learning Databricks runtime(MLR)
- Databricks container service(DCS)
专用访问模式的架构对在计算中运行的进程给予更高权限,因此需要更严格的数据治理。一个显著问题是:当对启用 FGAC 的视图或表进行查询时,会发生过量读取(overfetching) (详见第 2 章)。下面继续以 customer 表为例:市场团队被授予查看客户 PII 的权限,而其他团队受到限制。我们看看在专用模式计算中如何处理。
当市场团队用户对 customer 表提交查询时,系统使用由 Unity Catalog 签发的临时凭据从云存储取回相应文件。图 4-13 展示了 Unity Catalog 中 customer 表的云存储位置,底层物理文件为 Delta 格式。根据市场团队用户执行的查询,需要从云存储抓取 File1.parquet 与 File2.parquet,供计算引擎进一步处理:
SELECT
*
FROM
customer
WHERE
customer_id = 1011
图 4-13. customer 表的云存储
然后,专用计算对文件进行处理,过滤无关数据,并将查询结果返回给用户。对拥有该表完整读取权限的用户而言,这种过滤方式没有问题:不会应用任何遮蔽规则;且即使在 Spark 处理过程中通过临时路径发生了对未过滤数据的偶然访问,也不影响数据治理,因为用户本就拥有完全读取权。
当需求规划团队用户对 customer 表提交同样的查询时,系统同样会从云存储抓取 File1.parquet 与 File2.parquet,并传入专用计算环境;随后过滤无关数据以生成所需信息。由于该用户不具备对该表的完整读取权限,系统会应用数据遮蔽规则以保护敏感 PII:先在明文数据上执行过滤,再对 PII 进行遮蔽,最后将过滤且遮蔽后的结果返回,确保敏感信息受到保护。
在专用访问模式中,进程以提升权限运行,存在将未遮蔽敏感数据暴露给用户的潜在风险,如 图 4-14 所示。由于文件是在未遮蔽的状态下从云存储取回,提升权限与未遮蔽数据的组合会放大未授权暴露的风险。为缓解该风险,专用访问模式限制用户对启用 FGAC 的表进行查询。
此外,动态视图(dynamic views) 、流式表(streaming tables)与视图(views)也仅限从专用模式计算引擎访问。
视图建立在表之上,提供受限或聚合后的数据表示。由于视图在运行时由计算引擎物化,因而需要访问底层表文件。文件以连续块写入的特性,可能导致包含用户无权访问的列被一并传输到专用计算,引发敏感数据暴露风险。对视图的访问只有在用户对视图引用的底层表拥有读取权限时才被允许。在专用计算模式下,限制访问启用 FGAC 的表与视图,能够降低未授权数据暴露风险,但也会限制用户的数据访问能力,影响其查询与分析。
定义:STREAMING TABLE(流式表)
流式表是支持增量数据处理的 Delta 表,适用于持续增长的数据集。它非常适合需要新鲜数据与低时延的管道,同样适合大规模转换场景,在新数据到来时可增量更新结果。
图 4-14. 在启用 FGAC 的表上查询时的专用模式集群
注意(NOTE)
“专用模式仅能查询未启用任何 FGAC的表”的限制仅在你使用 15.4 LTS 以下版本的 Databricks Runtime(DBR)时存在。自 DBR 15.4 LTS 起,借助无服务器过滤编队(serverless filtering fleet) ,Lakeguard 已在专用模式计算上启用 FGAC。
专用集群中的 Unity Catalog Lakeguard
在 Nexa,大多数数据表都应用了行级过滤或列遮蔽。然而,专用计算访问模式历史上缺乏 FGAC,使得启用 FGAC 的表无法从专用模式集群访问。受限于标准集群对 Databricks MLR 的支持,Nexa 的所有 ML 工作负载都运行在专用模式集群上;在 Lakeguard 为专用模式集群启用 FGAC 之前,对启用 FGAC 的表进行分析是不可行的。
Lakeguard 通过一个运行在 Databricks 所属托管数据平面(managed data plane)内的无服务器计算——即过滤编队(filtering fleet) ,在 DBR 15.4 LTS 引入后,为专用模式集群启用 FGAC。过滤编队会对从云存储读取的数据执行过滤,去除所有未授权信息,然后再将已过滤的数据加载回专用计算,提供给消费者。
Lakeguard 过滤编队解决了从专用模式集群查询表时的过量读取问题。该无服务器过滤编队在托管数据平面中创建,且对用户不可见。任何从云存储读取的文件都会先加载至过滤编队;所有过滤操作(包括行级过滤与列遮蔽)都在此无服务器层完成;视图物化也在此层执行,从而确保仅处理并返回与权限与筛选条件相符的数据。最终数据集再被加载回专用计算层并返回给终端用户。
Lakeguard 在专用访问模式计算中为多类对象启用 FGAC,包括:
- Views(视图)
- Materialized views(物化视图)
- Streaming tables(流式表)
- Dynamic views(动态视图)
- 应用了行过滤函数的表
- 应用了列遮蔽函数的表
定义:MATERIALIZED VIEW(物化视图)
物化视图是预计算的视图,按计划进行刷新。Databricks 建议将它用于复杂数据处理任务,如转换、聚合,以及优化慢查询或高频计算。
定义:DYNAMIC VIEW(动态视图)
可基于用户或其身份的某些属性动态过滤数据,从而实现 FGAC。与常提供固定数据的静态视图不同,动态视图可在运行时依据用户角色等属性过滤/变更输出。
继续分析需求规划团队用户对 customer 表的同一条 SELECT 查询:所需的 File1.parquet 与 File2.parquet 会被加载到由 Databricks 托管、用户不可直接访问的中间无服务器过滤编队计算环境中,以确保在数据上强制执行过滤与访问控制。
随后,过滤与遮蔽后的结果数据被加载进专用模式集群,再返回给最终用户。通过将过滤与遮蔽过程从拥有提升权限的专用集群以及用户本身隔离开来,Lakeguard 在专用模式集群上实现了 FGAC,从而在 Nexa 解锁了大量用例。图 4-15 展示了在 Unity Catalog 专用访问模式计算环境中,过滤编队的工作方式。
图 4-15. 无服务器过滤编队在专用模式中启用 FGAC
专用访问模式的限制
仅在标准访问模式不支持的工作负载上,才建议使用专用访问模式。由于其对底层计算具有提升访问,专用模式存在一些限制。在构建基于 Unity Catalog 的数据与 AI 应用、并拟使用专用访问模式计算之前,建议先查阅 Databricks 的最新文档,确认当前支持的功能并充分了解限制。
指派给用户组的集群(Assigned to Group Cluster)
Nexa 的关键工作负载(包括分布式 ML 与依赖 GPU 的应用)需要专用访问模式计算。此外,一些使用 RDD 与 DBFS 的遗留框架也依赖该模式。因此,Nexa 的平台管理员给大多数数据科学家和 ML 工程师分配了各自的专用访问模式集群(运行 Databricks MLR)。为每位用户单独创建与维护集群会带来可扩展性与成本效益问题。
为解决这一挑战,Databricks 引入了指派给用户组的集群(assigned-to-group clusters) ,使团队可以通过组共享专用计算资源。Databricks 管理员可以从身份提供商(IdP)将这些组同步到 Databricks 账户,或直接在工作区内创建与管理。更全面的身份管理内容,参见第 3 章。本机制允许将专用访问模式计算指派给某个组,组内所有用户即可共享该计算资源,同时享有专用访问模式集群的全部特性。
在 Nexa 的需求规划(Demand Planning)团队中,一群数据科学家利用数据分析与时间序列预测建模来预测未来需求。团队使用 ARIMA(自回归积分滑动平均)分析历史需求数据,识别模式与趋势以预测未来需求。借助这些预测,团队更好地理解对供应链的潜在影响,并据此做出数据驱动的库存与物流决策。
起初,团队中每位数据科学家都被指派了一个专用模式集群以开发其 ML 模型,这给 Nexa 平台管理员带来了显著的成本与基础设施运维开销。为降低总体拥有成本(TCO) ,管理员为数据科学家创建了一个新的 Microsoft Entra 组,并将其指派给一个专用模式集群。借助指派给用户组的集群,该组内的数据科学家共享同一专用计算资源,提升了集群利用率并降低了 TCO。
从架构上看,“指派给用户组的集群”与专用模式集群的设计一致。关键在于权限模型的差异:当某个专用或标准访问模式的计算被指派给单个用户时,用户在 Unity Catalog 中对数据的个人权限会被正常强制执行;而指派给用户组的集群会忽略个人授权,改为使用组的授权,这使得所有组内用户拥有相同级别的数据访问权,与其个人权限无关。因此,当通过组来共享专用模式计算时,管理员与数据所有者必须将所需 Unity Catalog 对象的访问权限授予该组,以便工作负载能顺利运行。图 4-16 展示了 Nexa 需求规划团队中,属于组 NB_DP_Data_Scientist 的各位数据科学家在 Unity Catalog 表上的访问方式是如何随“组指派集群”而变化的。
图 4-16. 属于 NB_DP_Data_Scientist 组的 Nexa 需求规划团队数据科学家的表访问权限
注意(NOTE)
SparkML 是广泛使用的、基于 CPU 的分布式 ML 库。其主要限制之一是依赖 RDD API。因此,在 Unity Catalog 中它只能部署在专用集群或指派给用户组的集群上,难以在可供多用户共享的标准访问模式计算中灵活使用。不过,随着 Apache Spark 4 的发布,开源社区正在为 Spark Connect 引入对 SparkML 的支持。这将使 SparkML 可用于标准集群,并在未来可用于无服务器环境。该能力需要 DBR 17 或更高版本。
走向无服务器的 Databricks(Going Serverless with Databricks)
经典计算(classic compute)允许你在自有云账户中托管 Databricks 计算基础设施,利用该计算来处理你的工作负载与数据(如 Amazon S3、Azure Blob Storage、GCS)。你可以在自有云账户中自带 VPC/VNET,由 Databricks 在其中部署计算资源。经典计算为调优 Spark 集群提供了灵活性:你可以选择 VM 类型与 Databricks Runtime 版本,并通过调整 Spark 配置来优化性能与成本。由于计算基础设施位于你自己的云账户中,天然具备用户间的资源隔离;此外你还可配置网络(如云厂商的 Private Link 与存储防火墙)以进一步增强安全性。
定义:VPC/VNET
VPC(虚拟私有云)或 VNET(虚拟网络)是云中的虚拟化网络基础设施,为云资源提供安全、隔离的环境。用户可自定义 IP 地址段、子网与网络配置,从而获得高度的控制与安全。
尽管具备上述能力,经典计算也有局限,其中最大的问题是集群启动时间。任何一次经典计算创建请求可能需要 2–10+ 分钟(取决于区域与所选 VM 可用性)。主要耗时来自云厂商提供 VM 的延迟,其余是软件初始化。对于短时作业,频繁的启动会带来显著开销;启动时长也会计入 TCO,因为云厂商会对这段时间的计算资源收取费用。除启动时间外,你还需考虑容量规划与预留、自建网络与 VPC/VNET(子网与 IP 分配)等平台管理开销;随着业务增长与工作负载增加,还会受到云厂商配额与限制的掣肘。你也需要持续跟踪 Databricks Runtime 的版本升级,避免运行在将被弃用的版本上。——如果能把这些管理负担全部交给 Databricks 自动处理,会怎样?这正是**无服务器计算(serverless compute)**的价值所在:它解决了诸多问题,加速你的数据创新。
构建无服务器架构本身极其复杂。如果你曾在本地搭 Hadoop 或 Spark 集群,便了解其中门道。如今要在全自动的无服务器环境中复现同等复杂度——这正是无服务器 Spark 集群所做到的:由无服务器计算在数秒内调度启动。Databricks 无服务器每天启动数百万台 VM,全部受 Unity Catalog 的访问控制治理,这展示了 Unity Catalog 在超大规模下的治理能力。
经典计算的启动时间主要由两部分决定:
- 云厂商供应 VM 的时间;
- 集群内安装与配置依赖的时间。
无服务器计算池(serverless compute pool)通过预热 VM 来消除冷启动,显著缩短第 1 部分耗时。无服务器基础设施部署在 Databricks 的无服务器计算平面,通过预置镜像、包与依赖,按需快速下发,瞬时支撑工作负载执行。该架构模式已为主流云上的无服务器产品广泛采用,并辅以完备的网络安全选项,确保每个用户的工作负载在专属隔离环境中运行,最大限度降低未授权访问或数据泄露风险。
第 2 部分涉及安装与配置运行 Spark 集群所需的库与依赖(包括 Databricks runtime 镜像与监控工具)。无服务器基础设施使用定制操作系统、容器镜像以及其他优化,使计算更快可用。Databricks 工程博客 Booting Databricks VMs 7x Faster for Serverless 对这些优化有深入阐述。将以上实现相结合,Databricks 的大多数工作负载可在30 秒内获得可用的无服务器计算。
在 Databricks 中,无服务器计算覆盖多个产品域,包括:
- Serverless generic compute(通用无服务器计算)
- Serverless data warehouse(无服务器数据仓库)
- Serverless model serving(无服务器模型服务)
- Serverless Databricks Apps
- Serverless Lakeflow Declarative Pipelines
Databricks 的无服务器选项仍在不断扩展,预期最终会从当前的 PaaS 形态演进为 SaaS。接下来,我们将更深入地介绍当前的无服务器产品、其架构,以及它们如何与 Unity Catalog 集成,为你提供一流的数据与 AI 治理。
无服务器通用计算(Serverless Generic Compute)
想象一下:在本地数据中心里,为了让一个新的 Hadoop 集群跑起来,你得等上六个月。这正是 Nexa 团队过去的处境——从审批、采购硬件到系统配置,每一步都是拖慢创新的障碍。若能反转这一切呢?**无服务器计算(serverless)**就能做到:几秒内就拥有构建应用所需的基础设施——不用等待,也无需折腾。它让你即时获取计算与基础设施,把点子迅速变成现实。
Databricks 的无服务器通用计算支持交互式工作负载、定时作业以及在 Databricks 内编排数据与 AI 任务的工作流。从基础设施视角看,它与传统实现架构不同,但在 Unity Catalog 中与**标准访问模式(standard access mode)**共用相同的后端。标准访问模式借助 Spark Connect 实现完全隔离地强制 Unity Catalog 的访问控制。无服务器版本适用于 Databricks 作业与工作流:既能从 Notebook 或 IDE 运行交互式任务,也能运行基于 Databricks Workflow 的定时作业。图 4-17 展示了 Databricks 通用计算中的无服务器工作方式:使用无服务器计算池与基于 Spark Connect 的 Unity Catalog 标准访问模式。
图 4-17. Databricks 中的无服务器通用计算
当用户请求无服务器计算时,流程如下:
- 用户从 Databricks 工作区发起连接无服务器计算的请求。写作时,用户、控制平面与计算平面之间的所有请求均使用 TLS 1.2 加密传输。
- 控制平面联系由 Databricks 维护的 VM 池来执行作业。该池是未分配的,包含刚创建、未关联任何凭据的 VM。
- 首先分配一个客户端 REPL VM 用于评估用户请求。
- 客户端 REPL 通过 Spark Connect 连接到 Spark 集群,并通过 Unity Catalog 生成访问数据所需的短期凭据。工作负载在其私有网络中运行,不分配公网 IP;且不同无服务器工作负载之间不可互通。写作时,所有挂载到计算的存储均以 AES-256 加密。
- 读取数据时,计算连接到客户的数据平面,并使用 Unity Catalog 签发的短期凭据读取云存储。
- 处理完成后,数据返回给用户。随后相关存储与计算资源被安全清理,不会被其他工作负载复用。
无服务器计算与 Unity Catalog 深度集成,一致地执行访问控制以保障数据安全。在 Nexa,所有短作业都迁移到无服务器,借此避免经典计算的冷启动成本、降低 TCO。无服务器同时是“无版本”的:数据团队可直接使用 Databricks 推出的新功能,而无需经历 Databricks Runtime 的版本升级流程。
无服务器数据仓库(Serverless Data Warehouse)
数据仓库允许你对云存储中的数据执行 SQL 查询。在 Databricks 产品族里,无服务器通用计算比早期产品(如无服务器数据仓库)更复杂:它需要一个多语言、多用户且隔离的设置,类似 Unity Catalog 的标准访问模式。
而无服务器数据仓库只提供 SQL 接口,同样使用无服务器池,但不采用 Spark Connect 架构。与需要对操作系统具备高权限的分布式 ML 工作负载不同,SQL 仓库并不需要提升到计算资源的管理级权限。它沿用了支撑 Databricks 各类无服务器工作负载的深度网络隔离策略,包括:
- 专用 VM
- 无公网 IP 的网络隔离
- 静态与传输加密(写作时为 AES-256 与 TLS 1.2)
- 最小权限原则
无服务器仓库提供从 2X-Small 到 4X-Large 的多种规格,工作节点 VM 数量随规格而变:最小 1 台,最大可至 256 台。其核心优势是:快速扩容以提升性能、迅速缩容以降低低负载时的成本——因此非常适合 BI 与交互式分析。
与无服务器通用计算一样,无服务器仓库也由预热 VM 池创建。为确保安全与隔离,每个仓库都进行网络隔离与容器化,禁止跨租户网络访问。此外,数据访问经过严格控制:数据通过云后端的私网从客户云存储获取,不会暴露到公网。Unity Catalog 严格治理所有数据访问,并遵循最小权限原则:通过 Unity Catalog 下发的降权短期凭据向被授权用户授予对特定对象的访问。
在 Nexa,无服务器数据仓库因其即开即用与优于经典仓库的性能,被用于全部 BI 报表。图 4-18 展示了三位终端用户从无服务器计算池创建的数据仓库:用户 1 拥有两个中等规格仓库,用户 2 有一个大规格仓库,用户 3 有两个小型与一个中型仓库。每个仓库都在独立容器中部署,且禁止跨网络访问。
图 4-18. Databricks 中的无服务器数据仓库
无服务器模型服务(Serverless Model Serving)
Mosaic AI Model Serving 是 Databricks 的在线与批量模型托管能力:将 ML/AI 模型以 REST API 端点形式部署、治理并提供查询。底层使用无服务器基础设施来承载模型。Unity Catalog 治理模型工件与特征表的访问控制。与其他无服务器产品一致,模型在无服务器环境中隔离运行,数据访问由 Unity Catalog 控制。模型部署过程会从受 Unity Catalog 治理的云存储位置拉取模型工件;模型所需的外部库从公共仓库拉取,用以构建始终加密的模型镜像;随后从无服务器池分配计算资源安装镜像。
无服务器模型服务包含两部分:
- 从 Unity Catalog 与外部仓库生成并部署模型镜像;
- 提供模型端点以服务请求。
图 4-19 展示了第 1 部分:从 Unity Catalog 拉取模型工件并在无服务器计算上安装。
图 4-19. 模型服务的部署流程
工作原理如下:
- 用户向控制平面提交请求,部署已在 Unity Catalog 注册的模型。通过访问控制校验后,模型服务开始从 Unity Catalog 模型注册表下载所需工件。
- 镜像构建服务从用户存储层下载模型工件,并从 PyPI/Conda-Forge 等公共仓库拉取依赖库。
- 基于工件创建容器镜像,对其进行加密并注册到容器镜像仓库。
- 从无服务器池分配 VM,部署并配置该容器镜像以服务用户请求。
第二部分是将已部署模型以 REST API 端点对外提供,你可以在应用中进行批量或实时推理。图 4-20 展示了无服务器模型服务流程:模型在服务请求时可引用 Unity Catalog 的**特征库(feature store)**中的特征表。
图 4-20. 使用无服务器服务已部署的模型
无服务器 Databricks 应用(Serverless Databricks Apps)
Serverless Databricks Apps 允许你使用偏好的框架(如 Dash、Shiny、Gradio、Streamlit、React.js、Flask)构建自定义应用,并将其部署到 Databricks 管理的无服务器基础设施。以 Unity Catalog 治理为核心,你可以安全访问数据资产以支持多种用例。举例:Nexa 的数据科学家用 Databricks App 实现了**写回(writeback)**功能,以便对其 ML 模型的预测进行人工调整。你可用喜爱的 IDE(如 PyCharm、VS Code)开发,并接入 CI/CD 以便维护。Databricks 的自动化无服务器部署让你专注于构建应用,部署与基础设施运维由 Databricks 托管。
Databricks Apps 原生集成其它服务:用于治理的 Unity Catalog、用于执行查询的 Databricks 数据仓库、用于执行 Spark 工作负载的通用计算、用于推理的无服务器模型服务等。图 4-21 展示了在 Databricks 中基于无服务器基础设施部署应用的流程:每个应用在部署时都会分配一个服务主体(service principal) ,管理员通过该主体控制对其它资源的访问;任何数据访问都会被 Unity Catalog 的权限模型审计与治理。
图 4-21. 无服务器 Databricks 应用的部署
无服务器 Lakeflow Declarative Pipelines
Lakeflow Declarative Pipelines 是用于构建数据处理管道的声明式 ETL 框架(支持 Python 与 SQL)。它创建流式表(streaming tables)与物化视图(materialized views)来持久化处理结果(Delta 文件格式)。框架内置诸多能力:自动推断依赖、基于 expectations 定义数据质量规则、编排与错误处理等。Lakeflow Declarative Pipelines 同样可运行在无服务器计算上,提供即时计算以满足你的数据处理时效要求。从架构上看,它采用 Unity Catalog 的标准/共享访问模式计算,与 Databricks 的无服务器通用计算使用相同架构。
小结
“如果我能更快地访问服务器,我的电脑就不需要硬盘……背着这些不联网的电脑四处走简直是拜占庭式的累赘。”
—— Steve Jobs
Unity Catalog 中的计算主题庞大而复杂,足以写成另一本书。本章给出简明综述:我们梳理了当前 Databricks 产品的架构,为理解 Unity Catalog 下的计算打下基础。无服务器计算是数据处理的未来——通过消除基础设施运维负担,你可以专注于真正重要的事:推动增长。Unity Catalog 在这一愿景中扮演关键角色:为 Databricks 平台上的所有对象与工具提供统一治理。有了这块地基,你就能构建将业务继续向前推进的解决方案,而不是被基础设施管理所拖累。
第 5 章将讲解如何在 Unity Catalog 中建模访问控制与权限,并基于 Nexa 的实现示例提供一套可落地的访问控制模型。