Azure-数据工程权威指南-全-
Azure 数据工程权威指南(全)
一、工具和先决条件
本章将通过让你掌握传统的微软商业智能(BI)栈,涵盖一些 Azure 数据工程入门的关键技巧。本章将帮助您了解 Azure 的现代企业数据和分析平台、各种大数据选项和性能调整建议,以及 Azure 数据工程师助理认证的基本要求。最后,这一章将涵盖扩展你的其他 Azure 专业知识的价值,以解决 Azure 数据解决方案的商业价值,并向你介绍通过 Azure Portal 开始 Azure 数据工程的选项。这一章将以对本书将涉及的 Azure 服务以及未涉及的 Azure 服务的介绍结束。
掌握传统的微软商业智能堆栈
Azure 的许多数据平台工具都源于传统的微软 SQL Server BI 平台。例如,Azure Data Factory(ADF)的映射数据流(MDF)很像 SQL Server Integration Services(SSIS),而 Azure Analysis Services 则植根于 SQL Server Analysis Services (SSAS)。虽然 Azure 有许多微软传统 BI 堆栈中不常见的复杂性,但对 SSIS、SSRS、SSAS、T-SQL、C#、数据仓库等的深刻理解将有助于更好地理解 Azure 的数据服务。许多组织都有多年使用传统微软 BI 堆栈的相似历史,可能会寻找 Azure 数据工程师来帮助开拓他们进入现代企业数据和分析平台的旅程。通过对这些组织目前拥有的传统工具的了解和经验,您将能够很好地适应环境,并展示对传统 Microsoft BI 堆栈以及数据仓库概念的掌握。例如,了解如何设计和实现将数据从内部 SQL 数据库增量同步到 Azure Data Lake Storage gen 2(ADLS gen 2)的过程是许多组织正在寻求的技能,也是本书在未来章节中涉及的主题。
有许多在线资源和书籍可以帮助您掌握传统的 Microsoft BI 技能。例如,Ralph Kimball 的 数据仓库工具包 提供了维度建模的权威指南。还有许多其他学习微软商务智能的在线资源,从付费视频课程到免费的 YouTube 教程,例如来自 WiseOwlTutorials 、 TechBrothersIT 等等。图 1-1 描绘了传统微软 BI 数据架构的典型端到端流程。
图 1-1
在微软商务智能平台中使用 SSIS、SSAS 和 SSRS
了解 Azure 的现代企业数据和分析平台
虽然微软 Azure 拥有大量的资源,但现代企业数据和分析平台中最常见的组件在图 1-2 中列出。作为一名 Azure 数据工程师,能够设计和实现一个端到端的解决方案是至关重要的,这个解决方案遵循这个架构过程或它的定制变体,同时考虑安全性、高可用性等等。理解多种数据存储和数据集成选项之间的差异和相似之处也很重要。
图 1-2
现代 Azure 数据架构平台
在下一章中,我们将讨论如何在 Azure Data Factory、SQL Server Integration Services(SSIS)和 Azure Databricks 之间进行选择,以了解如何根据特定的用例及场景为工作选择正确的 ETL(提取-加载-转换)工具,并帮助您选择最适合工作的工具。了解何时选择 Azure Synapse 分析数据仓库(DW)还是 Azure SQL 数据库(ASQLDB)也是一种很好的做法。Melissa Coates 的以下文章详细讨论了这些不同的选项:
" Azure SQL 数据仓库是一个很好的选择吗?"( www.bluegranite.com/blog/is-azure-sql-data-warehouse-a-good-fit-updated
最后,对新的和现有的 Azure 数据资源的最近趋势、功能更新、可用性版本等有很好的理解,只会帮助你在构建更多 Azure 数据工程解决方案时做出更有教养、更有经验、更深思熟虑的决策。 Azure 更新(https://azure.microsoft.com/en-us/updates/
)是找到这些更新的好地方,你可以过滤产品类别到数据工程特定的资源。还有许多其他免费的学习资源,从文章到视频教程,都有助于了解 Azure 数据平台的最新动态。
了解如何使用 Azure 管理大数据
有许多数据存储选项可用,鉴于 MPP(大规模并行处理的缩写)和 Spark 之间的相似性,客户经常会问如何选择和决定一个何时适合另一个。
在 20 世纪 90 年代引入 MPP 之前,自 20 世纪 70 年代以来,分析数据库市场一直由 SMP 架构主导。SMP 在规模、可扩展性、工作负载管理、弹性和可用性方面存在缺陷。
MPP 架构解决了 SMP 在性能、可伸缩性、高可用性和读/写吞吐量方面的许多缺点。
然而,MPP 有与成本相关的缺点;它对数据分发有着迫切的需求,添加新节点和重新分发数据需要停机时间,按需扩展计算资源以满足实时处理需求的能力有限,并且由于将存储与计算隔离的限制,有可能出现容量过剩。
Spark 中的 RDD 类似于 MPP 中的分布式表,因为许多 RDD 操作都有等效的 MPP 操作。然而,RDD 确实为实时处理需求提供了更好的选择,并且能够纵向扩展节点以进行批处理,同时还能独立于计算经济高效地扩展存储(数据湖)。此外,对于高度非结构化的数据处理(文本、图像、视频等),推荐使用 MPP。此外,它还提供了大规模高级分析(人工智能、ML[机器学习]、文本/情感分析等)的能力。
Spark 和 MPP 都有很好的互补性,两者之间的选择取决于用例。Spark 非常适合大数据工程、ETL、AI/ML、实时数据处理和非报告/非查询用例,而 MPP 非常适合需要大量查询和性能功能的大数据报告和 BI 分析平台,因为它基于传统的 RDBMS,并带来了 SQL Server 的最佳功能,如自动查询调优、数据洗牌、分析平台管理的简便性,甚至基于主键的数据分布等等。
虽然 Spark 非常适合大数据处理,但是小文件会导致查询性能下降。此外,Spark 中缺乏数据重组会导致性能问题。由于 Spark 是为大数据批处理而设计的,所以当从报告仪表板查询数据时,它的性能也可能很差。
Azure Synapse Analytics 中的 Apache Spark 试图通过将 Spark 和 MPP 的优势结合到一个统一的分析平台中,来弥合 MPP 和 Spark 之间的鸿沟。
随着围绕大数据的大肆宣传,以及 Azure 中可用的多种大数据产品和资源,大数据主题对许多组织来说变得越来越重要。作为一名 Azure 数据工程师,这些组织将把你视为他们在大数据领域的常驻专家。很好地理解以下内容将是关键:
-
大数据架构
-
调整 ADF 复制活动的性能和可伸缩性
了解对数据工程师助理的基本要求
有这么多的微软 Azure 认证可供有志成为 Azure 专家的人使用,很明显关于 Azure 还有很多东西要学。数据工程师助理认证路径与 Azure 数据工程师最相关,最初包括通过两个考试,如图 1-3 所示:DP-200(实施 Azure 数据解决方案)和 DP-201(设计 Azure 数据解决方案)。
图 1-3
原始 Azure 数据工程师助理认证考试要求
获得数据工程师助理认证的学员通常要花大约 80 个小时来准备考试,同时有 3 个小时来完成每项考试。微软提供在线(免费)和教师指导的培训项目来准备这些考试。然后可以在线安排考试,并在远程或现场考试中心进行。完成这个认证将有助于获得 Azure 数据工程领域的基础知识。此外,对于那些为微软合作伙伴工作的人来说,成本可以完全报销,甚至可能包括通过考试的奖金,以及成为微软认证 Azure 数据工程师助理的荣耀。
Note
微软最近计划用一个考试 DP-203 取代考试 DP-200 和 DP-201,因为他们正在努力淘汰原来的考试。
图 1-4 展示了微软对 Azure 数据工程师的学习路径,包括使用 Azure 数据资源设计和实现数据的管理、监控、安全和隐私。
图 1-4
Azure 数据工程师的学习路径
跨 Azure 专业扩展您的知识
虽然 Azure 数据工程师角色涵盖了很多内容,但 Azure 中还有许多其他专业,包括 DevOps、安全、AI、数据科学、Azure 管理、数据库管理等等。虽然拥有跨这些领域的专业化很好,但获取这个知识库可能需要时间,并且它将有助于对 DevOps CI/CD、安全性、基础架构作为代码最佳实践、订阅和计费管理等有一个基本的了解,以及它如何与 Azure 中的数据工程相关联,以从角色基础之外的整体角度来拥抱 Azure。图 1-5 列出了其他可用的相关 Azure 认证及其相应的考试。
图 1-5
其他相关 Azure 认证列表
有了免费的在线视频教程,以及微软丰富的知识库文档,了解端到端架构流程以及它与连接性、安全性、基础设施代码、Azure 管理、DevOps CI/CD 以及计费和成本管理的关系,将有助于增强您对 Azure 的整体理解,帮助您的组织和团队宣传 Azure 数据工程并引领他们的云计算之旅。图 1-6 展示了一个包含多个组件的图,以及从架构的角度来看这些组件是如何联系在一起的。在本书的后续章节中,我们将讨论 DevOps CI/CD 的其他主题。
图 1-6
使用 DevOps CI/CD 的 Azure 数据架构的高级图表
能够解决 Azure 数据平台的商业价值
Azure 数据工程师支持并挑战组织大规模接受数字化转型。通常,Azure 数据工程师会参与到与组织中 C 级高管的对话中,并可能被要求参与涵盖成本、安全性以及 Azure 解决方案如何为组织带来真正商业价值的业务需求文档。能够谈论 Azure 数据和人工智能数字化转型解决方案的商业价值对于许多组织来说是一项宝贵的资产。图 1-7 展示了一些影响云商业价值的因素。
图 1-7
云的商业价值
微软有一门五小时(八个模块)的课程,涵盖了如何“学习微软 Azure 的商业价值” ( https://docs.microsoft.com/en-us/learn/paths/learn-business-value-of-azure/
)。此外,为了全面了解如何监控和控制你的 Azure 支出以及优化 Azure 资源的使用,微软提供了以下课程:用 Azure 成本管理+计费来控制 Azure 支出和管理账单 ( https://docs.microsoft.com/en-us/learn/paths/control-spending-manage-bills/
)。
通过 Azure 门户获得 Azure 数据工程实践
获得 Azure 数据工程实践的最佳方式之一是通过 Azure Portal 探索和创建这些资源。为了快速上手 Azure,您可以在 Azure Portal 中创建一个免费试用帐号(https://azure.microsoft.com/en-us/free/
),如图 1-8 所示。本书后续章节中的演示、练习和教程都是实践性的,所以如果你能够按照自己的叙述进行,这可能会补充你的学习经验。如果你没有 Azure 门户帐户,那么这本书作为 Azure 数据工程的权威指南仍然会有所帮助。
图 1-8
立即创建您的 Azure 免费帐户
本书涵盖的 Azure 服务
微软的 Azure 云平台有超过 6000 种服务,并且还在增加。本书旨在探索和深入研究这些资源中特定于数据提取、转换和摄取、开发运维、高级分析和治理的功能。本节将描述本书中涵盖的 Azure 数据服务,以及本书中如何使用这些服务的一些上下文。
数据湖存储第二代
Azure Data Lake Storage Gen2 是一组专用于大数据分析的功能,构建于 Azure Blob Storage 之上。Data Lake Storage Gen2 的一个基本部分是向 Blob 存储添加了一个层次名称空间。分层命名空间将对象/文件组织到目录的层次结构中,以实现高效的数据访问。在第三章中,我将详细讨论如何有效地设计 Azure Data Lake Storage Gen2 账户(ADLS Gen2)。在随后的许多章节中,您将通过 ETL 演示和练习更加熟悉 ADLS Gen2,了解它如何在数据接收和转换管道中用作源和接收器。
数据工厂
Azure Data Factory (ADF)是 Azure 的云 ETL 服务,用于横向扩展的无服务器数据集成和数据转换。它提供了一个无代码的用户界面,用于直观的创作和单一控制台监控和管理。您还可以将现有的 SSIS 包转移到 Azure,并在 ADF 中完全兼容地运行它们。本书的大部分章节,从第四章到第十五章,涵盖了围绕 Azure Data Factory 及其强大功能的深入主题。
摄取和加载
作为接收和加载过程的一部分,Data Factory 支持 90 多个源和接收器。在后续章节中,您将学习如何在 ADF 中创建管道、数据集、链接服务和活动:
-
管道:共同执行任务的活动的逻辑分组。
-
活动:定义对数据执行的操作(例如,复制数据活动、ForEach 循环活动等。)
-
数据集:数据的命名视图,它简单地指向或引用您希望在管道内的活动中使用的数据
-
链接服务:很像连接字符串,它定义了数据工厂连接到外部资源所需的连接信息
在 ADF 中,集成运行时(IRs)是用于提供数据集成功能(如数据流和数据移动)的计算基础设施。ADF 有以下三种 IR 类型:
-
Azure integration runtime****:底层基础设施的所有修补、扩展和维护都由微软管理,IR 只能访问公共网络中的数据存储和服务。
-
自托管集成运行时 : 基础设施和硬件由您管理,您需要解决所有的修补、扩展和维护问题。IR 可以访问公共和私有网络中的资源。
-
运行 SSIS 引擎的虚拟机允许你本地执行 SSIS 软件包。所有的修补、扩展和维护都由微软管理。IR 可以访问公共和私有网络中的资源。
为转换和聚合映射数据流
映射数据流是 Azure Data Factory 中可视化设计的数据转换。数据流允许数据工程师在不编写代码的情况下开发数据转换逻辑。产生的数据流作为 Azure 数据工厂管道中的活动执行,这些管道使用横向扩展的 Apache Spark 集群。在第 11–15 章中,我们将探讨使用 SCD Type I、大数据湖聚合、增量插入和 Delta Lake 进行数据仓库 ETL 时映射数据流的一些功能。关于映射数据流的功能,还有许多其他用例没有在本书中介绍(例如,动态地将大文件分割成多个小文件、管理小文件问题、解析转换等等),我鼓励您研究映射数据流的许多其他功能。
此外,可以通过 ADF 的常规复制数据活动中的存储过程活动来转换数据。
在映射数据流时,有三种不同的集群类型可用——通用、内存优化和计算优化:
-
通用:当您打算平衡性能和成本时,请使用默认的通用集群。该集群非常适合大多数数据流工作负载。
-
内存优化:如果您的数据流有许多连接和查找,请使用成本更高的每核内存优化集群,因为它们可以在内存中存储更多数据,并将您可能遇到的任何内存不足错误降至最低。如果在执行数据流时遇到任何内存不足的错误,请切换到内存优化的 Azure IR 配置。
-
计算优化:针对非内存密集型数据转换,如过滤数据或添加派生列,使用每内核价格更便宜的计算优化集群。
争论不休的数据流
Data Factory 中的数据争论允许您在本地构建交互式 Power Query 混搭,然后在 ADF 管道中大规模执行这些混搭。这本书将不会涉及这个介绍部分之外的争论数据流的主题。
计划和监控
对于触发的管道,您可以在 Azure 数据工厂用户体验中计划和监控所有管道运行。此外,您可以创建警报并接收与失败、成功或自定义管道执行状态相关的文本和/或电子邮件。
ADF 限制
目前,ADF 有一些限制。这些限制包括以下内容:
-
无法将 ForEach 活动或 Switch 活动添加到 If 活动中。
-
无法嵌套 ForEach 循环、If 和 Switch 活动。
-
查找活动最多有 5,000 行,最大大小为 4 MB。
-
无法为模块化调度添加 CRON 功能。
其中一些限制要么在 ADF 产品团队未来增强的路线图上,要么有定制的解决方案和变通办法。例如,单一管道中缺乏模块化调度可以通过利用 Azure 函数、逻辑应用、Apache Airflow 等工具来弥补。确保您有一个具有许多管道的模块化设计,以解决其他限制,例如每个管道 40 个活动的限制。其他限制包括每个管道 100 个排队运行,每个 Azure 集成运行时区域的每个订阅 1000 个并发管道活动运行。
大数据
Azure Databricks 是一个针对微软 Azure 云服务平台优化的数据分析平台。在本书的整个过程中,我们将探索 Databricks,除了它围绕图形分析(第二十一章)和机器学习(第二十三章)等用例的高级分析功能之外,它还是一种数据摄取和转换工具。此外,第十七章将讨论如何通过 Spark compute 使用 Databricks 进行实时物联网分析。
Synapse 分析
Azure Synapse Analytics 与 Databricks 非常相似,是一种企业服务,可以加快跨数据仓库和大数据系统的洞察速度。Azure Synapse 汇集了企业数据仓库中使用的最佳 SQL 技术、用于大数据的 Spark 技术、用于数据集成和 ETL/ELT 的管道,以及与 Power BI、Cosmos DB 和 Azure ML 等其他 Azure 服务的深度集成。在使用 Azure 数据工厂的 ELT 的后续章节中,我们将探讨如何动态加载 Azure Synapse Analytics DW。此外,在第二十二章中,我们将探讨如何开始使用 Azure Synapse 分析工作区示例来提升自助服务和高级分析功能。
对于客户来说,在 Synapse Analytics 和 Databricks 之间做出选择可能是一个挑战。尽管 Databricks 作为 Azure 中基于 Apache Spark 的分布式计算的行业标准已经达到了成熟和受尊重的水平,但 Synapse 正在缓慢但肯定地赶上成为一个统一的数据和分析平台,与其他 Azure 服务的集成可能比 Databricks 更紧密。随着 Synapse Analytics 的功能和产品不断成熟,许多在 Azure 中开始新项目的客户对探索其功能非常感兴趣。
数码宝贝/CD
CI/CD 管道用于自动化持续集成和持续部署的过程。管道通过构建、测试、合并和部署等阶段促进软件交付过程。Azure DevOps Server 是一款微软产品,提供版本控制、报告、需求管理、项目管理、自动化构建、测试和发布管理功能。它涵盖了整个应用生命周期,并支持 CI/CD 等开发运维功能。在第十九章中,我们将探索如何使用 DevOps CI/CD 将数据工厂部署到多个环境,在第二十章中,我们将探索如何使用 DevOps CI/CD 管道将 Azure SQL 数据库部署到多个环境。
物联网中心
物联网中心是一种托管在云中的平台即服务(PaaS)托管服务,充当物联网应用与其管理的设备之间双向通信的中央消息中心。在第十六章中,我们将建立一个物联网中心,它将从设备模拟器收集事件,以促进对即将到来的事件的实时分析和洞察。
在选择物联网中心之前,了解各种物联网中心选项之间的功能差异,并将它们与活动中心进行比较。表 1-1 列出了活动中心和物联网中心选项的功能。
表 1-1
物联网中心与活动中心
|物联网能力
|
物联网中心标准层
|
物联网中心基础层
|
活动中心
|
| --- | --- | --- | --- |
| 设备到云的消息传递 | 是 | 是 | 是 |
| 协议:HTTPS,AMQP,AMQP | 是 | 是 | 是 |
| 协议:MQTT,MQTT over webSockets | 是 | 是 | |
| 每个设备的身份 | 是 | 是 | |
| 从设备上传文件 | 是 | 是 | |
| 设备供应服务 | 是 | 是 | |
| 云到设备的消息传递 | 是 | | |
| 设备配对和设备管理 | 是 | | |
| 设备流(预览) | 是 | | |
| 物联网边缘 | 是 | | |
流分析
Azure Stream Analytics 是一个实时分析和复杂事件处理引擎,旨在同时分析和处理来自多个来源的大量快速流数据。模式和关系可以在从包括设备、传感器、点击流、社交媒体源和应用在内的许多输入源提取的信息中识别。在第十六章中,我们将探索特定于异常检测的流分析的实际使用案例,该案例可用于检测欺诈。
在时间流场景中,对时间窗口中包含的数据执行操作是一种常见的模式。流分析具有对窗口功能的本机支持,使开发人员能够以最少的工作量创作复杂的流处理作业。
Stream Analytics 中提供了以下窗口函数:
-
滚动窗口允许你将数据分割成不同的时间段(每 10 秒计算每个时区的推文数量)。
-
会话窗口允许对在相似时间到达的流媒体事件进行分组,并且不过滤任何数据(对彼此在 5 分钟内发生的推文进行计数)。
-
跳转窗口向后看以确定事件何时发生(每 5 秒,计算最近 10 秒内的推文数量)。
-
滑动窗口在事件发生时产生输出(过去 10 秒内单个主题的 tweets 计数)。
-
快照窗口对具有相同时间戳的事件进行分组。您可以通过添加系统来应用快照窗口。时间戳()添加到 GROUP BY 子句中。
商业智能
Power BI 是微软 Power 平台的一部分,是一个提供交互式可视化和商业智能功能的报告平台,它使最终用户能够创建自己的报告和仪表板。在第十六章中,我们将探讨如何构建一个 Power BI 仪表盘,用于实时监控和分析来自设备模拟器的传入物联网事件。
考虑电源 BI 时,有几个选项可供选择。这些选项包括高级版和专业版,它们都有自己的功能和价位。表 1-2 显示了 Power BI Pro 和 Premium 之间的并排比较,有助于根据您的报告需求选择合适的功能。
表 1-2
超级商务智能专业版与高级版
|特征
|
Power BI Pro
|
Power BI 高级版
|
Power BI 高级版
|
| --- | --- | --- | --- |
|
每个用户
|
单位容量
|
| --- | --- |
| 协作和分析 |
| 移动应用访问 | 是 | 是 | 是 |
| 发布报告以共享和协作 | 是 | 是 | |
| 分页(RDL)报表 | | 是 | 是 |
| 无需每用户许可证即可使用内容 | | | 是 |
| 使用 Power BI 报告服务器进行内部报告 | | | 是 |
| 数据准备、建模和可视化 |
| 模型大小限制 | 1 GB | 100 GB | 400 GB |
| 刷新率 | 8/天 | 48/天 | 48/天 |
| 连接到 100 多个数据源 | 是 | 是 | 是 |
| 使用 Power BI Desktop 创建报告和可视化效果 | 是 | 是 | 是 |
| 嵌入 API 和控件 | 是 | 是 | 是 |
| ai 视觉 | 是 | 是 | 是 |
| 高级人工智能(文本分析、图像检测、自动机器学习) | | 是 | 是 |
| XMLA 端点读/写连接 | | 是 | 是 |
| 数据流(直接查询、链接和计算实体、增强的计算引擎) | | 是 | 是 |
| 分析 Azure 数据湖存储中存储的数据 | | 是 | 是 |
| 治理和行政 |
| 数据安全和加密 | 是 | 是 | 是 |
| 内容创建、消费和发布的指标 | 是 | 是 | 是 |
| 应用生命周期管理 | | 是 | 是 |
| 多地区部署管理 | | | 是 |
| 自带钥匙(BYOK) | | | 是 |
| 自动扩展附件可用性(预览) | | | 是 |
| 最大存储量 | 10gb/用户 | 100 TB | 100 TB |
| 持续集成和部署 |
| 部署管道(包括分页报告管理) | | 是 | 是 |
范围
azure without 是一个统一的数据治理服务,通过自动数据发现、敏感数据分类和端到端数据沿袭,创建一个全面、最新的数据环境图,帮助您轻松管理和治理数据。它使数据消费者能够找到有价值、值得信赖的数据,并可以与本书中涵盖的许多服务集成,包括 Synapse Analytics、SQL 数据库、数据工厂等。在第二十四章中,我们将通过一个详细的练习来探索一个实现权限的实际例子。
雪花
雪花是一家云提供商,提供比传统产品更快、更易用、更灵活的数据存储、处理和分析解决方案。雪花数据平台不是建立在任何现有的数据库技术或“大数据”软件平台上,如 Hadoop。相反,雪花结合了一个全新的 SQL 查询引擎和一个为云设计的创新架构。雪花围绕数据共享、数据仓库和数据应用提供了一些非常好的功能。在第十章中,您将了解更多关于如何使用数据工厂和数据块动态加载雪花 DW 的信息。
SQL 数据库
Azure SQL Database 是一种云计算数据库服务(数据库即服务),由微软 Azure 平台提供,有助于在云中托管和使用关系型 SQL 数据库,而无需安装任何硬件或软件。我们将在本书的许多章节中使用标准 Azure SQL 数据库作为源、接收器和元数据驱动的控制数据库。
购买模型(SQL DTU 与 vCore 数据库)
Azure 中有大量的 SQL 数据库选项,包括 DTU 和 vCore。DTU 和 vCore 是 Azure SQL 的两种不同购买模式,包括计算、内存、存储和 I/O 的变化。Azure Pricing Calculator 可以帮助将成本和功能与适当的 SQL 数据库解决方案相匹配。
DTU 单元是 CPU、内存和读写操作的组合,并且可以在需要更多功率时增加。如果您有一个预配置的资源配置,其中资源消耗在 CPU、内存和 I/O 之间保持平衡,这将是一个很好的解决方案。一旦达到分配资源的限制并遇到节流,您可以增加保留的 dtu 数量,这将导致性能下降或超时。
dtu 的缺点是不能灵活地只扩展特定的资源类型,比如内存或 CPU。正因为如此,你最终可能会为不需要或不使用的额外资源付费。
vCore 模型允许您独立扩展每个资源(CPU、内存、IO)。您可以根据数据库需要多少 GB 的存储空间来扩大和缩小存储空间,还可以扩展核心(vCores)的数量。缺点是不能独立控制内存的大小。此外,需要注意的是,vCore 无服务器计算资源的价格是调配计算资源价格的两倍,因此持续的高负载在无服务器中的成本要高于调配计算资源的成本。vCore 可以使用您在本地环境中获得的 SQL Server 许可证。
部署模型
Azure SQL 数据库有两种可用的部署模型:
-
单一数据库代表一个完全管理的、隔离的数据库。如果您有需要单一可靠数据源的现代云应用和微服务,您可能会使用此选项。单个数据库类似于 SQL Server 数据库引擎中的包含的数据库。
-
弹性池是单个数据库的集合,具有一组共享的资源,如 CPU 或内存,单个数据库可以移入和移出弹性池。
服务等级
Azure SQL 数据库有三个可用的服务层:
-
通用/标准 服务层专为常见工作负载而设计。它提供以预算为导向的平衡计算和存储选项。
-
关键业务/高级 服务层专为具有高事务率和最低 I/O 延迟的 OLTP 应用而设计。它通过使用几个独立的副本来提供最高的故障恢复能力。
-
超大规模 服务层专为大数据 OLTP 数据库以及适度扩展存储和计算的能力而设计。
宇宙数据库(Cosmos DB)
Azure Cosmos DB 是一个完全托管的 NoSQL 数据库,用于现代应用开发。个位数毫秒级响应时间和自动即时可扩展性保证了任何规模的速度。通过由 SLA 支持的可用性和企业级安全性来确保业务连续性。在第十八章中,我们将在为 Cosmos DB 建立实时 Synapse 分析链接的背景下探索 Cosmos DB,以了解在 Cosmos DB 中对交易数据进行实时分析的能力。Azure Synapse Link for Azure Cosmos DB 是一种云原生混合事务和分析处理(HTAP)功能,使您能够对 Azure Cosmos DB 中的运营数据运行近实时分析。Azure Synapse Link 在 Azure Cosmos DB 和 Azure Synapse Analytics 之间创建了紧密的无缝集成。
在决定何时为您的数据解决方案选择 SQL 或 NoSQL 数据库时,请确保考虑以下比较因素,如表 1-3 所示。
表 1-3
SQL vs. NoSQL
| |结构化查询语言
|
NoSQL
|
| --- | --- | --- |
| 定义 | SQL 数据库主要称为 RDBMSs 或关系数据库。 | NoSQL 数据库主要被称为非关系数据库或分布式数据库。 |
| 设计用于 | 传统的 RDBMS 使用 SQL 语法和查询来分析和获取数据以获得进一步的见解。它们用于 OLAP 系统。 | NoSQL 数据库系统由多种数据库技术组成。这些数据库是应现代应用开发的需求而开发的。 |
| 查询语言 | 结构化查询语言 | 没有声明性查询语言 |
| 类型 | SQL 数据库是基于表的数据库。 | NoSQL 数据库可以是基于文档、键值对、图形数据库。 |
| 计划 | SQL 数据库有一个预定义的模式。 | NoSQL 数据库对非结构化数据使用动态模式。 |
| 扩展能力 | SQL 数据库是垂直可伸缩的。 | NoSQL 数据库是水平可伸缩的。 |
| 例子 | Oracle、Postgres 和 MS SQL。 | 蒙戈布、里兹、尼欧 4j、卡珊德拉、巴舍。 |
| 最适合 | 复杂的查询密集型环境的理想选择。 | 它不太适合复杂的查询。 |
| 分级数据存储 | SQL 数据库不适合分层数据存储。 | 更适合分层数据存储,因为它支持键值对方法。 |
| 变化 | 一种稍有变化的类型。 | 许多不同的类型,包括键值存储、文档数据库和图形数据库。 |
| 开发年份 | 它是在 20 世纪 70 年代开发的,用来处理平面文件存储的问题。 | 开发于 21 世纪后期,旨在克服 SQL 数据库的问题和限制。 |
| 一致性 | 它应该被配置为具有很强的一致性。 | 这取决于 DBMS,因为有些 DBMS 提供很强的一致性,如 MongoDB,而有些 DBMS 只提供最终的一致性,如 Cassandra。 |
| 最适用于 | RDBMS 是解决 ACID 问题的正确选择。 | NoSQL 最适合用于解决数据可用性问题。 |
| 重要 | 应该在数据有效性超级重要的时候使用。 | 当快速数据比正确数据更重要时使用。 |
| 最佳选择 | 当您需要支持动态查询时。 | 当您需要根据不断变化的需求进行扩展时使用。 |
| 酸与碱模型 | ACID(原子性、一致性、隔离性和持久性)是 RDBMS 的标准。 | BASE(基本可用、软状态、最终一致)是许多 NoSQL 系统的模型。 |
Cosmos DB 中提供了以下 API:
-
SQL: 为熟悉 SQL 查询的数据用户提供功能。尽管数据是以 JSON 格式存储的,但是可以使用类似 SQL 的查询很容易地对其进行查询。
-
MongoDB : 现有的 MongoDB 实例可以毫不费力地迁移到 Azure Cosmos DB。
-
Gremlin : 可用于存储和执行图形数据操作,支持图形建模和遍历的原生能力。
-
Cassandra****:为 Apache Cassandra 创建的应用的专用数据存储,用户可以通过 CQL (Cassandra 查询语言)与数据进行交互。
-
表:可以由本地准备的应用使用,以便与 Azure 存储表紧密协作。
未涵盖相关 Azure 服务
有大量相关的 Azure 服务不会在本书中涉及。我鼓励你对这些服务有一个基本的了解,因为它们经常是现代 Azure 数据平台架构堆栈的一部分。本节将对其中一些服务进行基本介绍。
分析服务
Azure Analysis Services 是一个完全托管的平台即服务,在云中提供企业级数据模型。使用高级混搭和建模功能来组合来自多个数据源的数据,定义指标,并在单个可信的表格语义数据模型中保护您的数据。Analysis Services 与 Logic 应用集成良好,也可以与 Azure 数据工厂和 Azure 函数集成,用于模型的增量处理。
在考虑分析服务时,可以将它与 Power BI Premium 进行比较,因为 Power BI Premium 有望提供一系列功能。
目前,在 Power BI Premium 和 Analysis Services 之间进行选择时,可以使用表 1-4 中的以下功能考虑因素来比较利弊。
表 1-4
Power BI Premium 与 Azure 分析服务
| |Power BI 高级版
|
Azure 分析服务
|
| --- | --- | --- |
| 无限强大的商务智能内容查看 | 是 | 不 |
| 分页报告 | 是 | 不 |
| 数据流 | 是 | 不 |
| 人工智能工作量 | 是 | 不 |
| 多模式内存管理 | 是 | 不 |
| 预聚合表 | 是 | 不 |
| 复合模型 | 是 | 不 |
| 自动增量刷新 | 是 | 不 |
| 大型数据集 | 是 | 是 |
| 第三方应用支持 | 是 | 是 |
| 自带钥匙 | 是 | 不 |
| 向外扩展 | 还没有 | 是 |
| 元数据翻译 | 还没有 | 是 |
| 对象级安全性 | 还没有 | 是 |
| 观点 | 还没有 | 是 |
认知服务
认知服务通过 API 将 AI 带给开发者,并提供各种服务,为 AI 提供看、听、说、搜索、理解的能力,并将决策加速到应用中。所有技能水平的开发人员和那些不具备机器学习专业知识的开发人员都可以轻松地将人工智能功能添加到他们的应用中。
当前可用的认知服务包括以下内容。
决定
语言
-
沉浸式阅读器 : 利用视听提示帮助理解文本。
-
语言理解 : 在 app 中构建自然语言理解。
-
QnA Maker:在数据上创建对话式问答层。
-
文本分析 : 检测情感、关键短语和命名实体。
-
翻译器 : 检测并翻译超过 90 种支持的语言。
演讲
视力
-
计算机视觉 : 分析图像和视频中的内容。
-
自定义视觉 : 自定义图像识别,满足您的业务需求。
-
人脸 : 检测和识别图像中的人和情感。
-
表单识别器 : 从文档中提取文本、键值对、表格。
-
视频索引器 : 分析视频的视听,索引内容。
搜索
- 搜索****:Azure Cognitive Search 是一项云搜索服务,为开发人员提供 API 和工具,用于在 web、移动和企业应用中构建丰富的私有异构内容搜索体验。
天蓝色机器学习
Azure 机器学习是一项提供完整数据科学平台的服务。它支持代码优先和低代码体验。Azure Machine Learning Studio 是 Azure Machine Learning 中的一个 web 门户,包含用于项目创作和资产管理的低代码和无代码选项。Azure 机器学习与 Databricks 和 Data Factory 等其他 Azure 服务集成得很好。
三种主要的机器学习技术包括以下内容。
监督学习
算法基于您提供的一组带标签的示例进行预测。当您知道结果应该是什么样子时,这种技术很有用。
无监督学习
算法通过组织数据或描述其结构来为您标记数据集。当您不知道结果应该是什么样时,这种技术很有用。
强化学习
算法从结果中学习,并决定下一步采取什么行动。在每一个动作之后,算法接收反馈,帮助它确定它做出的选择是正确的、中立的还是不正确的。对于需要在没有人类指导的情况下做出许多小决定的自动化系统来说,这是一种很好的技术。
班长
Azure Monitor 通过允许您监控基础架构和网络,帮助您最大限度地提高应用的性能和可用性,并在几秒钟内主动识别问题。
日志分析
通过日志分析,您可以从 Azure Monitor 日志收集的数据中编辑和运行日志查询,并交互式地分析它们的结果。您可以使用日志分析查询来检索符合特定标准的记录,确定趋势,分析模式,并提供对数据的各种见解。
活动中心
Event Hubs 是一个大数据流平台和事件摄取服务。它每秒可以接收和处理数百万个事件。发送到事件中心的数据可以通过使用任何实时分析提供程序或批处理/存储适配器进行转换和存储。
数据共享
Azure 数据共享使组织能够简单安全地与多个客户和合作伙伴共享数据。只需几次点击,您就可以提供新的数据共享帐户、添加数据集,并邀请您的客户和合作伙伴加入您的数据共享。数据提供者总是控制着他们共享的数据。值得注意的是,许多其他的多云平台(如 Snowflake)也提供了强大的数据共享机制和平台,这些机制和平台为被称为数据网格的现代架构模式做出了贡献。数据网格联合了领域数据所有者之间的数据所有权,这些所有者负责将他们的数据作为产品提供,同时还促进了不同位置的分布式数据之间的通信。
逻辑应用
Logic Apps 是一种云服务,当您需要跨企业或组织集成应用、数据、系统和服务时,它可以帮助您计划、自动化和协调任务、业务流程和工作流。
高级应用
Power Apps 是微软 Power 平台的一部分,它是一套应用、服务、连接器和数据平台,提供了一个快速的应用开发环境来构建满足您业务需求的定制应用。这些应用有两种风格:画布应用和模型驱动应用。
画布应用为您提供了一个空白画布,您可以在上面以任何形式拖放组件来设计用户界面。模型驱动的应用基于公共数据服务(CDS)中存储的底层数据,这是一个安全的基于云的存储空间,组织可以使用它来存储业务应用数据。Canvas 应用非常适合构建基于任务或基于角色的应用。另一方面,模型驱动的应用更适合创建端到端的解决方案。
应用服务
Azure App Service 是一个完全托管的 web 托管服务,用于构建 web 应用、移动后端和 RESTful APIs。
SQL 托管实例
SQL 托管实例是 Azure SQL 数据库的一个部署选项,提供了与最新的 SQL Server 本地(企业版)数据库引擎的接近 100%的兼容性,一个解决常见安全问题的本机虚拟网络(VNet) 实现,以及一个有利于本地 SQL Server 客户的业务模型。
数据盒子
Azure Data Box 可以让你以一种快速、廉价和可靠的方式将万亿字节的数据传入和传出 Azure。通过为您提供专有的数据盒存储设备,可以加速安全的数据传输。每个存储设备的最大可用存储容量为 80 TB,并通过区域运营商运输到您的数据中心。该设备有一个坚固的外壳,可以在传输过程中保护数据。
数据同步
Azure SQL 数据同步是一项服务,用于将 Azure SQL 数据库中的表复制到另一个 Azure SQL 数据库或本地数据库。数据可以单向或双向复制。
数据网关
网关作为一座桥梁,在内部数据源与您的逻辑应用、Power BI、Power 应用、Microsoft Flow 和 Analysis Services 之间提供快速数据传输和加密。
成本管理+计费
Azure 成本管理+计费帮助您了解您的 Azure 账单,管理您的计费帐户和订阅,监控和控制 Azure 支出,并优化资源使用。
数字双胞胎
Azure Digital Twins 是一个物联网(IoT)平台,使您能够创建真实世界的事物、地点、业务流程和人员的数字表示。获得洞察力,帮助您开发更好的产品、优化运营和成本,并创造突破性的客户体验。
移动的
Azure Mobile Services 为构建 Windows Store、Windows Phone、Apple iOS、Android 和 HTML/JavaScript 应用提供了可扩展的云后端。
建立关系网
Azure Networking 提供您需要的连接和规模,而不需要您构建或管理光纤。此外,它允许您使用 Azure App Gateway 管理应用的流量,使用 Azure WAF 进行保护,使用 Azure Front Door 定义和监控全局路由,以及使用 Azure Firewall 获得交钥匙防火墙功能。
安全
Azure Security Center 是一个统一的基础设施安全管理系统,它可以为您在云中的混合工作负载提供高级威胁保护,并加强您的数据中心的安全立场。
身份
Azure Active Directory (Azure AD)是微软基于云的身份和访问管理服务,它可以帮助您的员工登录和访问资源,如您公司网络和内部网的应用,以及您自己的组织开发的任何云应用。
忽必烈忽必烈忽必烈忽必烈忽必烈忽必烈忽必烈忽必烈忽必烈忽必烈
Azure Kubernetes Service (AKS)通过将运营开销卸载到 Azure,简化了在 Azure 中部署托管的 Kubernetes 集群。作为托管的 Kubernetes 服务,Azure 处理关键任务,如健康监控和维护。
功能
Azure Functions 是一种按需服务,为 Azure 提供无服务器计算,可用于构建 web APIs,响应数据库变化,处理物联网流,管理消息队列等。此外,函数可以从 Azure 数据工厂管道中调用并集成到其中。
HVR 实时数据复制
HVR for Azure 可用于将 Azure 数据与内部系统集成,以及云间集成和迁移,以及与 Azure 之间的零停机迁移,因为它提供了 Azure 中的实时异构数据复制,并允许您更快地移动大量数据,并以低延迟体验内部和云中的连续数据流。
摘要
在这一章中,我通过强调传统微软 BI 栈的重要性及其在 Azure 现代企业数据和分析平台中的重要作用,介绍了 Azure 数据工程入门技巧。我还介绍了关于性能调优建议的大数据选项的概念,以及 Azure 数据工程师助理认证的基本要求。此外,本章还介绍了在其他 Azure 专业领域扩展知识的价值,以解决 Azure 数据解决方案的商业价值,并向您介绍了通过 Azure Portal 开始 Azure 数据工程的选项。最后,本章向您介绍了本书将涉及的一些 Azure 资源,也讨论了本书将不会涉及的 Azure 资源。
二、数据工厂 vs. SSIS vs .DataBricks
基于来自微软不断增长的 Azure 数据工程和集成生态系统的许多数据集成产品,选择正确的 ELT 工具可能是困难的。从数据工程师到数据分析师的技术专业人员都对为工作选择正确的 ELT 工具感兴趣,并且在确定何时为他们的数据集成项目在 Azure Data Factory (ADF)、SQL Server Integration Services(SSIS)和 Azure Databricks 之间进行选择时,经常需要指导。
SSIS 和 ADF 都是健壮的 GUI 驱动的数据集成工具,设计用于 ELT 和 ETL 工作流、管道和操作,具有到多个源和汇的连接器。SSIS 开发托管在 SQL Server 数据工具中,而 ADF 开发是基于浏览器的体验;两者都有强大的调度和监控功能。借助 ADF 的映射数据流,通过聚合、派生列、模糊查找和其他类似于 SSIS 的可视化设计的数据转换来转换数据是一种允许数据工程师以无代码方式构建 ELT 的能力。ADF 的映射数据流和数据块都利用 Spark 集群来转换和处理 Azure 中的大数据和分析工作负载。本章旨在介绍 ADF、SSIS 和 Databricks 之间的相似之处和不同之处,并提供一些指导来帮助您确定如何在这些不同的数据集成服务之间进行选择。
选择正确的数据集成工具
当在 Azure Data Factory (ADF)和 SQL Server Integration Services(SSIS)之间为一个新项目做出选择时,了解您的组织是否有 Azure 足迹至关重要,如果有,您的数据集成项目能否在 Azure 中托管?如果答案是肯定的,那么 ADF 是这项工作的完美工具。另一方面,如果出于安全原因或因为已经存在 SSIS 生态系统,新项目必须在内部完成,那么 SSIS 是首选工具。通常,组织通过提升和转移场景获得将 SSIS 与 ADF 相结合的好处,在这些场景中,他们利用 ADF 的基于云的计算服务来调度、运行和执行 SSIS 包。
SSIS 是 SQL Server 的几个版本的一部分,价格从免费(Express 和 Developer editions)到每核约 14K 美元(Enterprise),SSIS 集成运行时节点在 Azure 上每小时 0.84 美元起。也就是说,当使用 SSIS 运行大数据工作负载时,从价格和性能的角度来看,数据量可能会成为一个问题,因为需要购买硬件并经常维护。
Azure Data Factory V2 公司的现收现付计划起价为每 1000 次协调运行 1 美元,每 1000 次自托管 IR 运行 1.5 美元。对于拥有数百个 SSIS 包的组织来说,ADF 将是一个很好的资源,他们不希望在 ADF 中重写这些包,但希望通过利用 Azure 来降低运营成本、提高高可用性和增加可伸缩性。对于这种情况,混合将 SSIS 工作负载转移到云将是理想的选择。
从数据速度的角度来看,除了计划批处理触发器之外,ADF 本身还支持基于事件和滚动窗口触发器,而 SSIS 本身只支持批处理,能够为接近实时的数据流构建自定义触发器。例如,为 SQL Server Integration Services 开发一个文件监视器任务将在处理传入文件之前自动检查它们的目录。
从数据多样性的角度来看,ADF 可以本机连接到 90 多个数据源,从 REST API 到 CRM 系统,再到复杂的 JSON 结构,而 SSIS 更适合结构化数据源,但可以很好地集成到 JSON、REST API 等的第三方或自定义 C#连接器。
从可编程性的角度来看,Azure Data Factory 没有原生编程 SDK,但通过 PowerShell 在没有任何第三方组件的情况下支持自动化,而 SSIS 有编程 SDK,以及通过 BIML 和各种其他第三方组件的自动化。图 2-1 列出了 SSIS 和 ADF 的各种异同。
图 2-1
SSIS 和澳大利亚国防军的能力
何时使用 Azure Data Factory、Azure Databricks 或同时使用两者
对于大数据项目,Data Factory 和 Databricks 都是基于 Azure 云的数据集成工具,在微软 Azure 的数据生态系统中可用,可以处理大数据、批量/流数据和结构化/非结构化数据。两者都有基于浏览器的界面和现收现付的定价方案。
ADF 的映射数据流使用横向扩展的 Apache Spark 集群,这与 Databricks 的底层架构类似,并且在大数据聚合和转换方面表现相似。值得注意的是,映射数据流目前不支持与本地数据源的连接。此外,ADF 的原始复制活动不使用 Spark 集群,而是自托管集成运行时,并允许连接到本地 SQL 服务器。基于这些连接到本地 SQL 服务器的选项,Databricks 确实具有连接到本地数据源的能力,并且可能在大数据工作负载上优于 ADF,因为它利用了 Spark 集群。
从速度的角度来看,ADF 和 Databricks 都支持批处理和流选项。ADF 本身不支持实时流功能,因此需要 Azure 流分析。Databricks 支持结构化流,这是一个 Apache Spark API,可以处理实时流分析工作负载。
从开发界面的角度来看,ADF 的拖放式 GUI 与 SSIS 非常相似,对于熟悉 SSIS 的无代码界面的开发人员来说,这有助于降低学习难度,并且易于使用。此外,Spark 计算环境中的集群类型、核心和节点可以通过 ADF activity GUI 进行管理,以提供更多处理能力来读取、写入和转换数据。
Databricks 确实需要致力于学习 Spark、Scala、Java、R 或 Python 来进行数据工程和数据科学相关的活动。对于传统的 MS SQL BI 开发人员来说,这相当于一个更高的学习曲线,他们已经在 SSIS ETL 过程中扎根了十多年。对于熟悉和熟悉 Databricks 编程语言的数据工程师和科学家来说,Databricks 提供了一种通过笔记本编写和管理代码的整洁和有组织的方法。
ADF 和 Databricks 之间最后也是最显著的区别与它们的主要用途有关。ADF 在许多方面与 SSIS 相似,主要用于 ETL/ELT、数据移动和编排,而 Databricks 可用于数据工程师、数据科学家等之间的实时数据流和协作,以及支持数据科学家设计和开发 AI 和机器学习模型。
例如,Databricks 的 MLflow 通过在可再现的环境中跟踪多个用户之间的实验运行来简化机器学习生命周期,并管理模型到生产的部署。此外,Databricks 支持各种第三方机器学习工具。在随后的章节中,我们将详细介绍 MLflow 的功能以及 Databricks 的各种其他高级特性。
一旦开发了这些数据块模型,就可以将它们集成到 ADF 的数据块活动中,并链接到复杂的 ADF ETL/ELT 管道中,再加上将参数从 ADF 传递到数据块的无缝体验。此外,可以通过 ADF 安排和监控 Databricks 型号。我们将在以后的章节中探讨这些不同的组合管道和参数传递能力。图 2-2 列出了 Databricks 和 ADF 的各种异同。
图 2-2
数据块和 ADF 的功能
摘要
在这一章中,我探讨了 ADF、SSIS 和 Databricks 之间的区别和相似之处,并就何时选择其中一个以及何时一起使用它们提出了建议。该解决方案确实取决于许多不同的因素,如性能、成本、偏好、安全性、功能等。在接下来的章节中,我们将结合使用 ADF 和 Databricks 来演示真实的端到端工作流和管道。
三、设计数据湖存储第二代账户
在设计和架构 Azure Data Lake Storage Gen2 帐户时,有各种注意事项需要考虑。这些考虑因素包括安全性、区域、文件夹和文件结构、数据湖层等等。
本章将解释在设计 Azure 数据湖存储二代帐户时要考虑的各种因素。将涉及的主题包括
-
数据湖图层及其一些属性
-
区域、目录和文件的设计注意事项
-
不同级别的安全选项和注意事项
数据湖层
Azure Data Lake Storage Gen2 提供了将存储库划分为多个层的灵活性。这些层有助于轻松地组织、保护和管理数据湖。图 3-1 概述了在设计数据湖时可以考虑的数据湖中的各个层。这些层包括
-
环境
-
存储帐户
-
文件系统
-
区域
-
目录
-
文件
后续部分将更详细地讨论这些层。
图 3-1
数据湖中的各种层
环境
环境定义了设计数据湖时需要考虑的顶层。例如,如果需要开发、QA 和生产环境,那么这些环境还必须包括一个或多个 ADLS 第二代存储客户。图 3-2 描述了如何通过 Azure DevOps 管道来管理和编排这个多环境。
图 3-2
由 DevOps 管道协调的开发、QA、生产环境
存储帐户
创建 Azure Data Lake 存储帐户时需要配置几个属性,如图 3-3 所示。此外,在设计存储帐户时,考虑存储帐户的限制和容量对于确定是否拥有多个存储帐户至关重要。存储帐户级别的安全性将由控制平面 RBAC(基于角色的访问控制)定义,更多详细信息将在“安全性”部分介绍。
图 3-3
存储帐户图层属性
以下是可在存储帐户级别配置的各种属性:
-
性能层:标准存储帐户由磁性驱动器支持,每 GB 成本最低。它们最适合需要大容量存储或不常访问数据的应用。高级存储客户以固态硬盘为后盾,可提供一致的低延迟性能。它们最适合 I/O 密集型应用,如数据库。此外,所有磁盘都使用高级存储的虚拟机符合 99.9%的 SLA,即使在可用性集之外运行也是如此。存储帐户创建后,不能更改此设置。
-
帐户种类:通用存储帐户在一个统一的帐户中为 blobs、文件、表和队列提供存储。Blob 存储帐户专门用于存储 blob 数据,并支持选择访问层,这允许您指定访问帐户中数据的频率。选择符合您的存储需求并优化成本的访问层。
-
复制:您的 Azure 存储帐户中的数据总是被复制,以确保持久性和高可用性。选择符合您持久性要求的复制策略。存储帐户创建后,某些设置不能更改。
-
时间点恢复:使用时间点恢复将一个或多个容器恢复到以前的状态。如果启用了时间点还原,则还必须启用版本控制、更改馈送和 blob 软删除。
-
容器的软删除:软删除使您能够恢复先前标记为删除的容器。
-
文件共享的软删除:软删除使您能够恢复之前标记为删除的文件共享。
-
blob 的版本控制:使用版本控制来自动维护 blob 的先前版本,以便进行恢复和复原。
-
Blob 更改反馈:跟踪您帐户中 Blob 的创建和删除更改或修改。
-
连接方法:您可以通过公共 IP 地址或服务端点公开连接到您的存储帐户,也可以使用私有端点秘密连接到您的存储帐户。
-
路由偏好:微软网络路由将引导您的流量尽快从源头进入微软云。互联网路由将引导你的流量进入更靠近 Azure 端点的微软云。
-
需要安全传输:安全传输选项仅允许通过安全连接向存储帐户发送请求,从而增强了存储帐户的安全性。例如,当调用 REST APIs 来访问您的存储帐户时,您必须使用 HTTPS 进行连接。启用“需要安全传输”时,任何使用 HTTP 的请求都将被拒绝。当您使用 Azure 文件服务时,没有加密的连接将失败,包括使用 SMB 2.1、没有加密的 SMB 3.0 以及一些 Linux SMB 客户端的场景。因为 Azure storage 不支持自定义域名的 HTTPS,所以在使用自定义域名时,此选项不适用。
-
允许公共访问:启用“允许公共访问”时,允许配置容器 ACL(访问控制列表)以允许匿名访问存储帐户内的 blobs。禁用后,无论底层 ACL 配置如何,都不允许匿名访问存储帐户中的 blobs。
-
分层命名空间:ADLS 第二代分层命名空间加速了大数据分析工作负载,并支持文件级访问控制列表(ACL)。
文件系统
文件系统也称为容器,包含用于日志和数据的分层文件系统。图 3-4 显示了可以配置的容器级属性。数据平面 RBAC 安全级别将在“安全”一节中详细讨论。
图 3-4
文件系统属性
可以在容器级别配置以下属性:
-
公开访问级别:指定容器中的数据是否可以公开访问。默认情况下,容器数据是帐户所有者的私有数据。使用“Blob”允许对 Blob 的公共读取访问。使用“容器”允许对整个容器的公共读取和列表访问。
-
不可变策略:不可变存储提供了以一写多读(WORM)状态存储数据的能力。一旦数据被写入,数据将变得不可擦除和不可修改,并且您可以设置一个保留期,以便在该期限过去之前不能删除文件。此外,可以对数据进行合法保留,以使数据不可擦除和不可修改,直到保留被移除。
-
存储访问策略:建立存储访问策略用于对共享访问签名进行分组,并为受策略约束的签名提供附加限制。您可以使用存储的访问策略来更改签名的开始时间、到期时间或权限,或者在签名发布后撤销它。
区域、目录和文件
在文件夹和文件层,存储帐户的容器定义区域、目录和文件,类似于图 3-5 中的图示。目录和文件层的安全级别包括 ACL 和 SAS。这些安全级别将在“安全”一节中介绍。
图 3-5
文件夹和文件级区域、目录和结构
区域
区域定义了数据湖容器中的根级文件夹层次结构。区域可以由存储帐户中的多个容器或容器中的多个文件夹来定义。表 3-1 中的以下示例区域描述了它们的用途和典型用户群。
区域不需要总是驻留在同一个物理数据湖中,也可以作为单独的文件系统或不同的存储帐户驻留,甚至可以驻留在不同的订阅中。如果预计单个区域中的大吞吐量需求超过每秒 20,000 的请求速率,那么不同订阅中的多个存储帐户可能是一个好主意。
表 3-1
数据湖区域、访问和描述
|区域
|
接近
|
描述
|
| --- | --- | --- |
| 生的 | 服务帐户(只读) | 没有转换;原始格式;按摄入日期储存 |
| 脚手架 | 科学家、工程师 | 一般分期;增量准备 |
| 当(博物馆、美术馆、图书馆)馆长 | 分析师、科学家、工程师 | 数据市场;数据湖标准 |
| 敏感的 | 选择性访问 | 需要提升和选择性访问的敏感数据 |
| 实验室 | 科学家、工程师 | 探索性分析;沙盒区域 |
| 瞬态/温度 | 服务帐户 | 支持数据摄取的临时区域。此区域的一个使用情形是,如果您要跨网络移动大量压缩数据,您可能希望解压缩此区域中的数据。数据应该是短暂的,因此被称为瞬态的。 |
| 主/参考 | 分析师、科学家、工程师 | 参考数据;存档数据 |
目录(文件夹)
设计数据湖文件夹结构时,图 3-6 中的层次结构针对分析查询进行了优化。每个源系统将被授予数据源文件夹级别的写权限,并指定默认 ACL。这将确保在创建新的日常文件夹和文件时继承权限。
图 3-6
样本数据湖文件夹结构
图 3-6 中所示的分层文件夹格式可以动态参数化并编码到数据块或数据工厂中的 ETL 解决方案中,以根据定义的层次自动创建文件夹和文件。以下代码片段定义了图 3-6 中相同的文件夹结构,并且可以添加到 ADF 管道的配置中。我将在以后的章节中更详细地讨论这一点:
\Raw\DataSource\Entity\YYYY\MM\DD\File.extension
原始层中的敏感子区域可以由顶层文件夹分隔。这将允许您定义单独的生命周期管理策略。以下代码通过在原始区域中引入子区域来进一步对数据源进行分类,展示了先前文件夹结构的变体:
\Raw\General\DataSource\Entity\YYYY\MM\DD\File.extension
\Raw\Sensitive\DataSource\Entity\YYYY\MM\DD\File.extension
文件
Azure Data Lake Storage Gen2 针对基于 Spark 的处理进行了优化,可以更好地处理每个文件大约 65mb-1gb 的较大文件。Azure 数据工厂压缩作业可以帮助实现这一点。此外,Databricks Delta 格式的优化或自动优化功能有助于实现这种压缩。借助事件中心,捕获特性可用于根据大小或定时触发来保存数据。
对于需要读取优化的高性能分析的策划或建模区域,Parquet 和 Databricks Delta 等列格式将是利用谓词下推和列修剪来节省时间和成本的理想选择。
表 3-2 捕获了一些样本文件类型及其功能和大概的压缩率。
表 3-2
数据湖文件类型、功能和压缩率
|样本文件类型
|
能力
|
压缩比
|
| --- | --- | --- |
| 欧罗欧欧欧罗欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧欧 | 可压缩;可拆分的;将架构存储在文件中;适用于非结构化和模式差异数据 | ~91.24% |
| 镶木地板 | 分栏格式;可压缩的 | ~97.5% |
| CSV/文本 | 几乎在每个组织中都普遍使用;容易解析;通常是批量处理的良好用例;根据使用情况,并不总是 Spark 的最佳选择 | |
表 3-3 列出了一些示例压缩类型及其功能和示例用途。
表 3-3
数据湖压缩类型、功能和示例用途
|压缩类型
|
能力
|
样本使用
|
| --- | --- | --- |
| Bzip2 | 高压缩;低速;适用于存档目的,而不是 HDFS 查询 | 归档用例;对于某些文件类型,比 Gzip 压缩得更好 |
| Gzip | 中压缩;中速 | 不经常访问的 Avro/Parquet 格式的冷数据 |
| 机场 | 高速;较低的压缩;适用于文本文件 | 经常被访问的文本格式的热数据 |
| 时髦的 | 高速;低压缩 | 经常访问的 Avro/Parquet 格式的热数据 |
安全
保护数据是设计数据湖的一个重要组成部分。在您的数据湖中可以配置许多权限和控制。以下部分描述了设计数据湖时必须考虑的安全特性。
控制平面权限
控制平面基于角色的访问控制(RBAC)权限旨在仅在 Azure 资源级别授予安全主体权限,不包括任何数据操作。授予用户“读取者”角色不会授予对存储帐户数据的访问权限,因为需要额外的 ACL 或数据平面 RBAC 权限。一种好的做法是将控制平面 RBAC 与文件夹/文件级 ACL 结合使用。
数据平面权限
为安全主体处理数据平面 RBAC 权限时,所有其他 ACL 都将被忽略,并且将阻止对文件和文件夹分配权限。
数据平面 RBAC 权限可以应用到低至存储帐户级别。
可以分配的内置数据平面 RBAC 角色列表包括:
-
存储 Blob 数据所有者:用于为 Azure Data Lake 存储二代设置所有权和管理 POSIX 访问控制。
-
存储 Blob 数据贡献者:用于授予对 Blob 存储资源的读/写/删除权限。
-
存储 Blob 数据读取器:用于授予对 Blob 存储资源的只读权限。
-
存储队列数据贡献者:用于向 Azure 队列授予读/写/删除权限。
-
存储队列数据读取器:用于向 Azure 队列授予只读权限。
-
存储队列数据消息处理器:用于授予查看、检索和删除 Azure 存储队列中消息的权限。
-
存储队列数据消息发送方:用于向 Azure 存储队列中的消息授予添加权限。
类似 POSIX 的访问控制列表
ADLS 第二代中的文件和文件夹级访问由 ACL 授予。无论 ACL 权限如何,控制平面 RBAC 权限都需要与 ACL 结合使用。作为最佳做法,建议在存储帐户/容器级别为安全主体分配一个 RBAC 读者角色,然后在文件和文件夹级别继续执行限制性和选择性 ACL。
这两种类型的 ACL 包括访问 ACL,它控制对文件或文件夹的访问,以及默认 ACL,它由子文件或文件夹中分配的访问 ACL 继承。
共享访问签名
共享访问签名(SAS)支持有限的访问能力,例如用户对容器的读、写或更新。此外,可以应用时间盒来确定签名何时有效。这允许临时访问您的存储帐户,并方便地管理组织内外用户的不同访问级别。
数据加密
数据在移动和静止时都是安全的,ADLS Gen2 自动管理数据加密、数据解密和数据放置。ADLS Gen2 还提供了允许数据湖管理员管理加密的功能。
Azure Data Lake 使用存储在 Azure 密钥库中的主加密密钥来加密和解密数据。用户管理的密钥提供了额外的控制和灵活性,但是除非有令人信服的原因,否则建议将加密留给数据湖服务来管理。
网络传输
配置网络规则后,只有通过指定网络集请求数据的应用才能访问存储帐户。对您的存储帐户的访问可以限制为来自指定 IP 地址或 IP 范围的请求,或者来自 Azure 虚拟网络(VNet)中的子网列表的请求。
可以为您的存储帐户创建一个专用端点,该端点将您的虚拟网络中的专用 IP 地址分配给存储帐户,并保护虚拟网络和存储帐户之间通过专用链路的所有流量。
摘要
在本章中,我介绍了如何设计、实现和保护 Azure Data Lake Storage Gen2 帐户。随着我们在后续章节中开始探索 Azure Data Factory 和 Databricks ELT 模式,对如何实现和保护您的数据湖有了这样的理解和基线,将在我们读取和/或写入数据湖时提供有用的考虑。
四、将 SQL 数据库动态加载到数据湖存储二代
将数据从内部 SQL Server 或 Azure SQL Server 移动到 Azure 数据湖存储的过程已经成为许多企业日益增长的重要需求。拥有大量内部 SQL 服务器以及这些服务器中数百个数据库的客户有兴趣利用 Azure 的数据服务来构建 ELT 和/或 ETL 流程,以便在结构化、分区和可重复的流程中为其 SQL Server 生态系统中的一个或多个服务器完全加载其 Azure 数据湖存储帐户和内部 SQL Server 数据库和表。获取本地关系数据,将它们放入数据湖中的文件,然后使用分布式和多云计算技术(如 Databricks ),这是一种流行的现代架构模式。这种模式通过引入 AI 和 ML 等高级分析功能,使客户能够提高他们在 Azure 云之旅中的成熟度级别,这些功能在他们现有的内部环境中无法轻松实现。
Azure Data Factory 已经成为许多使用 Azure 数据平台的数据工程师选择的重要 ELT 和 ETL 工具。在 ADF 管道中利用动态 SQL 和参数的能力允许无缝的数据工程和可伸缩性。在本章中,您将通过一个实际练习来了解这一过程,即创建一个端到端的数据工厂管道,通过几个利用动态参数的管道将所有本地 SQL Server 对象(包括数据库和表)移动到 Azure Data Lake Storage Gen2。
Azure 必备资源
在第三章中,我讨论了如何设计和实现 Azure 数据湖存储二代账户。本章将基于这些知识,使用数据湖作为最终需要加载到 Azure SQL 数据库中的 transit parquet 文件的目标目的地(sink)。
Parquet 是 Hadoop 生态系统中提供的一种文件格式,与基于行的文件(如 CSV 或 TSV 文件)相比,它旨在提供高性能、高效率的数据平面列存储格式。
Parquet 没有使用简单的嵌套名称空间展平,而是使用记录分解和组装算法。Parquet 具有不同的高效数据压缩方式和编码类型,并针对批量处理复杂数据进行了优化。这种方法最适合需要从大型表中读取某些列的查询。Parquet 只能读取需要的列,这样可以最小化 I/O。
图 4-1 展示了从源 SQL 数据库(Azure 或内部部署)到数据湖的数据流架构。此外,图 4-1 中也描述了所需的部件。
图 4-1
SQL 数据库到数据湖存储第二代体系结构图
在设计和实现图 4-1 中的架构时,将需要以下 Azure 资源列表。微软提供了许多教程、演示和资源,描述如何通过 Azure 门户 UI 或代码创建这些资源。通读以下列表,了解图 4-1 中列出的每个组件的用途,并在本章构建 ADF 管道之前在您的 Azure 订阅中创建它们:
-
Azure Data Lake Storage Gen2 :数据将存储在 Azure Data Lake Storage gen 2(ADLS gen 2)中。为此,你需要创建一个 Azure Data Lake Storage Gen2 存储帐户。创建此帐户时,请记住应用第三章中的知识,并确保在帐户创建设置中启用“分层名称空间”,以便创建第二代帐户。
-
Azure Data Factory V2:Azure Data Factory(ADF)将被用作 ETL 编排工具,因此您可以使用 Azure Data Factory UI 创建数据工厂。
-
Azure Data Factory 自托管 IR :如果您决定使用本地 SQL Server,那么自托管 IR 将在本地资源和 Azure 服务之间创建一个链接,并允许您连接到 ADF 中的本地数据。还需要注意的是,将托管自托管 IR 的本地机器必须安装有64 位 Java 运行时环境(JRE)来创建 parquet 文件。
-
本地 SQL Server 或 Azure SQL 数据库:在本练习中,为了简单起见,源数据可以存储在本地 SQL Server 或 Azure SQL 数据库中,并演示端到端架构流程。您可以随时在本地或云中试用 SQL Server以获得 SQL Server 的开发版、快速版或试用版。
-
Azure SQL 数据库(标准):最后,使用 Azure SQL 数据库(ASQLDB)来存放 ADF 管道参数值、控制和日志表。此外,这个 Azure SQL 数据库也可以用作这个练习的源。在为此流程创建 Azure SQL 数据库时,记得将您的客户端 IP 地址授予 SQL Server 的防火墙规则。此外,请记住允许 Azure 服务和资源访问此服务器。
准备并验证 SQL Server 数据库对象
通过将示例 SQL 数据库导入 Azure SQL 数据库来准备流程。有许多免费的 SQL Server 数据库示例版本可供下载,如 AdventureWorks 或 WideWorldImporters 示例数据库( https://github.com/microsoft/sql-server-samples/tree/master/samples/databases
)
)。添加示例数据库后,导航到 SQL Server Management Studio (SSMS)并连接到包含两个 OLTP SQL 数据库的本地 SQL Server(或 Azure SQL 数据库),如图 4-2 所示。
图 4-2
OLTP 源数据库的 SSMS 视图
图 4-3 展开了 WideWorldImporters 数据库中的详细信息,以验证两个数据库中都有表。
图 4-3
源 WideWorldImporters 数据库中的表列表
同样,图 4-4 扩展了 AdventureWorksLT 数据库中的详细信息,以验证两个数据库中都有表。
图 4-4
源 AdventureWorksLT 数据库中的表列表
准备并验证 Azure SQL 数据库对象
接下来,创建一个名为 ADF_DB 的 Azure SQL 数据库以及一个表来存储表名、目录名和进程标志,这将在运行时驱动管道配置。该表也称为控制表。以下代码可用于创建元数据驱动的 ELT 流程所需的基表:
USE [ADF_DB]
go
SET ansi_nulls ON
go
SET quoted_identifier ON
go
CREATE TABLE [dbo].[pipeline_parameter1]
(
[parameter_id] [INT] IDENTITY(1, 1) NOT NULL,
[table_name] NVARCHAR NULL,
[table_catalog] NVARCHAR NULL,
[process_type] NVARCHAR NULL,
PRIMARY KEY CLUSTERED ( [parameter_id] ASC )WITH (pad_index = OFF,
statistics_norecompute = OFF, ignore_dup_key = OFF, allow_row_locks = on,
allow_page_locks = on, optimize_for_sequential_key = OFF) ON [PRIMARY]
)
ON [PRIMARY]
go
图 4-5 显示了创建数据库和表后,这些数据库对象在 SSMS 中的外观。
图 4-5
SSMS ADF _ DB 数据库和表格视图
准备 Azure 数据湖存储二代容器
还需要一个用于根级别层次结构的 ADLS Gen2 容器和文件夹,它将位于服务器级别。因此,根文件夹将是服务器的名称,如图 4-6 所示。
图 4-6
Azure 数据湖容器和根文件夹
图 4-7 确认服务器级文件夹中没有现有数据。
图 4-7
深入根文件夹以确认不存在任何数据。
创建 Azure 数据工厂管道资源
此时,通过导航到 Azure 数据工厂资源并单击 Author & Monitor,开始创建 Azure 数据工厂管道,如图 4-8 所示。
图 4-8
Azure 数据工厂管道创建的作者和监控者
一旦 Azure 数据工厂画布加载,点击“创建管道”,如图 4-9 所示,将创建一个新的管道和空白画布。
图 4-9
创建 Azure 数据工厂管道。
创建自托管集成运行时
如果您将本地服务器链接到 ADF,那么您将需要创建一个自托管集成运行时(
https://docs.microsoft.com/en-us/azure/data-factory/create-self-hosted-integration-runtime
)。
自托管集成运行时可以在云数据存储和私有网络中的数据存储之间运行复制活动。它还可以针对内部网络或 Azure 虚拟网络中的计算资源分派转换活动。自托管集成运行时的安装需要一台本地机器或私有网络中的一台虚拟机。
创建自托管 IR 后,验证其是否处于“运行”状态,如图 4-10 所示。自托管集成运行时可以在云数据存储和私有网络中的数据存储之间运行复制活动。
图 4-10
自承载集成运行时处于运行状态
创建链接服务
创建自托管 IR 后,可以创建所有需要的链接服务,包括 SQL Server、Azure SQL 数据库和 Azure Data Lake Storage Gen2,如图 4-11 所示。
图 4-11
已创建的链接服务
创建数据集
ADF 管道将需要三个数据集,如图 4-12 所示。第一个 DS_ADLS2 数据集将连接到接收器 Azure 数据湖存储二代帐户。第二个 DS_ASQLDB_PIPELINE_PARAMETER 数据集将连接到 ADF_DB 中的pipeline_parameter
表。最后,第三个 DS_SQLSERVER 数据集将是到源 SQLSERVER 数据库的连接。
图 4-12
已经创建的数据集
S7-1200 可编程控制器
接下来,将 ADLS 第二代数据集配置为拼花格式,如图 4-13 所示。此外,图中是参数化的文件路径连接,允许我们通过“文件路径”部分中列出的YY-MM-DD-HH
对数据进行分区。下页也提供了该代码。还要记住将压缩类型设置为“snappy ”,以提高性能。请忽略黄色警告图标,因为这种图标经常出现在动态和参数化的内容中,尤其是当字符串可能比预期的要长时。
图 4-13
ADLS2 数据集连接属性
作为参考,图 4-13 中的 ADLS 第二代数据集连接属性使用了以下代码。
@concat('rl-sql001/',dataset().table_catalog)
@{item().Table_Name}/@{formatDateTime(utcnow(),'yyyy')}/@{formatDateTime(utcnow(),'MM')}/@{formatDateTime(utcnow(),'dd')}/@{item().Table_Name}@{formatDateTime(utcnow(),'HH')}
ADF 允许您解释字符串中的表达式,以便轻松地将计算、参数和字段值作为字符串的一部分。现在,通过字符串插值,您可以使用类似这些示例的表达式生成超级简单的字符串求值。ADF 管道中实现的许多代码都使用字符串插值。
在该数据集中,添加图 4-14 所示的参数,这些参数将在稍后阶段使用。
图 4-14
需要 ADLS2 参数
DS_SQLSERVER
接下来,将数据集连接添加到本地 SQL Server。同样将表设置为“None ”,以允许遍历 SQL Server 中的所有表,如图 4-15 所示。
图 4-15
SQL Server 连接属性
DS _ ASQLDB _ 管道参数
最终的数据集将连接到 Azure SQL 数据库中的pipeline_parameter
表,如图 4-16 所示。这就完成了继续创建管道所需的所有数据集。
图 4-16
Azure SQL 数据库连接属性
创建 Azure 数据工厂管道
既然已经创建了数据集,那么是时候创建 ADF 管道来将数据移动到湖中了。该管道将利用到内部网络的自托管 IR 连接来转换 SQL 数据库表,并将它们作为 parquet 文件动态加载到数据湖中。此外,此管道将使用 ADF_DB,它是在本章的上一节中创建的。
p _ 插入 _ 基本 _ 表格 _ 信息
P_Insert_Base_Table_Info 管道将查询本地information_Schema.tables
作为其来源,以获取表和数据库名称,然后将结果输出到 Azure SQL 数据库中的基本参数表。这个过程的目的是填充pipeline_parameter
表,通过它的元数据字段驱动其余的管道。
要创建此管道,请向管道画布添加一个复制活动,如图 4-17 所示,并将源设置为本地 SQL Server 数据集。还要添加本节中包含的查询代码作为源代码。该查询将查询指定的数据库,并列出可在其余过程中使用的表。现在,为每个需要加载和执行管道的数据库手动更改数据库名称。图 4-17 显示了该代码块在复制活动中的位置。
图 4-17
ADF 复制活动中的源查询
以下是添加到图 4-17 中查询部分的 SQL 查询:
USE adventureworkslt
SELECT Quotename(table_schema) + '.'
+ Quotename(table_name) AS Table_Name,
table_catalog
FROM information_schema.tables
WHERE table_type = 'BASE TABLE'
尽管出于本练习的目的,我们手动将代码粘贴到 ADF 中的 source query 部分,但作为产品开发和部署的最佳实践,我建议在 SQL 数据库环境中创建存储过程,然后在 ADF 源代码中将它们作为存储过程而不是硬编码查询来调用。这将有助于简化代码的维护和管理。此外,在添加活动和设计 ADF 管道时,一定要正确、合理地命名 ADF 活动、管道和数据集。
作为命名 ADF 管道、活动和数据集的最佳实践,我建议遵循表 4-1 中列出的命名约定。
表 4-1
Azure 数据工厂命名约定
| 管道 | PL_ | | 映射数据流 | MDF_ | | 复制活动 | C_ | | 链接服务 | LS_ | | 资料组 | DS_ | | ForEach 循环 | FE_ | | 检查 | L_ | | 存储过程 | SP_ |现在您已经配置了源,是时候通过切换到 sink 选项卡并选择您在上一节中配置的pipeline_parameter
数据集来设置 Sink 了,如图 4-18 所示。
图 4-18
接收器数据集属性
最后,确保源到目的地的映射是准确的,如图 4-19 所示。通常,源和目标之间的一对一命名约定会自动映射,您也可以手动改变这种映射。
图 4-19
ADF 管道源到目标的映射
产生的pipeline_parameter
Azure SQL 表应该看起来类似于图 4-20 中所示的插图。
图 4-20
ADF 管道参数表
P_SQL_to_ADLS
在下一部分中,我们的目标是创建 SQL Server 到 ADLS Gen2 数据编排管道。将 Lookup 和 ForEach 活动添加到管道画布中,如图 4-21 所示。
图 4-21
ADF 管道查找和 ForEach 活动
查找活动只是查找先前管道中填充的管道参数表,如图 4-22 所示的设置。
图 4-22
查找活动的 ADF 管道设置
接下来,在 ForEach 活动的设置中,确保将“Items”设置为以下内容:
@activity('Get-Tables').output.value
此外,确保“顺序”保持未选中状态,以便表可以并行执行。目前,ForEach 活动支持最多 50 个批次的顺序批次计数,留空时默认批次计数为 20,如图 4-23 所示。
图 4-23
ForEach 活动的 ADF 管道设置
此外,在 ForEach 活动的“活动”选项卡中,添加一个复制活动。点击【编辑活动】查看详细信息,如图 4-24 所示。
图 4-24
ForEach 活动的 ADF 管道活动
源数据集是如图 4-25 所示的本地 SQL 服务器。
图 4-25
复制活动的 ADF 管道源和查询
此外,使用下面的动态源查询,它将查找Table_Catalog
和Table_Name
:
USE @{item().Table_Catalog} SELECT * FROM @{item().Table_Name}
您的接收器数据集将是指定的 ADLS Gen2 帐户容器和文件夹结构,在本章的上一节中已创建为 DS_ADLS2。另外在创建 DS_ADLS2 数据集时已经配置好的数据集属性中添加@{item().Table_Name}
和@{item().Table_Catalog}
,如图 4-26 所示。
图 4-26
ADF 管道接收器数据集属性
这个管道现在已经完成,可以运行了。
运行数据工厂管道并验证 Azure 数据湖存储二代对象
运行 ADF 管道,从图 4-27 中可以看到,已经为两个数据库创建了两个数据库级文件夹。
图 4-27
ADLS2 数据库级文件夹
还要注意,在您的 ADLS Gen2 帐户中已经创建了适当的表格级文件夹,如图 4-28 所示。
图 4-28
ADLS2 表级文件夹
此外,在钻取文件夹时,请注意图 4-29 中的文件夹被适当地进行了时间分区,并且已经创建了 Parquet 格式的表格级文件。
图 4-29
ADLS 第二代实木复合地板文件
摘要
在这一章中,我介绍了 Azure Data Factory 及其在现代基于云的 ETL 环境中的作用,它是许多使用 Azure 数据平台的数据工程师的首选工具。我还演示了一个实际的例子,说明如何创建一个端到端的数据工厂管道,用几个利用动态参数的管道将所有本地 SQL Server 对象(包括数据库和表)移动到 Azure Data Lake Storage Gen2。
这个练习展示了 ADF 为大容量、高速度和多种多样的数据接收构建动态的、元数据驱动的 ELT 管道的能力。这些管道可以将数据从各种源系统(包括内部数据库)移动到 ADLS Gen2 和其他低成本存储帐户,以进行进一步处理、清理、转换、探索和高级分析使用案例。
五、使用COPY INTO
加载 Synapse Analytics 专用 SQL 池
在第四章中,我向您展示了如何将 snappy 压缩的 parquet 文件从本地 SQL Server 加载到 Data Lake Storage Gen2 中。本章将向您介绍用于将 ADLS Gen2 的拼花文件完全加载到 Synapse Analytics 专用 SQL 池表中的基本机制和技术。此外,本章还将详细介绍 COPY INTO 命令,该命令提供了许多好处,包括消除了数据加载过程中的多个步骤,并减少了该过程所需的数据库对象的数量。此外,与 PolyBase 不同,COPY INTO 不需要对 sink SQL pool 表的控制访问权限,只需要插入和管理数据库批量操作权限。本章将演示使用复制到命令的一些常见场景。
Azure Synapse Analytics 是一项无限的分析服务,它将数据集成、企业数据仓库和大数据分析结合在一起。它让你可以自由地使用无服务器或专用资源来查询数据。Azure Synapse 将这些世界与统一的体验结合在一起,以摄取、探索、准备、管理和提供数据,满足即时的 BI 和机器学习需求。专用 SQL 池指的是 Azure Synapse Analytics 中提供的企业数据仓库功能。专用 SQL 池代表使用 Synapse SQL 时调配的分析资源的集合。
图 5-1 类似于第四章 4 的图 4-1 所示的架构图,增加了一个 Synapse Analytics 专用 SQL 池作为我们创建并存储在 ADLS Gen2 中的拼花文件的最终目的地。
图 5-1
第二代数据湖存储到 Synapse 专用 SQL 池架构图
在更详细地研究 COPY INTO 命令之前,您需要为目标 SQL 数据仓库创建一个 Synapse Analytics 专用 SQL 池。此外,您需要创建一个与列名、列顺序和列数据类型相匹配的目标表。您可以使用 Azure Portal 在Synapse Analytics 中创建一个 专用 SQL 池。
COPY INTO
命令的功能
Synapse Analytics 中的复制命令功能为用户提供了一个简单、灵活、快速的界面,用于 SQL 工作负载的高吞吐量数据接收。COPY INTO
命令支持以下参数:
FILE_TYPE = {'CSV' | 'PARQUET' | 'ORC'}
FILE_FORMAT = EXTERNAL FILE FORMAT OBJECT
CREDENTIAL = (AZURE CREDENTIAL)
ERRORFILE = http(s)://storageaccount/container]/errorfile_directory[/]
ERRORFILE_CREDENTIAL = (AZURE CREDENTIAL)
MAXERRORS = max_errors
COMPRESSION = { 'Gzip' | 'DefaultCodec'|'Snappy'}
FIELDQUOTE = 'string_delimiter'
FIELDTERMINATOR = 'field_terminator'
ROWTERMINATOR = 'row_terminator'
FIRSTROW = first_row
DATEFORMAT = 'date_format'
ENCODING = {'UTF8'|'UTF16'}
IDENTITY_INSERT = {'ON' | 'OFF'}
请注意,在这个列表中,可以在每个参数中选择和配置多个选项来定制配置参数。
数据准备技巧
在 ADLS Gen2 中创建拼花文件之前,源数据的数据准备将是一个重要且必要的过程。以下部分提供了一些数据准备技巧,以确保拼花文件可以通过 COPY INTO 命令运行。
技巧 1:删除列名中的空格
在将拼花文件加载到 Synapse Analytics 专用 SQL 池时,经常会出现包含空格的列名的明显问题。如果您正在使用内部源系统,则可以通过创建一个视图并为名称中包含空格的列分配一个别名来处理这些列名称中的空格。
或者,作为一个更复杂的解决方案,可以通过利用 sys columns 和 sys tables 以及下面的脚本来删除所有表中的列名中的空格,从而从多个源表中删除列名空格:
SELECT 'EXEC SP_RENAME ''' + B.NAME + '.' + A.NAME
+ ''', ''' + Replace(A.NAME, ' ', '')
+ ''', ''COLUMN'''
FROM sys.columns A
INNER JOIN sys.tables B
ON A.object_id = B.object_id
AND Objectproperty(b.object_id, N'IsUserTable') = 1
WHERE system_type_id IN (SELECT system_type_id
FROM sys.types)
AND Charindex(' ', a.NAME) <> 0
如果您的源系统是基于云的源,那么您可能还想考虑使用映射数据流,通过模式、规则和派生列动态地从源列中删除空格。我将在第十一章和第十二章讲述映射数据流的一些附加功能。
技巧 2:将 VARCHAR(MAX)转换为 VARCHAR(4000)
通常,需要考虑数据类型的容量限制和各种其他组件的最大值。请注意,随着时间的推移,这可能会改变并成为受支持的功能。Azure Synapse Analytics 过去不支持 varchar(max)数据类型,因此,您可以根据需要在源系统上使用以下 CONVERT 函数将 varchar(max)数据类型转换为 varchar(4000)数据类型。这可以通过使用以下 CONVERT 函数将源表的数据类型转换为 select 语句或视图来实现:
CONVERT(VARCHAR(length) , varchar_column_name)
SELECT column1 AS column1,
column2 AS column2,
CONVERT(VARCHAR(4000), varchar_column) AS varchar_column
FROM dbo.table_name
使用拼花文件复制到
对于大数据工作负载,使用 COPY INTO 命令的首选方法是使用 snappy Parquet 作为定义的 FILE_FORMAT 来读取 parquet (snappy compressed)文件。此外,对于这种情况,请使用托管身份凭据。
以下是 snappy parquet 文件的复制到 SQL 语法,您必须在 Synapse Analytics 专用 SQL 池中运行这些文件:
COPY INTO [Table1]
FROM 'https://lake.dfs.core.windows.net/lake/staging/Table1/parquet/*.parquet'
WITH (
FILE_FORMAT = [snappyparquet],
CREDENTIAL = (IDENTITY='Managed Identity')
)
运行该命令,您会注意到 snappy parquet 文件从 ADLS Gen2 复制到 Synapse Analytics 专用的 SQL 池表中,每 100 万行大约需要 30 秒。
此外,在执行数据准备步骤后,以下数据类型没有错误:DATETIME、INT、NVARCHAR(4000)。此外,文本字段中的空整数、逗号和引号对于这种时髦的拼花格式来说不是问题。
使用 CSV 文件复制到
某些情况下可能需要 CSV 格式的源文件。对于这种情况,需要对源数据集进行更多的设置。
首先在数据工厂中配置一个 CSV 数据集,并选择以下连接属性,如图 5-2 所示:
图 5-2
ADF 中的 CSV 连接配置属性
-
列分隔符:逗号(,)。
-
行分隔符:自动检测。
-
编码:默认(UTF-8)。这需要为 CSV 文件设置。或者,可以在 COPY INTO 命令语法中指定“编码”。
-
转义字符:' '(注意,该设置允许文本字段中使用双引号和逗号)。
-
引号字符:双引号(")(注意,该设置允许文本字段中使用双引号和逗号)。
-
Null 值 : @concat(')(注意这个设置将允许 NULL int 数据类型)。
确保 ADF 源连接选项卡包含所有配置的属性。
图 5-2 中用于动态文件路径的代码如下:
@{item().dst_folder}
@{item().dst_name}/csv/@{formatDateTime(utcnow(),'yyyy-MM-dd')}/ @{item().dst_name}.csv
以下示例代码显示了可在 Synapse Analytics 专用 SQL 池中运行的 CSV 文件的复制到 SQL 语法。请注意,语法中的编码被指定为 UTF8,逗号作为字段终止符:
COPY INTO [Table1]
FROM 'https://sdslake.dfs.core.windows.net/lake/staging/Table1/csv/*.csv'
WITH (
FILE_TYPE = 'CSV',
CREDENTIAL = (IDENTITY='Managed Identity'),
ENCODING = 'UTF8',
FIELDTERMINATOR = ','
)
类似于使用 snappy Parquet 语法复制到,运行命令并注意 CSV 文件在大约 12 秒内从 ADLS Gen2 复制到 Azure Synapse Analytics 专用 SQL 池表,用于 300K 行。此外,在执行数据准备步骤后,以下数据类型没有遇到错误:DATETIME、INT、NVARCHAR(4000)。此外,在配置 CSV 数据集属性后,文本字段中的空整数、逗号和引号对于此 CSV 文件类型来说不是问题。
使用从数据工厂复制到
要使用数据工厂中的 COPY INTO 命令,请创建 Synapse Analytics 专用 SQL 池数据集,以及包含复制活动的新管道,如图 5-3 所示。将源设置为包含 ADLS Gen2 存储帐户的数据集,将接收器设置为 Synapse Analytics 专用 SQL 池数据集。
图 5-3
用于复制到配置中的 ADF 源设置
图 5-4 显示了将接收器数据集配置到 Synapse Analytics 专用 SQL 池数据集后将显示的各种复制方法。
图 5-4
用于复制到配置中的 ADF 接收器设置
请注意,选项包括聚合库、复制命令和批量插入。通过选择“Copy command”,请注意,如果您可能需要在完全重新加载之前截断临时表,可以选择添加预拷贝脚本。此外,还有一个“自动创建表格”选项。当 ADF 管道运行时,来自 ADLS Gen2 的 snappy parquet 文件将从数据工厂管道加载到 Synapse Analytics 专用 SQL 池。
摘要
在本章中,我讨论了用于将 ADLS Gen2 的拼花文件完全加载到 Synapse Analytics 专用 SQL 池表中的基本机制和技术。此外,我还演示了 COPY INTO 命令的用法,该命令消除了数据加载过程中的多个步骤,并减少了该过程所需的数据库对象的数量。
六、将数据湖存储二代文件加载到 Synapse Analytics 专用 SQL 池中
第四章向您展示了如何创建一个动态的、参数化的、元数据驱动的流程,将数据从本地 SQL Server 完全加载到 Azure Data Lake Storage Gen2。本章将演示如何将所有来自 ADLS Gen2 的 snappy 压缩拼花数据文件完全加载到 Azure 专用 SQL 池中。
Azure Data Factory 的 sink Copy 活动允许三种不同的复制方法将数据加载到 Azure 专用 SQL 池中,这是 Azure Synapse 分析生态系统的一部分。本章将使用动态和参数化的 ADF 管道来探索这三种方法:
-
聚合碱
-
复制命令
-
批量插入
首先,要做一些准备工作,创建本章前几节中演示的数据集和管道。在本章的最后,将讨论和演示前面列出的三种加载数据的方法。
重新创建管道参数表
首先在 ADF_DB 中重新创建您在第四章中创建的pipeline_parameter
表,使其更加健壮,为本章将要构建的 ADF 管道做准备。
下面是重新创建该表的代码。如果该表存在,它首先删除该表。然后,它重新创建表:
USE [ADF_DB]
go
/****** Object: Table [dbo].[pipeline_parameter] ******/
IF EXISTS (SELECT *
FROM sys.objects
WHERE object_id = Object_id(N'[dbo].[pipeline_parameter]')
AND type IN ( N'U' ))
DROP TABLE [dbo].[pipeline_parameter]
go
/****** Object: Table [dbo].[pipeline_parameter] ******/
SET ansi_nulls ON
go
SET quoted_identifier ON
go
CREATE TABLE [dbo].[pipeline_parameter]
(
[parameter_id] [INT] IDENTITY(1, 1) NOT NULL,
[server_name] NVARCHAR NULL,
[src_type] NVARCHAR NULL,
[src_schema] NVARCHAR NULL,
[src_db] NVARCHAR NULL,
[src_name] NVARCHAR NULL,
[dst_type] NVARCHAR NULL,
[dst_schema] NVARCHAR NULL,
[dst_name] NVARCHAR NULL,
[include_pipeline_flag] NVARCHAR NULL,
[partition_field] NVARCHAR NULL,
[process_type] NVARCHAR NULL,
[priority_lane] NVARCHAR NULL,
[pipeline_date] NVARCHAR NULL,
[pipeline_status] NVARCHAR NULL,
[load_synapse] NVARCHAR NULL,
[load_frequency] NVARCHAR NULL,
[dst_folder] NVARCHAR NULL,
[file_type] NVARCHAR NULL,
[lake_dst_folder] NVARCHAR NULL,
[spark_flag] NVARCHAR NULL,
[dst_schema] NVARCHAR NULL,
[distribution_type] NVARCHAR NULL,
[load_sqldw_etl_pipeline_date] [DATETIME] NULL,
[load_sqldw_etl_pipeline_status] NVARCHAR NULL,
[load_sqldw_curated_pipeline_date] [DATETIME] NULL,
[load_sqldw_curated_pipeline_status] NVARCHAR NULL,
[load_delta_pipeline_date] [DATETIME] NULL,
[load_delta_pipeline_status] NVARCHAR NULL,
PRIMARY KEY CLUSTERED ( [parameter_id] ASC )WITH (statistics_norecompute =
OFF, ignore_dup_key = OFF) ON [PRIMARY]
)
ON [PRIMARY]
go
从代码中列出的列可以看出,已经添加了相当多的新元数据字段,可以通过创建动态数据集和管道在 ADF 管道中捕获这些字段。
创建数据集
在下一节中,为 ADLS Gen2 snappy 压缩拼花文件创建一个源数据集,为 Azure 专用 SQL 池创建一个接收数据集。
首先创建三个数据集,并将数据集命名如下:
-
ADLS 到突触
-
ADLS 至突触
-
DS_SYNAPSE_ANALYTICS_DW
接下来的小节将展示如何创建它们。
ADLS 到突触
首先创建一个带有参数化路径的源 ADLS Gen2 数据集。请记住,pipeline_date
已经添加到您在第四章中创建的pipeline_parameter
表中,因为pipeline_date
捕获了数据加载到 ADLS Gen2 的日期。在此步骤中,您将从 ADLS Gen2 向 Synapse Analytics 专用 SQL 池加载数据。您可以从第四章重新运行管道,或者在此pipeline_date
栏中手动输入日期,该日期最好包含最新的文件夹日期。第八章将讨论如何自动将最大文件夹日期插入到此pipeline_date
列中,以确保此列始终具有可以传递到参数化 ADF 管道中的最新和最大文件夹日期。这将通过使用在复制活动成功后立即运行的存储过程活动来实现。
图 6-1 说明了如何设置参数化连接属性,以读取由pipeline_parameter
控制表驱动的源 ADLS Gen2 拼花目录和文件夹。
图 6-1
ADLS Gen2 拼花文件夹和文件的 ADF 参数化连接
以下是添加到图 6-1 中文件路径部分的代码:
@{item().dst_folder}
@{item().dst_name}/parquet/ @{item().pipeline_date}/ @{item().dst_name}.parquet
图 6-2 显示了如何添加所需的参数。
图 6-2
ADLS Gen2 实木复合地板文件夹和文件的 ADF 参数
图 6-3 中说明了链接的服务细节。Azure 密钥库用于存储凭据机密。当管道开始运行时,如果发现任何身份验证错误,这将与后面的部分相关。
图 6-3
使用 Azure Key Vault 的 ADF 链接服务连接属性
ADLS 至突触
图 6-4 中的 ADF 数据集连接使用托管身份连接凭据。图 6-4 中显示的数据集与上一个数据集的区别在于,这个链接的服务连接不使用 Azure Key Vault。稍后发现错误时,使用此选项来测试密钥存储库连接和非密钥存储库连接并在两者之间切换。
图 6-4
使用托管身份的 ADF 数据集连接属性
以下是添加到图 6-4 中文件路径部分的代码:
@{item().dst_folder}
@{item().dst_name}/parquet/ @{item().pipeline_date}/ @{item().dst_name}.parquet
与之前的数据集类似,添加如图 6-5 所示的参数。
图 6-5
ADLS 第二代实木复合地板文件夹和文件的 ADF 参数-托管身份
链接的服务详情如图 6-6 所示。这里没有使用 Azure Key Vault。同样,当执行管道时,如果发现任何身份验证错误,这将与后面的部分相关。
图 6-6
ADF 链接服务连接
在此部分中,已使用托管身份创建了新的 ADF 链接服务连接。
DS_SYNAPSE_ANALYTICS_DW
接收器连接将连接到 Azure Synapse Analytics 专用的 SQL 池,如图 6-7 所示。此外,参数用于指定来自pipeline_parameter
表的模式和表名。当 ForEach 循环活动将用于使用同一个接收数据集创建多个表时,这将是一个很好的特性。
图 6-7
ADF Synapse DW 链接的服务连接属性
以下是添加到图 6-7 中文件路径部分的代码:
@{item().src_schema}
@{item().dst_name}
创建管道
既然已经创建了数据集,那么还要创建一个新的管道。这样做时,添加一个连接到 ForEach 循环活动的查找活动,如图 6-8 所示。
图 6-8
包含查找和 ForEach 循环活动的 ADF 管道画布
图 6-9 中显示的查找查询将获得需要加载到 Azure Synapse Analytics 专用 SQL 池的表列表。请注意,目前有一个过滤器应用于查询,它将只包括load_synapse
= 1 的记录。
图 6-9
ADF 查找活动查询设置
图 6-9 中包含的代码片段如下:
SELECT [server_name],
[src_type],
[src_schema],
[src_db],
[src_name],
[dst_type],
[dst_name],
[include_pipeline_flag],
[partition_field],
[process_type],
[priority_lane],
[pipeline_date],
[pipeline_status],
[dst_folder],
[file_type]
FROM [dbo].[pipeline_parameter]
WHERE load_synapse = 1
在 ForEach 循环活动的设置中,添加查找活动的输出值,如图 6-10 所示。记住不要选中“顺序”框,以确保多个表并行处理。如果留空,默认“批次计数”为 20,最大值为 50。
图 6-10
ADF ForEach 活动设置
还要在 ForEach 循环活动中添加一个 Copy 活动,如图 6-11 所示。单击铅笔图标查看复制活动。
图 6-11
ADF ForEach 活动
源设置为 DS_ADLS_TO_SYNAPSE,它在链接的服务连接中使用 Azure 密钥库。添加所需的动态参数。请注意,参数是在数据集中定义的。图 6-12 显示了如何以及在哪里添加这些值。
图 6-12
ADF 复制活动源数据集属性
最后,选择 DS_SYNAPSE_ANALYTICS_DW 数据集作为 sink,并在启用“自动创建表”选项的情况下选择“批量插入”,如图 6-13 所示。
图 6-13
ADF 复制活动接收器数据集属性
基于管道的当前配置,由于它是由pipeline_parameter
表驱动的,当(n)个表/记录被添加到管道参数表并且load_synapse
标志被设置为 1 时,管道将基于所选择的复制方法并行地执行和加载所有表到 Azure Synapse Analytics 专用 SQL 池。
选择复制方法
现在,我们终于到了选择复制方法的时候了。接收器复制方法有三个选项。批量插入、聚合库和复制命令都是您将在本节中学习使用的选项。
批量插入
SQL Server 提供了 BULK INSERT 语句,以便使用 T-SQL 高效、快速地将大量数据导入 SQL Server,并且只需最少的日志记录操作。
在 ADF 复制活动的 Sink 选项卡中,将复制方法设置为 Bulk insert。如果表不存在,则“自动创建表”会使用源文件中的模式自动创建该表。当接收器指定存储过程或复制活动配备了分段设置时,不支持这种情况。对于这个场景,源文件是一个 parquet snappy 压缩文件,不包含 VARCHAR(MAX)等不兼容的数据类型,因此“自动创建表”选项应该没有问题。
请注意,预复制脚本将在创建表之前运行,因此在使用“自动创建表”的场景中,当表不存在时,首先在没有预复制脚本的情况下运行它,以防止出现错误,然后在为正在进行的完整加载创建表之后,再添加预复制脚本。图 6-14 显示了接收器设置以及添加任何预拷贝脚本(如截断脚本)的位置。
图 6-14
ADF 复制活动接收器复制前脚本
如果默认的“自动创建表”选项不能满足基于表的自定义分发的分发需求,那么可以利用“添加动态内容”来使用在每个表的管道参数表中指定的分发方法。
以下是添加到图 6-14 中的预拷贝脚本部分的代码:
TRUNCATE TABLE @{item().src_schema}.@{item().dst_name}
运行管道后,使用批量插入复制方法成功,如图 6-15 所示的活动运行监视器所示。
图 6-15
大容量插入的 ADF 管道成功
图 6-16 显示了批量插入复制管道状态的详细信息。
图 6-16
大容量插入的 ADF 管道运行详细信息
查询 Synapse 表后,注意表中有相同数量的行,如图 6-17 所示。
图 6-17
查询 Synapse Analytics 专用 SQL 池表以验证批量插入 ADF 管道结果
批量插入方法也适用于内部 SQL Server 作为源,Synapse Analytics 专用 SQL 池作为接收器。
聚合碱
使用 PolyBase 是以高吞吐量将大量数据加载到 Azure Synapse Analytics 的有效方式。通过使用 PolyBase 代替默认的 Bulk insert 机制,您将会看到吞吐量的大幅提高。
在下一个练习中,选择 PolyBase ,如图 6-18 所示,以测试该复制方法。
图 6-18
用于选择聚合库的 ADF 管道接收器数据集属性
PolyBase 将需要托管身份凭证来提供 Azure AD 并授予数据工厂对数据库的完全访问权限。
有关验证访问的更多详细信息,请查看并在 Synapse Analytics 专用 SQL 池上运行以下查询:
select * from sys.database_scoped_credentials
select * from sys.database_role_members
select * from sys.database_principals
此外,当需要创建外部表、数据源和文件格式时,以下查询有助于验证所需的对象是否已创建:
select * from sys.external_tables
select * from sys.external_data_sources
select * from sys.external_file_formats
配置并运行管道后,您可能会注意到管道失败,并出现以下错误:
"ErrorCode=FailedDbOperation,'Type=Microsoft.DataTransfer.Common.Shared.HybridDeliveryException,Message=Error happened when loading data into SQL Data Warehouse.,Source=Microsoft.DataTransfer.ClientLibrary,''Type=System.Data.SqlClient.SqlException,Message=External file access failed due to internal error: 'Error occurred while accessing HDFS: Java exception raised on call to HdfsBridge_IsDirExist. Java exception message:\r\nHdfsBridge::isDirExist - Unexpected error encountered checking whether directory exists or not: AbfsRestOperationException: Operation failed: \"This request is not authorized to perform this operation.\", 403, HEAD, https://lake.dfs.core.windows.net/lake //?upn=false&action=getAccessControl&timeout=90',Source=.Net SqlClient Data Provider,SqlErrorNumber=105019,Class=16,ErrorCode=-2146232060,State=1,Errors=[{Class=16,Number=105019,State=1,Message=External file access failed due to internal error: 'Error occurred while accessing HDFS: Java exception raised on call to HdfsBridge_IsDirExist. Java exception message:\r\nHdfsBridge::isDirExist - Unexpected error encountered checking whether directory exists or not: AbfsRestOperationException: Operation failed: \"This request is not authorized to perform this operation.\", 403, HEAD, https://lake.dfs.core.windows.net/lake //?upn=false&action=getAccessControl&timeout=90',},],'",
在研究错误后,原因是因为源数据集 DS_ADLS_TO_SYNAPSE 的原始 Azure 数据湖存储链接服务正在使用 Azure 密钥库来存储身份验证凭据,这是目前不支持的托管身份验证方法,用于使用 PolyBase 和 Copy 命令。
将源数据集更改为 DS_ADLS_TO_SYNAPSE_MI,它不再使用 Azure 密钥库,请注意图 6-19 中管道使用 PolyBase 复制方法成功。
图 6-19
更改为托管身份后,ADF 管道执行显示成功
复制命令
Copy 命令的功能与 PolyBase 相似,因此 PolyBase 所需的权限对于 Copy 命令来说也是绰绰有余的。有关复制到的更多信息,请重新访问第五章,其中涵盖了权限、用例以及复制到的 SQL 语法的详细信息。图 6-20 显示了如何在 ADF 接收活动中配置复制命令。
图 6-20
在 ADF 接收器中配置复制命令
与使用 Azure Key Vault 的 PolyBase 复制方法类似,您会注意到以下略有不同的错误消息:
ErrorCode=UserErrorSqlDWCopyCommandError,'Type=Microsoft.DataTransfer.Common.Shared.HybridDeliveryException,Message=SQL DW Copy Command operation failed with error 'Not able to validate external location because The remote server returned an error: (403) Forbidden.',Source=Microsoft.DataTransfer.ClientLibrary,''Type=System.Data.SqlClient.SqlException,Message=Not able to validate external location because The remote server returned an error: (403) Forbidden.,Source=.Net SqlClient Data Provider,SqlErrorNumber=105215,Class=16,ErrorCode=-2146232060,State=1,Errors=[{Class=16,Number=105215,State=1,Message=Not able to validate external location because The remote server returned an error: (403) Forbidden.,},],'", "failureType": "UserError", "target": "Copy data1", "details": []
切换到不使用 Azure Key Vault 的链接服务,注意管道成功,如图 6-21 所示。
图 6-21
ADF 管道执行结果
请注意,一旦创建并测试了 ADF 管道,考虑调度和触发它们是很重要的。触发器根据触发器类型和触发器中定义的标准确定何时触发管道执行。有三种主要类型的 Azure 数据工厂触发器:根据挂钟时间表执行管道的时间表触发器,定期执行管道并保持管道状态的翻转窗口触发器,以及响应 blob 相关事件的基于事件的触发器。此外,ADF 具有警报功能,可监控管道和触发故障,并通过电子邮件、文本等发送通知。
摘要
在本章中,我向您展示了如何创建源 Azure 数据湖存储二代数据集和 sink Synapse Analytics 专用 SQL 池数据集,以及由参数表驱动的 Azure 数据工厂管道。您还学习了如何使用三种复制方法将 snappy 压缩的 parquet 文件加载到 Synapse Analytics 专用的 SQL 池中:批量插入、聚合库和复制命令。本章向您介绍了 Azure Data Factory 中可用的各种摄取选项。
七、动态创建和加载 Synapse Analytics 专用 SQL 池表
在第六章中,您学习了如何使用数据工厂将数据湖文件加载到 Synapse Analytics 专用的 SQL 池中,方法是使用 COPY INTO 命令作为加载选项之一。现在,您已经设计并开发了一个动态流程,可以自动创建 ETL 模式表并将其加载到 Synapse Analytics 专用的 SQL 池中,该 SQL 池具有 snappy 压缩的 parquet 文件,让我们来探索创建表并将其加载到管理模式中的选项,您可以在运行时动态定义模式和分布类型,以创建管理模式表。请注意,在许多现代的基于云的数据架构模式中,暂存和监管更多地发生在数据湖中。然而,本章将展示通过使用几个简单的 ADF 管道将大量表持久化到数据仓库中的巨大能力。尽管 Delta Lake 有很多好处,我们将在第十五章中更详细地介绍,但是客户仍然有兴趣将他们最终的生产就绪的、可信的和精选的数据保存到 SQL 数据仓库中,原因有很多,包括易于分析查询、易于连接 Power BI 和其他报告工具等等。
在第四章中,我介绍了管道参数表的概念来跟踪和控制所有的 SQL Server 表、服务器、模式等等。本质上,这个管道参数表是为了驱动数据工厂编排过程而设置的。为了动态地定义分布类型和管理模式,我将在这个管道参数表中引入几个新列:[distribution_type]
、[dst_schema]
和[dst_name]
。这些新列可以在数据工厂管道中使用,以便从 ETL 模式中动态创建和加载管理的表。
使用 ADF 复制前脚本动态创建和加载新表
将表从源数据湖存储帐户加载到 Synapse Analytics DW 表的 ADF 管道流程将从使用查询查找图 7-1 中所示的管道参数表开始,在查询中您可以适当地指定您的标志和过滤器。
图 7-1
显示从 pipeline_parameter 表中选择的查询的 ADF 查找设置
请注意,图 7-1 添加了源 SQL select 语句作为本练习的查询。作为最佳实践,我建议考虑将这个 SQL 语句转换为存储过程,然后通过将源查询设置为存储过程,通过 ADF 管道调用代码。这将允许在 ADF 环境之外更容易地维护代码。
一旦添加了 source lookup 查询,过滤器pipeline_status = 'success'
就可以跟踪文件是否成功到达 lake,这是通过 SQL 存储过程完成的。此外,值得注意的是,这个管道参数中有相当多的列有助于跟踪整个端到端流程的步骤。出于本练习的目的,我们对列[dst_schema]
、[dst_schema]
和[distribution_type]
感兴趣。
将以下代码添加到图 7-1 所示的 ADF 查找活动的源查询部分:
SELECT [id],
[server_name],
[src_type],
[src_schema],
[src_db],
[src_name],
[dst_type],
[dst_name],
[include_pipeline_flag],
[partition_field],
[process_type],
[priority_lane],
[pipeline_date],
[pipeline_status],
[load_synapse],
[load_frequency],
[dst_folder],
[file_type],
[lake_dst_folder],
[spark_flag],
[data_sources_id],
[dst_schema],
[distribution_type],
[load_sqldw_etl_pipeline_date],
[load_sqldw_etl_pipeline_status],
[load_sqldw_curated_pipeline_date],
[load_sqldw_curated_pipeline_status],
[load_delta_pipeline_date],
[load_delta_pipeline_status]
FROM [dbo].[pipeline_parameter]
WHERE load_synapse = 1
AND pipeline_status = 'success'
AND include_pipeline_flag = 1
AND process_type = 'full'
AND load_frequency = 'daily'
例如,pipeline_ parameter
表中的dst_schema
和distribution_type
可能如下图 7-2 所示。
图 7-2
pipeline_parameter 表中的 dst_schema 和 distribution_type
当您继续进行图 7-3 所示的 ForEach 循环活动时,请确保正确填写设置选项卡中的项目字段,以获得查找活动的输出。
图 7-3
管道的 ADF ForEach 设置
下面是您需要添加到图 7-3 中 ForEach 循环活动的 Items 字段中的代码:
@activity('L_Get_Tables').output.value
深入 ForEach 活动。图 7-4 中显示了复制数据活动以及所需的数据集属性。
图 7-4
ADF 复制活动源设置和数据集属性
如图 7-4 所示的源数据集属性的名称和值如下:
|名字
|
价值
|
| --- | --- |
| dst_name
| @{item().dst_name}
|
| src_schema
| @{item().src_schema}
|
| distribution_type
| @{item().distribution_type}
|
| load_sqldw_etl_pipeline_date
| @{item().load_sqldw_etl_pipeline_date}
|
| load_sqldw_etl_pipeline_status
| @{item().load_sqldw_etl_pipeline_status}
|
| load_sqldw_curated_pipeline_date
| @{item().load_sqldw_curated_pipeline_date}
|
| load_sqldw_curated_pipeline_status
| @{item().load_sqldw_curated_pipeline_status}
|
| dst_schema
| @{item().dst_schema}
|
为 Synapse Analytics 专用 SQL 池 ETL 模式配置源数据集连接,如图 7-5 所示。注意,etl 模式是硬编码的。但是,表名来自于pipeline_parameter
表。
图 7-5
ADF 源数据集连接属性
以下是您需要在图 7-5 中的表格连接设置中输入的代码:
etl.@{item().dst_name}
图 7-6 中所示的汇数据集被定义为管理模式,其中您需要参数化目标模式和名称。请注意,源数据集包含源模式所需的参数。但是,接收器数据集不包含任何参数。
图 7-6
ADF 接收器数据集连接属性
以下是您需要输入图 7-6 中的表格连接设置的代码:
@{item().dst_schema}.@{item().dst_name}
创建数据集后,仔细看看拷贝前脚本。请注意,批量插入被用作复制方法,因为数据当前存在于 Synapse Analytics 专用 SQL 池中的 ETL 模式中,并且必须加载到管理的模式中。
如图 7-7 所示,还将表选项设置为“无”,因为表将使用以下预拷贝脚本创建,这基本上是一个动态的 Create Table as Select (CTAS)语法,它引用目标模式和名称以及来自pipeline_parameter
表的分布类型,特别是图 7-2 所示的部分。此外,脚本中使用了 SELECT TOP (0 ),因为我们只想使用此步骤创建表,并使用 ADF Copy 活动加载它们。
图 7-7
ADF 复制数据接收器设置
以下是在图 7-7 中的接收器预拷贝脚本中使用的代码:
CREATE TABLE @{item().dst_schema}.@{item().dst_name}
WITH
(
CLUSTERED COLUMNSTORE INDEX,
DISTRIBUTION = @{item().distribution_type}
)
AS SELECT TOP (0) * FROM etl.@{item().dst_name}
OPTION (LABEL = 'CTAS : @{item().dst_name}');
请注意,图 7-7 中所示的预拷贝脚本只是一个示例,向您展示了可用于预拷贝脚本的功能范围。在这个场景中,我演示了如何在一个预拷贝 SQL 语句中添加使用元数据驱动的管道参数的动态字符串插值函数。最佳实践是,尽量避免将代码直接嵌入到 ADF 管道活动中,并且仅在产品功能存在明显限制时才考虑此类选项,这可能需要使用此类定制配置。
运行管道后,将在 Synapse Analytics 专用 SQL 池中使用适当的目标模式、名称和分布类型创建所有管理的表。
使用 ADF 预复制脚本动态截断和加载现有表
在您可能需要动态截断和加载现有表而不是重新创建表的场景中,通过简单地截断目标表来完成该任务,如图 7-8 所示。这种方法将是与之前管道的唯一显著变化。
图 7-8
ADF 复制数据接收器设置,预复制脚本更改为截断
以下是在图 7-8 中的接收器预拷贝脚本中使用的代码:
TRUNCATE TABLE @{item().dst_schema}.@{item().dst_name}
使用存储过程动态删除、创建和加载表
最后,让我们探索一个选项,使用 Synapse Analytics 专用 SQL 池中的存储过程来删除和创建管理的表。
管道设计将与之前的管道非常相似,从查找开始,然后流入 ForEach 循环活动,如图 7-9 所示。
图 7-9
包含查找和 ForEach 活动的 ADF 管道流
在 ForEach 循环活动中,有一个名为 CTAS 的存储过程活动,来自图 7-10 所示的管道参数。该存储过程是在 Synapse Analytics 专用 SQL 池中创建的,基于动态 Create Table as Select (CTAS)语句,我将在本节中进一步提供其代码。此外,目的地名称和模式已被定义为存储过程参数,其值来自管道参数表并被传递给存储过程,如图 7-10 所示。
图 7-10
ADF 存储过程详细信息和参数
它使用可以从pipeline_parameter
表传递到存储过程的动态参数,该存储过程将由 ADF 管道调用。这里是在 ForEach 循环活动中调用的[etl].[Ctas_from_pipeline_parameter]
ADF 存储过程中使用的源代码,如图 7-10 所示。
SET ansi_nulls ON
go
SET quoted_identifier ON
go
CREATE PROC [etl].[Ctas_from_pipeline_parameter] @schema VARCHAR,
@name VARCHAR,
@distribution_type VARCHAR
AS
BEGIN
DECLARE @table VARCHAR(255)
DECLARE @table_stage VARCHAR(255)
DECLARE @table_etl VARCHAR(255)
DECLARE @sql VARCHAR(max)
SET @table = @schema + '.' + @name
SET @table_stage = @table + '_stage'
SET @table_etl = 'etl.' + @name
SET @sql = 'if object_id (''' + @table_stage
+ ''',''U'') is not null drop table '
+ @table_stage + '; CREATE TABLE ' + @table_stage
+ ' WITH ( DISTRIBUTION = ' + @distribution_type
+ ' ,CLUSTERED COLUMNSTORE INDEX ) AS SELECT * FROM ' + @table_etl + '; if object_id ('''
+ @table
+ ''',''U'') is not null drop table '
+ @table + '; RENAME OBJECT ' + @table_stage + ' TO '
+ @name + ';'
EXEC(@sql)
END
go
在转向 SSMS,然后编写存储过程脚本之后,请注意前面的脚本执行了以下操作
-
动态声明和设置
distribution_type
以及 ETL、管理和模式/表名 -
删除
curated_stage
表(如果存在) -
将创建阶段表的 SQL 语法设置为从动态设置分布类型的 etl 表中选择所有数据
-
删除实际/原始管理的表
-
将
curated_stage
重命名为实际/原始策划表
在您可能希望重命名原始管理的表而不是删除原始管理的表的情况下,请在 ADF 管道内的存储过程活动中使用以下脚本:
SET ansi_nulls ON
go
SET quoted_identifier ON
go
CREATE PROC [etl].[Ctas_from_pipeline_parameter] @schema VARCHAR,
@name VARCHAR,
@distribution_type VARCHAR
AS
BEGIN
DECLARE @table VARCHAR(255)
DECLARE @table_stage VARCHAR(255)
DECLARE @table_drop VARCHAR(255)
DECLARE @table_etl VARCHAR(255)
DECLARE @schematable_drop VARCHAR(255)
DECLARE @sql VARCHAR(max)
SET @table = @schema + '.' + @name
SET @table_stage = @table + '_stage'
SET @table_drop = @name + '_drop'
SET @table_etl = 'etl.' + @name
SET @schematable_drop = @table + '_drop'
SET @sql = 'if object_id (''' + @table_stage
+ ''',''U'') is not null drop table '
+ @table_stage + '; CREATE TABLE ' + @table_stage
+ ' WITH ( DISTRIBUTION = ' + @distribution_type
+ ' ,CLUSTERED COLUMNSTORE INDEX ) AS SELECT * FROM ' + @table_etl + '; if object_id ('''
+ @table
+ ''',''U'') is not null rename object '
+ @table + ' TO ' + @table_drop + '; RENAME OBJECT '
+ @table_stage + ' TO ' + @name + '; if object_id ('''
+ @schematable_drop
+ ''',''U'') is not null drop table '
+ @schematable_drop + ';'
EXEC(@sql)
END
go
最后,需要注意的是,在 Synapse Analytics 专用 SQL 池中,如果您尝试删除或重命名一个表,而该表具有与已创建的实体化视图相关联的依赖项,则删除和重命名脚本可能会失败。
摘要
在本章中,我概述了如何通过在复制活动中使用 ADF 的预复制脚本来动态创建新表并将其加载到 Synapse Analytics 专用 SQL 池中的步骤。此外,我还介绍了如何使用 ADF 的预复制脚本动态截断和加载现有表,最后,我演示了如何使用存储在 Synapse Analytics 专用 SQL 池中的 SQL 存储过程动态删除、创建和加载 Synapse Analytics 专用 SQL 池表。
我在本章中演示的一些示例可能并不完全适用于您的特定场景或用例,但可能有助于进一步加深您对 ADF 功能的理解,以及如何构建和利用定制的动态 SQL 脚本和存储过程来适应可能无法通过 ADF 中的现成功能获得的特定用例。我希望这些例子对你有所帮助。在接下来的两章中,您将进一步了解如何通过构建自定义审计和错误日志记录流程,在 ADF 管道完成运行后,在 SQL 数据库表中捕获和保存与管道相关的指标,从而使您所了解和构建的这些 ADF 管道更加健壮。
八、在 SQL 数据库中为管道活动指标构建自定义日志
在前面的章节中,我演示了如何使用数据工厂将数据从 ADLS Gen2 加载到 Synapse Analytics 专用的 SQL 池中。在这一章中,我将演示如何利用已经建立的管道来实现一个过程,该过程用于跟踪运行和保存数据的管道的日志活动。
Azure Data Factory 是一个健壮的基于云的 ELT 工具,能够适应记录管道审计数据的多种场景,包括现成的服务,如日志分析、Azure Monitor 等,以及提取管道指标并将它们传递给另一个自定义流程的更多自定义方法。在本章中,我将向您展示如何实现这些可能的自定义日志记录选项中的三个,它们是:
-
选项 1–创建存储过程活动:使用 ADF 更新静态管道参数表中的管道状态和日期时间列可以通过使用存储过程活动来实现。
-
选项 2–在 Data Lake Storage Gen2 中创建 CSV 日志文件:为创建的每个拼花文件生成一个元数据 CSV 文件,并将日志作为 CSV 文件存储在 ADLS Gen2 中的分层文件夹中,这可以使用复制数据活动来实现。
-
选项 3——在 Azure SQL 数据库中创建日志表:在 Azure SQL 数据库中创建管道日志表,并将管道活动作为记录存储在表中,可以通过使用 Copy data activity 来实现。
图 8-1 说明了这三个选项,并显示了从复制表活动到创建各种记录方法的数据流的可视化表示。
图 8-1
用于记录自定义管道数据的 ADF 选项
选项 1:创建一个存储过程活动
存储过程活动将用于调用 Synapse Analytics 专用 SQL 池中的存储过程。
对于这个场景,您可能希望将您的pipeline_status
和pipeline_date
细节作为列保存在您的adf_db.dbo.pipeline_parameter
表中,而不是拥有一个单独的日志表。这种方法的缺点是,它不会保留历史日志数据,而只是根据对传入文件在pipeline_parameter
表中的记录的查找来更新原始pipeline_parameter
表中的值。这提供了一种快速但不一定可靠的方法来查看管道参数表中所有项目的状态和加载日期。这种方法的具体用例可能是根据传入的文件夹和文件名以及时间戳来记录最大文件夹日期。
首先,在 ForEach 循环活动中添加一个存储过程活动,如图 8-2 所示,以确保流程使用存储过程迭代并记录每个表。请注意绿色箭头和线连接器,它指示存储过程必须在复制数据活动成功时运行。
图 8-2
使用存储过程记录数据的 ADF 选项 1
接下来,将以下存储过程添加到管道参数表所在的数据库中。此过程只是在管道参数表中查找目标表名,并在复制数据活动成功后更新每个表的状态和日期时间。类似地,通过在复制活动完成后将存储过程链接到失败约束,您可以轻松地添加一个新的存储过程来处理错误:
SET quoted_identifier ON
go
CREATE PROCEDURE [dbo].[Sql2adls_data_files_loaded] @dst_name NVARCHAR(500)
AS
SET nocount ON
-- turns off messages sent back to client after DML is run, keep this here
DECLARE @Currentday DATETIME = Getdate();
UPDATE [dbo].[pipeline_parameter]
SET pipeline_status = 'success',
pipeline_date = @Currentday
WHERE dst_name = @dst_name;
go
创建存储过程后,确认它已在相应的数据库中创建。注意图 8-3 中的确认,这是 SSMS 境内的屏幕截图。
图 8-3
显示 ADF 选项 1 使用的存储过程的 SSMS 视图
接下来,返回到数据工厂管道并配置存储过程活动。在“存储过程”选项卡中,选择刚刚创建的存储过程。还要添加一个新的存储过程参数,该参数引用在复制活动中配置的目的地名称,如图 8-4 所示。
图 8-4
ADF 存储过程详细信息和参数
在保存、发布和运行管道之后,注意到pipeline_date
和pipeline_status
列已经作为 ADF 存储过程活动的结果被更新,如图 8-5 中的pipeline_parameter
表视图所示。这是一个轻量级的测试模式,在一个集中的位置为您提供每个表的状态和加载日期的详细信息。我注意到 ADF 并不总是提供与有问题的表或列相关的健壮细节。
图 8-5
ADF 存储过程中更新的 pipeline_date 和 pipeline_status 列的 SSMS 视图
选项 2:在数据湖存储二代中创建一个 CSV 日志文件
由于您的复制表活动正在将快速拼花文件生成到分层的 ADLS Gen2 文件夹中,您可能还希望创建一个 CSV 文件,其中包含您的 ADLS Gen2 帐户中每个拼花文件的管道运行详细信息。对于这个场景,您可以设置一个数据工厂事件网格触发器来监听元数据文件,然后触发一个流程来转换源表并将其加载到一个管理区域中,从而在某种程度上复制一个接近实时的 ELT 流程。
开始设计 ADF 管道,通过添加用于创建日志文件的复制活动并将其连接到 Copy-Table 活动,在您的 ADLS Gen2 帐户中创建 CSV 日志文件,如图 8-6 所示。与上一个遍历每个表的过程类似,该过程将在每个表的元数据文件夹中生成一个 CSV 扩展元数据文件。
图 8-6
ADF 选项 2 用于记录数据,使用复制数据活动创建 CSV 文件
若要配置源数据集,请选择源本地 SQL Server。接下来,添加如图 8-7 所示的查询作为源查询。请注意,该查询将包含管道活动、复制表活动和用户定义参数的组合。
图 8-7
ADF 选项 2 用于提取管道活动指标的源查询
回想一下前面章节中的注释,这些注释指出将源查询作为代码嵌入到 ADF 管道中仅仅是为了直观演示的目的。将源查询作为存储过程添加,然后调用存储过程,这总是一个更好、更高效的过程。这将有助于在一个集中的位置维护代码。
下面是图 8-7 中使用的相应源代码:
SELECT '@{pipeline().DataFactory}' AS datafactory_name,
'@{pipeline().Pipeline}' AS pipeline_name,
'@{pipeline().RunId}' AS runid,
'@{item().src_name}' AS source,
'@{item().dst_name}' AS destination,
'@{pipeline().TriggerType}' AS triggertype,
'@{pipeline().TriggerId}' AS triggerid,
'@{pipeline().TriggerName}' AS triggername,
'@{pipeline().TriggerTime}' AS triggertime,
'@{activity('copy-TABLE').output.rowsCopied}' AS rowscopied,
'@{activity('copy-TABLE').output.rowsRead}' AS rowsread,
'@{activity('copy-TABLE').output.usedParallelCopies}' AS no_parallelcopies,
'@{activity('copy-TABLE').output.copyDuration}' AS copyduration_in_secs,
'@{activity('copy-TABLE').output.effectiveIntegrationRuntime}' AS effectiveintegrationruntime,
'@{activity('copy-TABLE').output.executionDetails[0].source.type}' AS source_type,
'@{activity('copy-TABLE').output.executionDetails[0].sink.type}' AS sink_type,
'@{activity('copy-TABLE').output.executionDetails[0].status}' AS execution_status,
'@{activity('copy-TABLE').output.executionDetails[0].start}' AS copyactivity_start_time,
'@{utcnow()}' AS copyactivity_end_time,
'@{activity('copy-TABLE').output.executionDetails[0].detailedDurations.queuingDuration}' AS copyactivity_queuingduration_in_secs,
'@{activity('copy-TABLE').output.executionDetails[0].detailedDurations.timeToFirstByte}' AS copyactivity_timetofirstbyte_in_secs,
'@{activity('copy-TABLE').output.executionDetails[0].detailedDurations.transferDuration}' AS copyactivity_transferduration_in_secs
sink 将是一个 CSV 数据集,扩展名为 CSV,如图 8-8 所示。
图 8-8
CSV 的 ADF 接收器数据集
图 8-9 显示了用于 CSV 数据集的连接配置。
图 8-9
CSV 的 ADF 接收器数据集连接属性
以下参数化路径将确保在正确的文件夹结构中生成文件。下面是如图 8-9 所示的代码:
@{item().server_name}/@{item().src_db}/@{item().src_schema}/@{item().dst_name}/metadata/@{formatDateTime(utcnow(),'yyyy-MM-dd')}/@{item().dst_name}.csv
保存、发布和运行管道后,请注意元数据文件夹是如何在以下文件夹结构中创建的:
Server>database>schema>date>Destination_table location
图 8-10 显示了您在 ADSL Gen2 中看到的这个文件夹。
图 8-10
ADF 管道选项 2 生成的 ADLS Gen2 文件夹
打开元数据文件夹,注意管道运行的每一天都会创建 CSV 文件夹,如图 8-11 所示。
图 8-11
由 ADF 管道选项 2 创建的 ADLS Gen2 文件夹(按时间戳)
最后,请注意图 8-12 中的元数据。以该表的名称命名的 csv 文件已创建。
图 8-12
包含来自选项 2 的 ADF 管道指标的 ADLS Gen2 元数据文件
下载并打开文件,注意所有的查询结果都已经被填充到。csv 文件,如图 8-13 所示。
图 8-13
ADLS Gen2 元数据文件,包含选项 2 中 ADF 管道指标的详细信息
选项 3:在 Azure SQL 数据库中创建日志表
本章的最后一个场景是在参数表所在的数据库中创建一个日志表,然后将数据作为记录写入该表。对于该选项,首先添加一个连接到复制表活动的复制数据活动,如图 8-14 所示。
图 8-14
ADF 选项 3,用于使用写入日志表的复制数据活动记录数据
接下来,在 ADF_DB 数据库中创建下表。此表将存储和捕获管道和复制活动的详细信息:
SET ansi_nulls ON
go
SET quoted_identifier ON
go
CREATE TABLE [dbo].[pipeline_log]
(
[log_id] [INT] IDENTITY(1, 1) NOT NULL,
[parameter_id] [INT] NULL,
[datafactory_name] NVARCHAR NULL,
[pipeline_name] NVARCHAR NULL,
[runid] NVARCHAR NULL,
[source] NVARCHAR NULL,
[destination] NVARCHAR NULL,
[triggertype] NVARCHAR NULL,
[triggerid] NVARCHAR NULL,
[triggername] NVARCHAR NULL,
[triggertime] NVARCHAR NULL,
[rowscopied] NVARCHAR NULL,
[dataread] [INT] NULL,
[no_parallelcopies] [INT] NULL,
[copyduration_in_secs] NVARCHAR NULL,
[effectiveintegrationruntime] NVARCHAR NULL,
[source_type] NVARCHAR NULL,
[sink_type] NVARCHAR NULL,
[execution_status] NVARCHAR NULL,
[copyactivity_start_time] NVARCHAR NULL,
[copyactivity_end_time] NVARCHAR NULL,
[copyactivity_queuingduration_in_secs] NVARCHAR NULL,
[copyactivity_transferduration_in_secs] NVARCHAR NULL,
CONSTRAINT [PK_pipeline_log] PRIMARY KEY CLUSTERED ( [log_id] ASC )WITH (
statistics_norecompute = OFF, ignore_dup_key = OFF) ON [PRIMARY]
)
ON [PRIMARY]
go
与最后一个管道选项类似,将本地 SQL Server 配置为源,并将选项 2 中提供的查询代码用作源查询,如图 8-15 所示。
图 8-15
ADF 选项 3 用于提取管道活动指标的源查询
接收器将连接到之前创建的 SQL 数据库管道日志表。
在保存、发布和运行管道之后,注意管道复制活动记录已经被捕获到dbo.pipeline_log
表中,如图 8-16 所示。
图 8-16
pipeline_log 表结果的 SSMS 视图,它将 ADF 选项 3 管道数据记录到 SQL DW 中
摘要
在本章中,我演示了如何使用自定义方法记录 ADF 管道数据,该方法从 ADF 管道中提取每个表或文件的指标,然后将结果写入pipeline_parameter
表、pipeline_log
表或 ADLS Gen2 中的 CSV 文件。此自定义日志记录流程可添加到多个 ADF 管道活动步骤中,以实现强大且可重复使用的日志记录和审计流程,该流程可在 SSMS 通过自定义 SQL 查询轻松查询,甚至可链接到 Power BI 仪表板和报告,以促进对日志记录数据的强大报告。在下一章,我将演示如何将 ADF 管道中的错误细节记录到 Azure SQL 表中。
九、在 SQL 数据库中捕获管道错误日志
在第八章 ?? 中,我讨论了各种捕获 Azure 数据工厂管道日志并将数据持久化到 SQL 表或 Azure 数据湖存储二代中的方法。尽管当管道活动成功时,捕获管道日志数据的过程是有价值的,但本章将介绍如何捕获 Azure 数据工厂管道错误并将其持久化到前面章节中创建的 ADF_DB 内的 SQL 表中。此外,我们将回顾我在前面章节中讨论过的管道参数流程,以展示pipeline_errors
、pipeline_log
和pipeline_parameter
表之间的相互关系。
概括地说,这个过程需要的表格包括
-
管道参数
-
管道 _ 日志
-
管道 _ 错误
图 9-1 展示了这些表格是如何相互连接的。
图 9-1
描述管道错误、日志和参数表之间关系的图表
创建参数表
概括地说,我们在前几章中创建了一些pipeline_parameter
表的变体。下面的脚本将创建一个更新版本的pipeline_parameter
表,其中包含一些额外的列,并将列parameter_id
作为主键。回想一下前面章节的练习,该表推动了元数据 ETL 方法:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
go
CREATE TABLE [dbo].[pipeline_parameter]
(
[parameter_id] [INT] IDENTITY(1, 1) NOT NULL,
[server_name] NVARCHAR NULL,
[src_type] NVARCHAR NULL,
[src_schema] NVARCHAR NULL,
[src_db] NVARCHAR NULL,
[src_name] NVARCHAR NULL,
[dst_type] NVARCHAR NULL,
[dst_name] NVARCHAR NULL,
[include_pipeline_flag] NVARCHAR NULL,
[partition_field] NVARCHAR NULL,
[process_type] NVARCHAR NULL,
[priority_lane] NVARCHAR NULL,
[pipeline_date] NVARCHAR NULL,
[pipeline_status] NVARCHAR NULL,
[load_synapse] NVARCHAR NULL,
[load_frequency] NVARCHAR NULL,
[dst_folder] NVARCHAR NULL,
[file_type] NVARCHAR NULL,
[lake_dst_folder] NVARCHAR NULL,
[spark_flag] NVARCHAR NULL,
[dst_schema] NVARCHAR NULL,
[distribution_type] NVARCHAR NULL,
[load_sqldw_etl_pipeline_date] [DATETIME] NULL,
[load_sqldw_etl_pipeline_status] NVARCHAR NULL,
[load_sqldw_curated_pipeline_date] [DATETIME] NULL,
[load_sqldw_curated_pipeline_status] NVARCHAR NULL,
[load_delta_pipeline_date] [DATETIME] NULL,
[load_delta_pipeline_status] NVARCHAR NULL,
PRIMARY KEY CLUSTERED ( [parameter_id] ASC )WITH (statistics_norecompute =
OFF, ignore_dup_key = OFF) ON [PRIMARY]
)
ON [PRIMARY]
go
创建日志表
下一个脚本将创建用于捕获数据工厂成功日志的pipeline_log
表。在该表中,log_id
列是主键,parameter_id
列是外键,引用参数表中的parameter_id
列:
SET ansi_nulls ON
go
SET quoted_identifier ON
go
CREATE TABLE [dbo].[pipeline_log]
(
[log_id] [INT] IDENTITY(1, 1) NOT NULL,
[parameter_id] [INT] NULL,
[datafactory_name] NVARCHAR NULL,
[pipeline_name] NVARCHAR NULL,
[runid] NVARCHAR NULL,
[source] NVARCHAR NULL,
[destination] NVARCHAR NULL,
[triggertype] NVARCHAR NULL,
[triggerid] NVARCHAR NULL,
[triggername] NVARCHAR NULL,
[triggertime] NVARCHAR NULL,
[rowscopied] NVARCHAR NULL,
[dataread] [INT] NULL,
[no_parallelcopies] [INT] NULL,
[copyduration_in_secs] NVARCHAR NULL,
[effectiveintegrationruntime] NVARCHAR NULL,
[source_type] NVARCHAR NULL,
[sink_type] NVARCHAR NULL,
[execution_status] NVARCHAR NULL,
[copyactivity_start_time] NVARCHAR NULL,
[copyactivity_end_time] NVARCHAR NULL,
[copyactivity_queuingduration_in_secs] NVARCHAR NULL,
[copyactivity_transferduration_in_secs] NVARCHAR NULL,
CONSTRAINT [PK_pipeline_log] PRIMARY KEY CLUSTERED ( [log_id] ASC )WITH (
statistics_norecompute = OFF, ignore_dup_key = OFF) ON [PRIMARY]
)
ON [PRIMARY]
go
ALTER TABLE [dbo].[pipeline_log]
WITH CHECK ADD FOREIGN KEY([parameter_id]) REFERENCES
[dbo].[pipeline_parameter] ([parameter_id]) ON UPDATE CASCADE
go
创建一个错误表
创建一个错误表需要执行下一个脚本,该脚本将创建一个pipeline_errors
表,用于从失败的管道活动中捕获数据工厂错误细节。在该表中,列error_id
是主键,列parameter_id
是外键,引用来自pipeline_parameter
表的列parameter_id
:
SET ansi_nulls ON
go
SET quoted_identifier ON
go
CREATE TABLE [dbo].[pipeline_errors]
(
[error_id] [INT] IDENTITY(1, 1) NOT NULL,
[parameter_id] [INT] NULL,
[datafactory_name] NVARCHAR NULL,
[pipeline_name] NVARCHAR NULL,
[runid] NVARCHAR NULL,
[source] NVARCHAR NULL,
[destination] NVARCHAR NULL,
[triggertype] NVARCHAR NULL,
[triggerid] NVARCHAR NULL,
[triggername] NVARCHAR NULL,
[triggertime] NVARCHAR NULL,
[no_parallelcopies] [INT] NULL,
[copyduration_in_secs] NVARCHAR NULL,
[effectiveintegrationruntime] NVARCHAR NULL,
[source_type] NVARCHAR NULL,
[sink_type] NVARCHAR NULL,
[execution_status] NVARCHAR NULL,
[errordescription] NVARCHAR NULL,
[errorcode] NVARCHAR NULL,
[errorloggedtime] NVARCHAR NULL,
[failuretype] NVARCHAR NULL,
CONSTRAINT [PK_pipeline_error] PRIMARY KEY CLUSTERED ( [error_id] ASC )WITH
(statistics_norecompute = OFF, ignore_dup_key = OFF) ON [PRIMARY]
)
ON [PRIMARY]
textimage_on [PRIMARY]
go
ALTER TABLE [dbo].[pipeline_errors]
WITH CHECK ADD FOREIGN KEY([parameter_id]) REFERENCES
[dbo].[pipeline_parameter] ([parameter_id]) ON UPDATE CASCADE
go
创建一个存储过程来更新日志表
现在您已经准备好了所有必要的 SQL 表,通过使用下面的脚本开始创建一些必要的存储过程,这将创建一个存储过程来用成功的管道运行中的数据更新pipeline_log
表。请注意,此存储过程将在运行时从数据工厂管道中调用:
SET ansi_nulls ON
go
SET quoted_identifier ON
go
CREATE PROCEDURE [dbo].[usp_updatelogtable] @datafactory_name
VARCHAR(250),
@pipeline_name
VARCHAR(250),
@runid
VARCHAR(250),
@source
VARCHAR(300),
@destination
VARCHAR(300),
@triggertype
VARCHAR(300),
@triggerid
VARCHAR(300),
@triggername
VARCHAR(300),
@triggertime
VARCHAR(500),
@rowscopied
VARCHAR(300),
@dataread
INT,
@no_parallelcopies
INT,
@copyduration_in_secs
VARCHAR(300),
@effectiveintegrationruntime
VARCHAR(300),
@source_type
VARCHAR(300),
@sink_type
VARCHAR(300),
@execution_status
VARCHAR(300),
@copyactivity_start_time
VARCHAR(500),
@copyactivity_end_time
VARCHAR(500),
@copyactivity_queuingduration_in_secs
VARCHAR(500),
@copyactivity_transferduration_in_secs VARCHAR(500)
AS
INSERT INTO [pipeline_log]
([datafactory_name],
[pipeline_name],
[runid],
[source],
[destination],
[triggertype],
[triggerid],
[triggername],
[triggertime],
[rowscopied],
[dataread],
[no_parallelcopies],
[copyduration_in_secs],
[effectiveintegrationruntime],
[source_type],
[sink_type],
[execution_status],
[copyactivity_start_time],
[copyactivity_end_time],
[copyactivity_queuingduration_in_secs],
[copyactivity_transferduration_in_secs])
VALUES ( @datafactory_name,
@pipeline_name,
@runid,
@source,
@destination,
@triggertype,
@triggerid,
@triggername,
@triggertime,
@rowscopied,
@dataread,
@no_parallelcopies,
@copyduration_in_secs,
@effectiveintegrationruntime,
@source_type,
@sink_type,
@execution_status,
@copyactivity_start_time,
@copyactivity_end_time,
@copyactivity_queuingduration_in_secs,
@copyactivity_transferduration_in_secs )
go
创建一个存储过程来更新错误表
接下来,运行下面的脚本,它将创建一个存储过程,用失败的管道运行中的详细错误数据更新pipeline_errors
表。请注意,此存储过程将在运行时从数据工厂管道中调用:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[usp_updateerrortable]
@datafactory_name nvarchar NULL,
@pipeline_name nvarchar NULL,
@runid nvarchar NULL,
@source nvarchar NULL,
@destination nvarchar NULL,
@triggertype nvarchar NULL,
@triggerid nvarchar NULL,
@triggername nvarchar NULL,
@triggertime nvarchar NULL,
@no_parallelcopies [int] NULL,
@copyduration_in_secs nvarchar NULL,
@effectiveintegrationruntime nvarchar NULL,
@source_type nvarchar NULL,
@sink_type nvarchar NULL,
@execution_status nvarchar NULL,
@errordescription nvarchar NULL,
@errorcode nvarchar NULL,
@errorloggedtime nvarchar NULL,
@failuretype nvarchar NULL
AS
INSERT INTO [pipeline_errors]
(
[datafactory_name],
[pipeline_name],
[runid],
[source],
[destination],
[triggertype],
[triggerid],
[triggername],
[triggertime],
[no_parallelcopies],
[copyduration_in_secs],
[effectiveintegrationruntime],
[source_type],
[sink_type],
[execution_status],
[errordescription],
[errorcode],
[errorloggedtime],
[failuretype]
)
VALUES
(
@datafactory_name,
@pipeline_name,
@runid,
@source,
@destination,
@triggertype,
@triggerid,
@triggername,
@triggertime,
@no_parallelcopies,
@copyduration_in_secs,
@effectiveintegrationruntime,
@source_type,
@sink_type,
@execution_status,
@errordescription,
@errorcode,
@errorloggedtime,
@failuretype
)
GO
创建源错误
在第四章中,您启动了构建 ADF 管道的过程,将源 SQL Server 表加载到 Data Lake Storage Gen2。基于这个过程,让我们测试数据工厂管道中的一个已知错误,并为了这个练习的目的通过重新创建一个错误进行处理。通常,包含至少 8,000 个以上字符的 varchar(max)数据类型在加载到 Synapse Analytics 专用 SQL 池时会失败,因为 varchar(max)是不支持的数据类型。这似乎是一个很好的错误测试用例。
首先创建一个表(如SalesLT.Address
),该表将存储一大块文本,这些文本在加载到 Synapse Analytics 专用 SQL 池时最终会导致错误。图 9-2 所示的SalesLT.Address
包含具有 varchar(max)数据类型的描述列。
图 9-2
SSMS 的销售观。地址
在SalesLT.Address
内,添加一大块文本。例如,您可以输入一些大于 8001 个单词的随机文本,类似于图 9-3 中所示的示例查询输出。确认 Description 列包含 8001 个单词,由于 Synapse Analytics 专用 SQL 池目标端的 8000 个字符的长度限制,这肯定会使 Azure 数据工厂管道失败,并且它将触发在pipeline_errors
表中创建记录。
图 9-3
SSMS 的销售观。包含大量示例文本的地址描述列
向参数表中添加记录
在确定了要在流程中运行的源 SQL 表之后,将它们添加到pipeline_parameter
表中,如图 9-4 所示。对于本练习,添加在上一步中创建的包含 8,001 个字符的大块的SalesLT.Address
表,以及一个我们期望成功的常规表(例如SalesLT.Customer
),以演示成功和失败的端到端日志记录过程。
图 9-4
添加到 pipeline_parameter 表的记录的 SSMS 视图,用于测试 ADF 管道中的错误
验证 Azure 数据湖存储二代文件夹和文件
在运行管道将 SQL 表加载到 Azure Data Lake Storage Gen2 之后,图 9-5 显示目的地 ADLS Gen2 容器现在已经以 snappy compressed Parquet 格式拥有了这两个表。
图 9-5
包含来自 ADF 管道执行的文件夹的 ADLS Gen2 视图
作为额外的验证步骤,地址文件夹包含图 9-6 所示的预期拼花文件。
图 9-6
包含来自 ADF 管道执行的拼花文件的 ADLS Gen2 视图
配置管道查找活动
现在是构建和配置 ADF 管道的时候了。在第七章中, I 详细介绍了如何构建一个 ADF 管道来加载 Synapse Analytics 专用 SQL 池,其中包含存储在 ADLS Gen2 中的 parquet 文件。作为流程的回顾,查找中的 select 查询获取需要加载到 Synapse Analytics 专用 SQL 池的 parquet 文件列表,然后将它们传递到 ForEach 循环,该循环将 parquet 文件加载到 Synapse Analytics 专用 SQL 池,如图 9-7 所示。
图 9-7
ADF 管道查找活动设置和查询以获取列出的 pipeline_parameter 表
配置管道 ForEach 循环活动
ForEach 循环活动包含 Copy-Table 活动,该活动获取 parquet 文件并将它们加载到 Synapse Analytics 专用的 SQL 池中,同时自动创建表。如果复制表活动成功,它将把管道运行数据记录到pipeline_log
表中。但是,如果 Copy-Table 活动失败,它会将管道错误详细信息记录到pipeline_errors
表中。
配置存储过程来更新日志表
还要注意,之前创建的UpdateLogTable
存储过程将被图 9-8 所示的成功存储过程活动调用。
图 9-8
ADF 管道存储过程设置
图 9-9 显示了将更新pipeline_log
表并可直接从存储过程导入的存储过程参数。
图 9-9
ADF 管道存储过程参数
表 9-1 中列出的下列值需要作为存储过程活动参数值输入,如图 9-9 中部分所示。
表 9-1
要输入到管道日志存储过程活动的参数设置中的值列表
|名字
|
价值
|
| --- | --- |
| 数据工厂名称 | @{pipeline()。数据工厂} |
| 管道名称 | @{pipeline()。管道} |
| 运行 Id | @{pipeline()。runid} |
| 来源 | @{item()。src_name} |
| 目的地 | @{item().dst_name} |
| 触发类型 | @{pipeline()。triggertype} |
| 已触发 | @{pipeline()。triggerid} |
| TriggerName | @{pipeline()。triggername} |
| 触发时间 | @{pipeline()。triggertime} |
| 罗斯佩德 | @ { activity(' Copy-Table '). output . rowscopied } |
| RowsRead | @ { activity(' Copy-Table '). output . rows read } |
| No _ ParallelCopies | @ { activity(' Copy-Table '). output . usedparallelcopys } |
| 复制持续时间(秒) | @ { activity(' Copy-Table '). output . Copy duration } |
| 有效积分运行时间 | @ { activity(' Copy-Table '). output . effective integration runtime } |
| 来源类型 | @ { activity(' Copy-Table '). output . execution details[0]. source . type } |
| 汇 _ 类型 | @ { activity(' Copy-Table '). output . execution details[0]. sink . type } |
| 执行 _ 状态 | @ { activity(' Copy-Table '). output . execution details[0]。状态} |
| 复制活动开始时间 | @ { activity(' Copy-Table '). output . execution details[0]。开始} |
| 复制活动结束时间 | @{utcnow()} |
| 复制活动 _ 队列持续时间 _ 秒 | @ { activity(' Copy-Table '). output . execution details[0]. detailed durations . queuingduration } |
| 复制活动 _ 传输持续时间 _ 秒 | @ { activity(' Copy-Table '). output . execution details[0]. detailed durations . transfer duration } |
配置一个存储过程来更新错误表
ForEach 循环活动中的最后一个存储过程是之前创建的UpdateErrorTable
存储过程,将被失败存储过程活动调用,如图 9-10 所示。
图 9-10
错误的 ADF 管道存储过程
图 9-11 显示了将更新pipeline_errors
表的存储过程参数,这些参数可以直接从存储过程中导入。
图 9-11
错误的 ADF 管道存储过程参数
表 9-2 中的以下值需要作为存储过程参数值输入,如图 9-11 中部分所示。
表 9-2
要输入到管道错误存储过程活动的参数设置中的值列表
|名字
|
价值
|
| --- | --- |
| 数据工厂名称 | @{pipeline()。数据工厂} |
| 管道名称 | @{pipeline()。管道} |
| 运行 Id | @{pipeline()。runid} |
| 来源 | @{item()。src_name} |
| 目的地 | @{item().dst_name} |
| 触发类型 | @{pipeline()。triggertype} |
| 已触发 | @{pipeline()。triggerid} |
| TriggerName | @{pipeline()。triggername} |
| 触发时间 | @{pipeline()。triggertime} |
| No _ ParallelCopies | @ { activity(' Copy-Table '). output . usedparallelcopys } |
| 复制持续时间(秒) | @ { activity(' Copy-Table '). output . Copy duration } |
| 有效积分运行时间 | @ { activity(' Copy-Table '). output . effective integration runtime } |
| 来源类型 | @ { activity(' Copy-Table '). output . execution details[0]. source . type } |
| 汇 _ 类型 | @ { activity(' Copy-Table '). output . execution details[0]. sink . type } |
| 执行 _ 状态 | @ { activity(' Copy-Table '). output . execution details[0]。状态} |
| 错误代码 | @ { activity(' Copy-Table '). error . error code } |
| 错误描述 | @ { activity(' Copy-Table '). error . message } |
| 错误日志时间 | @utcnow() |
| 故障类型 | @ concat(activity(' Copy-Table '). error . message,' failuretype:',activity(' Copy-Table '). error . failure type)。 |
运行管道
现在您已经配置了管道,继续运行管道。从图 9-12 中的调试模式输出日志中可以看出,正如所料,一个表成功,另一个表失败。
图 9-12
包含活动状态的 ADF 管道运行输出
核实结果
最后,验证pipeline_log
表中的结果。注意在图 9-13 中pipeline_log
表已经捕获了一个包含源SalesLT.Customer
的日志。
图 9-13
pipeline_log 表的 SSMS 视图显示成功的 ADF 管道
pipeline_errors
表中有一条SalesLT.Address
的记录,以及详细的错误代码、描述、消息等,如图 9-14 所示。
图 9-14
pipeline_errors 表的 SSMS 视图,显示失败的 ADF 管道
作为最后一项检查,在导航到 Synapse Analytics 专用 SQL 池时,请注意图 9-15 中的两个表都是自动创建的,尽管一个失败,一个成功。
图 9-15
自动创建的 Synapse Analytics 专用 SQL 池表的视图
值得注意的是,由于etl.Address
发生故障,数据仅加载到etl.Customer
中,随后没有数据加载到其中。图 9-16 显示了来自etl.Address
的数据的select *
,以确认表格不包含任何数据。
图 9-16
选择*自动创建的 etl。地址表,由于 ADF 管道失败,该表不包含任何数据
其他 ADF 日志记录选项
前面几节描述了在 ADF 管道中记录和处理错误的一种更加自定义的方法。在图 9-17 所示的复制数据活动中,有一个验证数据一致性、管理容错和启用日志记录的内置方法。
图 9-17
ADF 复制数据活动中的数据验证、容错和日志记录选项
以下列表包含 ADF 中“复制数据”活动的“设置”选项卡中作为可选配置属性提供的功能的详细信息和定义。这些功能旨在提供额外的现成数据验证、确认和日志记录方法,并且可以在 ADF 管道中有选择地启用和/或禁用它们:
-
数据一致性验证:选择此选项时,复制活动将在数据移动后在源和目标存储之间进行额外的数据一致性验证。验证包括二进制文件的文件大小检查和校验和验证,以及表格数据的行数验证。
-
容错:选择此选项时,您可以忽略复制过程中间发生的一些错误,例如,源存储和目标存储之间的不兼容行、数据移动过程中文件被删除等。
-
启用日志记录:选择此选项时,您可以将复制的文件、跳过的文件和行记录到 blob 存储中。
类似地,在映射数据流中,sink 设置中也有一个选项,在图 9-18 的情况下,它使用 Azure SQL DB。请注意各种选项,包括错误行处理、事务提交和报告错误成功选项。
图 9-18
ADF 映射数据流中的错误行处理
以下列表包含 ADF 中接收器复制数据活动的“设置”选项卡中作为可选配置属性提供的功能的详细信息和定义。这些特性旨在提供额外的开箱即用错误处理、事务提交等,并且可以在 ADF 管道中有选择地启用和/或禁用它们:
-
错误行处理:“出错时继续”将防止管道失败——例如,在加载数百万行时,有几行在过程中失败。
-
事务提交:在 SQL 事务提交的上下文中允许“单个”和“批量”提交。例如,批处理将具有更好的性能,因为数据将成批加载,而不是单次提交。
-
输出被拒绝的数据:此选项类似于常规的 ADF 复制数据活动,选择后会提示您将被拒绝的数据记录到存储帐户。
-
出错时报告成功:选中时,管道出错时报告成功。
摘要
在这一章中,我介绍了自定义 ADF 日志框架中的pipeline_errors
表,并讨论了它与前面章节中创建的pipeline_parameter
和pipeline_log
表的相关性和关系。此外,我还演示了如何在 ADF ELT 管道中设计和实现一个流程,通过在源系统上重新创建一个错误,并跟踪失败活动的 ADF 管道执行流程如何处理错误,从而将错误详细信息记录到pipeline_errors
表中。最后,我描述了其他一些内置方法,用于管理 ADF 的复制数据活动和映射数据流中的错误。
十、动态加载雪花数据仓库
许多组织和客户正在考虑将雪花数据仓库作为 Azure 的 Synapse Analytics 专用 SQL 池的替代方案。在应用第七章中介绍的相同模式的同时,本章将着重向您展示如何通过使用数据块和数据工厂将数据加载到雪花 DW 中。
在现代 Azure 数据平台中,将 ADLS 第二代数据动态加载到雪花型数据仓库有多种选择。您将在本章中了解到的一些选项包括
-
ADF 管道中的参数化数据块笔记本
-
数据工厂的常规复制活动
-
数据工厂的映射数据流
在对这些不同的选项进行了详细的端到端练习之后,我将讨论基于各种 ADF 管道执行运行中的选项的功能和限制的建议。
图 10-1 中的架构图说明了 Azure 资源正在被评估,以动态地将数据从 SQL 数据库(AdventureWorks)加载到 ADLS Gen2 帐户,使用数据工厂作为 ELT,雪花数据库(ADF_DB)
作为控制和记录表。请注意,ADF_DB
已经在前面包含元数据管道参数表和错误表的章节中创建。在学习本章的过程中,将探索将数据加载到雪花数据仓库的各种选项,以便将 ADLS Gen2 文件动态加载到雪花数据仓库中。
图 10-1
用于在雪花数据仓库中动态加载数据的 Azure 数据流架构
链接服务和数据集
最初,您需要在 ADF 中创建一些链接的服务和数据集来构建管道。链接的服务将包括源、接收器、控制数据库和数据块记事本,它们将是 ADF 管道流程的一部分。
基础链接服务
要开始这个过程,请在数据工厂中创建如图 10-2 所示的以下链接服务。
图 10-2
将数据加载到雪花所需的基本链接服务
如图 10-3 所示,一个 ADLS Gen2 链接服务将作为 snappy 压缩文件的容器和登陆区。
图 10-3
ADLS Gen2 的连接属性
一个示例AdventureWorks
Azure SQL 数据库将作为源 SQL 数据库,图 10-4 显示了用于生成本章示例的数据库的连接属性。
图 10-4
Azure SQL DB 的连接属性
雪花图ADF_DB
将被用作控制数据库,用于存放 ADF 管道中的控制、日志和审计表。图 10-5 显示了一些示例连接属性。
图 10-5
雪花控制表的连接属性
图 10-6 显示了雪花AdventureWorks
DB,它将作为所有AdventureWorks
表将要到达的目的地/目标雪花 DB。
图 10-6
雪花目标数据仓库的连接属性
创建图 10-7 所示的数据块链接服务是为了处理包含 Scala 代码的数据块笔记本,该代码将 ADLS Gen2 文件推送到雪花目标表。
图 10-7
Azure 数据块的连接属性
资料组
一旦创建了链接的服务,还需要创建图 10-8 中的数据集。这些是将在管道中使用的数据集。
图 10-8
ADF 管道所需的数据集
图 10-9 所示的 ADLS Gen2 数据集也包含由控制表和动态输入文件驱动的参数化文件夹路径和结构。
图 10-9
ADLS 第二代数据集的连接属性详细信息
以下是图 10-9 中文件路径部分包含的代码:
poc/raw/@{item().SRC_DB}/@{item().SRC_SCHEMA}/@{item().DST_TAB_NAME}/@{formatDateTime(utcnow(),'yyyy-MM-dd')}/ @{item().SAT_TAB_NAME}
需要设置图 10-10 中的参数。这些参数由包含详细元数据信息的雪花控制表填充,在 ADF 管道和数据集中称为动态参数。
图 10-10
ADLS 第二代数据集的参数属性详细信息
接下来,请创建如图 10-11 所示的AdventureWorks
数据集。这是我们到AdventureWorks2019LT
数据库的源数据库连接,它将驻留在 Azure SQL 数据库上。我们将使用这个数据库提取这些表,并将它们加载到 Data Lake Storage Gen2,然后使用 Databricks 笔记本将它们移动到 Snowflake DW,这将由 ADF 编排和调用。
图 10-11
Azure SQL 数据库的连接属性详细信息
需要创建如图 10-12 所示的动态参数化雪花数据库数据集。
图 10-12
动态雪花 DW 目标表的连接属性详细信息
此外,确保在目标雪花数据库中创建一个包含控制表的ADF_DB
,这些控制表可以用作图 10-13 所示的数据集。
图 10-13
雪花 DW 控制数据库和表的连接属性详细资料
雪花中的ADF_DB
控制表包含如下图 10-14 所示的模式,可以根据需要进一步更新和编辑。
图 10-14
雪花型 ADF_DB 控制表方案
雪花控制数据库和表格
在第四章中,我向您展示了如何通过元数据驱动和参数化流程实现用于控制 ADF 管道的控制数据库和表格。在本章中,遵循雪花型数据仓库中控制数据库和表的相同概念。与 T-SQL 相比,SnowSQL 语法会有一些变化,我将提供您需要在 Snowflake DW 上执行的 SnowSQL 代码。
图 10-15 显示了被称为ETL_PIPELINE_CTL
的ADF_DB
管线控制表。
图 10-15
雪花 ADF_DB。ETL _ 管道 _CTL 控制表
此外,以下是用于在雪花中创建控制和审计表的脚本。确保在您的ADF_DB
数据库的 ETL 模式中运行该脚本。该脚本将创建两个表—PIPELINE_CTL
和AUDIT_TAB
:
CREATE OR replace TABLE pipeline_ctl
(
parameter_id number(38,0) NOT NULL autoincrement,
server_name varchar(500),
src_type varchar(500),
src_schema varchar(500),
src_db varchar(500),
src_tab_name varchar(500),
dst_type varchar(500),
dst_tab_name varchar(500),
include_pipeline_flag varchar(500),
process_type varchar(500),
load_snowflake varchar(500),
load_frequency varchar(500),
dst_folder varchar(500),
file_type varchar(500),
lake_dst_folder varchar(500),
dst_schema varchar(500),
distribution_type varchar(500),
asql_to_lake_pipeline_date timestamp_ntz(9),
asql_to_lake_pipeline_status varchar(500),
load_snow_etl_pipeline_date timestamp_ntz(9),
load_snow_etl_pipeline_status varchar(500),
load_snow_curated_pipeline_date timestamp_ntz(9),
load_snow_curated_pipeline_status varchar(500),
load_delta_pipeline_date timestamp_ntz(9),
load_delta_pipeline_status varchar(500),
partition_field varchar(500),
priority_lane varchar(500),
spark_flag varchar(500),
swim_lane int,
PRIMARY KEY (parameter_id)
);
CREATE OR replace TABLE audit_tab
(
pipeline_name varchar(100),
db_name varchar(20),
sch_name varchar(20),
table_name varchar(50),
source_count number(38,0),
adls_count number(38,0),
snowflake_count number(38,0),
load_time timestamp_ntz(9) DEFAULT CURRENT_TIMESTAMP()
);
管道
既然已经创建并填充了基本元数据驱动的 ETL 控制表,那么就按照几个关键步骤开始创建 ADF 管道。首先,您需要设计并执行 ADF 管道来将 Azure SQL 数据库加载到 ADLS Gen2。下一步将是加载 ADLS 第二代到雪花。在将 ADLS Gen2 加载到雪花的第二步中,您将了解一些不同的选项来完成这个摄取任务。
步骤 1:设计并执行一个 ADF 管道,将 Azure SQL 数据库加载到 Data Lake Storage Gen2
本节记录了从 Azure SQL DB 到 ADLS Gen2 的数据迁移。作为参考,在第四章中已经详细讨论和演示了将数据加载到 Synapse Analytics 专用 SQL 池中的过程,而本章重点介绍了作为目标数据仓库的雪花。
一旦创建了数据集和链接服务,图 10-16 中所示的以下查找活动将查找控制表中定义的表列表,并将它们传递给 ForEach 循环活动,该循环活动将遍历源表列表(一次最多并行 50 个批处理计数)。确保在“常规”选项卡中对查找活动进行如下配置。
图 10-16
ADF 管道查找和外部 ForEach 循环活动常规属性
还要确保查找活动的配置如图 10-17 中的设置选项卡所示。
图 10-17
ADF 管道查找和外部 ForEach 循环活动设置
最后,确保在设置选项卡中配置外部 ForEach 循环活动,如图 10-18 所示。
图 10-18
ADF 管道外部 ForEach 循环活动设置
然后,ForEach 循环的内部复制活动将以 Parquet 格式将数据复制到 ADLS Gen2 中。确保在如图 10-19 所示的常规选项卡中进行配置。
图 10-19
ADF 管道复制活动常规连接属性
还要确保复制活动的源数据集属性的配置如图 10-20 所示。
图 10-20
ADF 管道复制活动源数据集属性
以下是添加到图 10-20 中的源查询部分的代码:
SELECT * FROM @item().SRC_SCHEMA}.@item().DST_TAB_NAME}
最后一个配置步骤是确保复制活动的汇数据集属性如图 10-21 所示进行配置。
图 10-21
ADF 管道复制活动接收器数据集属性
一旦管道成功执行,我们可以看到所有的表都以 Parquet 格式成功加载到 ADLS Gen2 中。图 10-22 显示了成功的管道活动运行的成功确认。
图 10-22
ADF 管道活动运行确认执行成功
图 10-23 显示 ADLS Gen2 中的文件夹结构与预期一致。
图 10-23
从 ADF 管道创建的 ADLS Gen2 文件夹
如图 10-24 所示,文件与 ADLS Gen2 中的文件一致。
图 10-24
从 ADF 管道创建的 ADLS Gen2 文件
步骤 2:设计数据湖存储二代到雪花 ADF 管道
一旦文件以 snappy 压缩文件格式进入 ADLS Gen2,有几个选项可以将拼花文件加载到雪花中。对于湖泊到雪花的摄取过程,本章评估了以下 ADF 管道选项,如图 10-25 所示。
图 10-25
将拼花文件加载到雪花中的选项
选项 1:使用 Azure Databricks 将 ADLS Gen2 加载到雪花的 ADF 管道
使用 Databricks 的 ADLS Gen2 到雪花 ADF 管道是一个选项,可以将参数从数据工厂传递到参数化 Databricks 笔记本,并确保两个服务之间的连接和集成,如图 10-26 所示。
图 10-26
选项 1 的 ADF 管道数据流
在 ForEach 循环活动中,添加 Databricks notebook 活动,并将其连接到我们在图 10-27 所示的前一部分中运行的复制数据活动。
图 10-27
ADF 管道 Azure 数据块连接属性
请注意图 10-28 中的设置选项卡,笔记本路径引用数据块笔记本,该笔记本包含代码以及将值动态传递到数据块笔记本以供进一步处理所需的基本参数。
图 10-28
具有数据块笔记本路径和参数设置的 ADF 管道
图 10-28 所示的数据块笔记本设置部分中的基本参数值使用的代码如下:
@item().DST_TAB_NAME}
@{item().DST_SCHEMA}
raw/AdventureWorksLT2019/SALESLT/@{item().DST_TAB_NAME}/@{formatDateTime(utcnow(),'yyyy')}-@{formatDateTime(utcnow(),'MM')}-@{formatDateTime(utcnow(),'dd')}/
在 Databricks 中,笔记本将包含以下 Scala 代码,如图 10-29 所示,它动态地接受来自 ADF 复制活动的参数,然后将它们传递给数据帧,该数据帧根据动态参数读取拼花文件,然后将其写入雪花表:
图 10-29
Databricks 笔记本包含将数据从 ADLS Gen2 加载到雪花的代码,从 ADF 管道活动中调用
import org.apache.spark.sql.{SaveMode, SparkSession}
spark.conf.set(
"fs.azure.account.key.adl001.dfs.core.windows.net",
"ENTER-ACCOUNT-KEY-HERE"
)
val DST_TAB_NAME = dbutils.widgets.get("DST_TAB_NAME")
val DST_SCHEMA = dbutils.widgets.get("DST_SCHEMA")
val FOLDER_PATH = dbutils.widgets.get("FOLDER_PATH")
var options = Map(
"sfUrl" -> "px.east-us-2.azure.snowflakecomputing.com",
"sfUser" -> "USERNAME",
"sfPassword" -> "PW",
"sfDatabase" -> "ADVENTUREWORKS",
"sfSchema" -> DST_SCHEMA,
"truncate_table" -> "ON",
"usestagingtable" -> "OFF",
"sfWarehouse" -> "COMPUTE_WH"
)
val df = spark.read.parquet("abfss://poc@gze2np1adl001.dfs.core.windows.net/"+FOLDER_PATH+DST_TAB_NAME)
df.write
.format("snowflake")
.options(options)
.option("dbtable", DST_TAB_NAME)
.mode(SaveMode.Overwrite)
.save()
选项 2:使用 ADF 复制活动将 ADLS Gen2 加载到雪花的 ADF 管道
下一个 ADLS Gen2 到 Snowflake ADF 管道选项将使用所有使用常规复制活动的数据工厂原生工具。ADF 管道的高层数据流如图 10-30 所示。
图 10-30
选项 2,将使用数据工厂的本地工具,使用常规的复制活动
此外,该选项将要求创建和配置 Blob 存储服务,并且仅要求对 Blob 链接服务连接进行 SAS URI 认证,图 10-31 中显示了一个配置示例。
图 10-31
Blob 存储连接属性
确保已经配置了以下复制数据活动源设置,如图 10-32 所示。
图 10-32
复制数据源数据集属性
图 10-33 确认以下复制数据活动接收器设置已正确配置。
图 10-33
复制数据接收器设置详细信息
请注意,在图 10-34 的设置部分,需要启用暂存并链接到服务。
图 10-34
复制数据设置详细信息
选项 3:使用映射数据流将 ADLS Gen2 加载到雪花的 ADF 管道
这个 ADLS Gen2 到雪花 ADF 管道选项将在映射数据流中使用所有数据工厂原生工具以及 Spark compute。图 10-35 显示了这个高级 ADF 数据流的样子。
图 10-35
在映射数据流中使用所有数据工厂原生工具和 Spark 计算的选项
在 ForEach 循环活动中,确保数据流活动连接到复制数据活动,并如图 10-36 所示配置设置。
图 10-36
映射数据流设置
在映射数据流活动中,有一个到 ADLS Gen2 帐户的源连接需要配置,如图 10-37 所示。
图 10-37
将数据流活动来源连接映射到 ADLS Gen2
还要确保引用目标雪花账户的目的地配置如下,如图 10-38 所示。
图 10-38
映射数据流活动接收器雪花连接属性
请注意,在图 10-39 的目标设置中,我们指定了一个“重建表格”动作。
图 10-39
指定“重新创建表格”操作的目标设置
图 10-40 显示了在映射部分中有其他有价值的特性来跳过重复。
图 10-40
映射部分中跳过重复项的功能
此外,图 10-41 显示有优化分区的选项。
图 10-41
优化分区的选项
比较各种 ADLS 第二代和雪花摄入选项
在本章的前几节中,我已经演示了几种将数据加载到雪花中的方法。在这一节中,我将比较这些不同的摄取选项,总结这些选项的优缺点。
表 10-1 显示了所有三项活动的执行管道的一些比较,比较了稳定、可扩展和成功摄取管道的关键组成部分。
表 10-1
比较各种 ADLS 第二代和雪花摄入选项
| |参数化数据块笔记本
|
数据工厂映射数据流
|
数据工厂复制活动
|
| --- | --- | --- | --- |
| 数据类型映射问题 | AdventureWorks 示例表中没有记录。 | 二进制数据类型会导致错误。 | 二进制数据类型会导致错误。 |
| 动态自动创建表格能力 | 是的(目前,自动创建表的过程正在最大限度地利用雪花中的数据类型)。 | 是的(目前,自动创建表的过程正在最大限度地利用雪花中的数据类型)。 | 否(目前,没有现成的动态自动创建表的功能)。 |
| 动态自动截断功能 | 是 | 是 | 是 |
| 管道活动审计捕获能力 | 是 | 是 | 是 |
| 需要中间斑点阶段 | 不 | 不 | 是 |
| 需要 SAS URI 认证 | 不 | 不 | 是 |
| 所需的集群预热时间或运行状态 | 是(Databricks 集群预热大约需要 5 分钟;指定核心数量、计算类型和生存时间的能力)。 | 是(映射数据流群集预热大约需要 5 分钟;指定核心数量、计算类型和生存时间的能力)。 | 不 |
| 指定计算和内核数量的能力 | 是 | 是 | 不适用(本活动不使用 Spark 计算)。 |
| 管理模式漂移/演变的能力 | 是 | 是 | 不适用的 |
| 优化分区的能力 | 是 | 是 | 不适用的 |
| 追加库(罐子、鸡蛋、轮子)的能力 | 是 | 是 | 不适用(本练习不使用 Spark 计算,因此没有附加库功能)。 |
| 运行并行活动的能力 | 是 | 是 | 是 |
泳道
由于 ADF 目前能够通过其 ForEach 循环管道活动同时并行运行 50 个表,如果需要并行运行大量的表,您可以向雪花控制表添加一个名为swim_lane
的自定义属性,然后运行下面的代码,该代码将为一组表分配一个唯一的编号,然后通过对swim_lane
列进行筛选,这些表可以通过一个活动集运行。使用这种方法,您可以在 ADF 管道中使用多个 ForEach 循环拥有多个泳道。
以下代码将更新该表以创建swim_lane
列:
UPDATE adf_db.etl.pipeline_ctl PL1
SET swim_lane = 2
FROM (SELECT src_tab_name,
Row_number()
OVER (
ORDER BY src_tab_name ) AS rn
FROM adf_db.etl.pipeline_ctl) b
WHERE PL1.src_tab_name = b.src_tab_name
AND b.rn > 5
数据有效性
有必要通过验证从源 Azure SQL 数据库服务器复制到 ADLS Gen2 并从那里复制到雪花目标表集的最终目的地的行数来执行基本的完整性检查。
这种级别的详细信息可以在您的雪花环境中的控制表中捕获,并可以命名为AUDIT_TAB
。该表将接受来自 ADF 和 Databricks 笔记本的动态传递的参数。请参见第八章和第九章,了解如何在 ADF 中构建一个健壮的日志记录框架,然后将其与本章的知识相结合,以将该日志记录流程与 ADF、Databricks 和雪花集成。
以下代码可用于在雪花 DW 中创建日志表:
CREATE OR replace TABLE audit_tab
(
pipeline_name varchar(100),
src_db_name varchar(20),
dest_db_name varchar(20),
sch_name varchar(20),
table_name varchar(50),
source_count number(38,0),
adls_count number(38,0),
snowflake_count number(38,0),
load_time timestamp_ntz(9) DEFAULT CURRENT_TIMESTAMP()
);
摘要
在本章中,我演示了一个两步流程,该流程在一个 ADF 管道中链接在一起,用于(1)将数据从 Azure SQL 数据库加载到 Data Lake Storage Account Gen2,以及(2)将数据从 Data Lake Storage Gen2 加载到雪花数据仓库。在该过程的第二部分(ADLS Gen2 到雪花),我演示了三个选项:数据块、ADF 复制活动和映射数据流。我还介绍了通过利用从第八章和第九章学到的知识,将 ADF 管道指标记录到雪花表格中的想法。最后,我比较了三个选项,以了解每个选项的优缺点。
十一、为数据仓库 ETL 映射数据流
Azure 众多数据服务的出现在数据仓库领域引发了兴奋和困惑,原因有几个。客户对现代基于云的数据仓库的概念感兴趣,但可能会被市场上过多的基于云的服务所淹没。他们想知道如何开始实施传统的数据仓库概念,例如维度建模、渐变维度(SCDs)、星型模式以及云中的数据仓库 ETL 或 ELT。SQL Server Integration Services(SSIS)等传统的内部 Microsoft 技术是成熟的数据集成工具,已经流行了十多年。随着越来越多的基于云的工具变得可用,客户有兴趣将他们的 ETL 迁移到云中,或者只是开始了解云中的数据仓库。
微软继续通过映射数据流来扩展他们在 Azure Data Factory 中的服务产品,这允许可视化和无代码的数据转换逻辑,该逻辑使用横向扩展的 Azure Databricks 集群作为 Azure Data Factory 管道的活动来执行。本质上,这一产品使 Azure Data Factory 更接近微软的传统 SQL Server Integration Services,后者已用于数据仓库 ETL 多年。映射数据流在数据仓库空间中对于几种数据仓库模式具有巨大的潜力,例如渐变维度类型 I 和类型 II 以及事实提取、转换和数据加载。
在这一章中,我将讨论典型的数据仓库负载模式,称为渐变维度类型 I,以展示如何使用 Azure Data Factory 的映射数据流来设计这种数据流模式的实际例子。
现代数据仓库
数据工厂在现代数据仓库环境中扮演着关键角色,因为它可以很好地集成结构化、非结构化和本地数据。最近,它开始与 Data Lake Storage Gen2 和 Azure Databricks 很好地集成。图 11-1 中的图表很好地描述了数据工厂在现代数据仓库中的位置。
图 11-1
现代 Azure 数据平台数据流架构图
从图 11-1 中可以看出,数据工厂是源、目标和分析系统之间的关键集成者。此外,通过添加一个无代码的基于图形用户的界面,如映射数据流,利用引擎盖下的 Spark 集群,Data Factory 肯定会在现代数据仓库的设计和开发中发挥关键作用。
创建基础 Azure 数据资源
出于本章示例练习的目的,您将需要创建一个源 OLTP 数据库以及一个包含转换维度的目标 OLAP 数据库。在第四章中,我描述了如何免费获取样本数据,比如AdventureWorksLT
表和数据,然后可以加载到 Azure SQL 数据库中。这个练习将利用与OLTP_Source
相同的AdventureWorksLT
数据库。一旦在 Azure 中创建了数据库,请注意图 11-2 中包含了您将在本练习中使用的SalesLT.Customer
表。
图 11-2
源 OLTP 和目标 OLAP 数据库
在OLAP_Target
数据库中创建下面的DimCustomer
表。DimCustomer
的模式如下:
CREATE TABLE dbo.dimcustomer
(
[customerid] INT NOT NULL,
[title] NVARCHAR (8) NULL,
[firstname] [dbo].[NAME] NOT NULL,
[middlename] [dbo].[NAME] NULL,
[lastname] [dbo].[NAME] NOT NULL,
[suffix] NVARCHAR (10) NULL,
[companyname] NVARCHAR (128) NULL,
[salesperson] NVARCHAR (256) NULL,
[emailaddress] NVARCHAR (50) NULL,
[inserteddate] DATETIME NULL,
[updateddate] DATETIME NULL,
[hashkey] NVARCHAR (128) NOT NULL,
PRIMARY KEY (customerid)
);
一旦创建了表,通过导航到 Azure Portal 中的资源组并确认数据工厂、逻辑 SQL Server、源数据库和目标数据库都已创建,验证所有必要的资源都已创建,如图 11-3 所示。
图 11-3
Azure 门户资源
缓变尺寸 I 型
渐变维度是维度数据仓库常用的高级技术,用于捕获维度内随时间变化的数据。本章中的练习将利用数据工厂管道中缓慢变化的维度类型 I。
虽然有许多类型的渐变维度,但我将在本章中介绍的类型 I 只是用新值覆盖现有的数据值。这种方法的优点是,它使维度的更新变得容易,并将增长限制在新记录上。缺点是会丢失历史数据,因为维度总是只包含每个属性的当前值。
创建数据工厂管道和数据集
通过单击“Author & Monitor”启动数据工厂控制台,开始为渐变维度类型 I ETL 模式创建 ADF 管道,如图 11-4 所示。
图 11-4
通过单击“作者和监视器”启动 Azure 数据工厂
接下来,点击“创建管道”创建一个新的管道,如图 11-5 所示。
图 11-5
创建新的 ADF 管道
将新管道命名为 DW ETL,它将包含以下两个数据集:
-
AzureSqlCustomerTable****:这是包含
AdventureWorksLT
表的 OLTP Azure SQL 源数据库。具体来说,使用Customer
表进行 ETL。 -
AzureSqlDimCustomerTable****:这是包含维度 Customer 表的 OLAP Azure SQL 目标数据库。这个维度表与 OLTP 源表的不同之处在于,它包含更少的字段,并且包含一个
InsertedDate
、UpdatedDate
和HashKey
,您将把它们用于 SCD Type I ETL 模式。
创建管道和数据集后,工厂资源部分将被填充,如图 11-6 所示。
图 11-6
ADF 管道和数据集
创建数据工厂映射数据流
现在,您已经为源和目标创建了 ADF 管道和数据集,您已经准备好使用 SCD Type I 创建您的数据流。首先,将数据流从 Activities 拖到 Data Factory 画布上,如图 11-7 所示。
图 11-7
ADF 数据流活动
然后给你的数据流一个直观的名字。此时为DimCustomer
,如图 11-8 所示。
图 11-8
DimCustomer 的 ADF 数据流活动
创建数据流之前,请确保打开数据流调试模式( https://docs.microsoft.com/en-us/azure/data-factory/concepts-data-flow-debug-mode
)
),因为您将在将管道部署到生产环境之前对其进行测试。图 11-9 显示了数据流调试模式,这对于测试是足够的。当您切换到调试模式时,系统会询问您是否希望继续。单击“确定”继续。
图 11-9
ADF 数据流调试模式
图 11-10 显示集群需要几分钟的时间准备好,准确地说通常需要 5 到 7 分钟。
ADF 在 Azure integration runtime 中为数据流生存时间(TTL)引入了一个新的“快速重用”特性。启用 TTL 后,ADF 可以在管道中执行最后一个数据流后的一段时间内维护 Spark 集群,这将在数据流活动中使用相同的 Azure IR 提供更快的连续执行。
图 11-10
ADF 数据流调试模式群集正在准备就绪
一旦打开数据流调试模式,图 11-11 所示的绿点将出现在它的右侧,以确认它已准备好开始调试模式流水线运行。此时,您可以开始创建渐变维度类型 I 数据流。
图 11-11
ADF 数据流调试模式群集准备就绪
如图 11-12 所示,通过添加和配置两个数据集作为源开始数据流。
图 11-12
ADF 映射数据流源设置
点击AzureSqlCustomerTable
旁边图 11-13 所示的+图标,添加一个派生列,称为CreateHash
。
图 11-13
ADF 映射数据流派生列
然后选择散列列并使用散列函数。对于这个场景,派生列将使用以下函数,如图 11-14 所示:
图 11-14
ADF 映射数据流派生列设置
sha1(FirstName+LastName+CompanyName)
然后将以下输入、模式和行修饰符添加到数据流中,如图 11-15 所示。
图 11-15
DimCustomer 中 SCD 类型 1 的 ADF 映射数据流活动
以下小节描述了图 11-15 中的每个步骤。
存在
Exists 步骤将通过比较新创建的源哈希键和图 11-16 所示的目标哈希键来检查哈希键是否已经存在。
图 11-16
ADF 映射数据流存在设置
外观更新
然后LookupDates
步骤将连接从源到目标的CustomerID
以确保包含相关的记录,如图 11-17 所示。
图 11-17
ADF 映射数据流查找设置
SetAttributes
SetAttributes
步骤将添加两个派生列。如果为空,InsertedDate
将插入当前时间戳,UpdatedDate
将总是用当前时间戳更新该行,如图 11-18 所示。
图 11-18
ADF 映射数据流派生列的设置
以下是图 11-18 中InsertedDate
和UpdatedDate
的列字段中使用的代码:
iif(isNull(InsertedDate),currentTimestamp(),{InsertedDate})
currentTimestamp()
交替行
AlterRows 允许 upserts,条件设置为true()
,这将更新或插入通过流的所有内容,如图 11-19 所示。
图 11-19
ADF 映射数据流改变行设置
sink1
最后,接收步骤将写回图 11-20 所示的DimCustomer
表。
图 11-20
ADF 映射数据流接收器设置
在图 11-21 所示的设置选项卡中,确保选中“允许上插”,并将CustomerID
指定为关键栏。
图 11-21
ADF 映射数据流接收器更新方法“允许向上插入”
最后,确保映射是准确的。可能需要禁用“自动映射”,如图 11-22 所示,以正确映射新创建的派生列。
图 11-22
ADF 映射数据流接收器映射
一旦完成渐变维度类型 I 数据流,它将如图 11-23 所示。
图 11-23
在 DimCustomer MDF 管道中,ADF 映射数据流已完成 SCD 类型 1
为DimCustomer
设计和配置 SCD 类型 I 数据流的过程现在已经完成。由于调试模式已经打开,只需在管道视图中点击图 11-24 中的“调试”并等待管道完成运行。
图 11-24
ADF 映射数据流管道在调试模式下运行
一旦管道完成运行,请注意管道成功状态右侧的绿色检查圈。由于DimCustomer
表中没有数据,所以这次管道运行将所有记录加载到DimCustomer
表中,如图 11-25 所示。
图 11-25
ADF 映射数据流调试模式管道成功输出
更新记录
为了测试管道的功能,从 OLTP 系统中选择一条记录,如图 11-26 所示。它可以是任何记录,为了举例,我们假设您选择了艾伦·布鲁尔的记录。
图 11-26
从 OLTP 源客户表中选择一条记录
以下是已经在图 11-26 中执行的 SQL 代码:
SELECT *
FROM [SalesLT].[customer]
WHERE customerid = 148
然后从 Brewer 更新CustomerID
148 的LastName
,更新如图 11-27 所示。
图 11-27
更新 OLTP 源客户表中的记录
以下是已经在图 11-27 中执行的 SQL 代码:
UPDATE [SalesLT].[customer]
SET lastname = 'Update'
WHERE customerid = 148;
SELECT *
FROM [SalesLT].[customer]
WHERE customerid = 148
在重新运行 ADF 管道之前,在DimCustomer
表上运行 select *查询,注意到LastName
仍然是“Brewer”,如图 11-28 所示。
图 11-28
从 OLAP DimCustomer 表中选择记录
以下是已经在图 11-28 中执行的 SQL 代码:
SELECT *
FROM [dbo].[Dimcustomer]
WHERE CustomerId = 148
重新运行 ADF 管道后,请注意图 11-29 中的LastName
已被适当更新,这确认了 ADF 管道考虑了更新。
图 11-29
更新 OLAP DimCustomer 表中的记录
以下是已经在图 11-29 中执行的 SQL 代码:
SELECT *
FROM [dbo].[DimCustomer]
插入记录
还要测试向 OLTP 系统中插入一条新记录,然后重新运行 ADF 管道,查看插入是否被拾取。为此,请执行以下示例中的 USE 和 INSERT 语句。执行以下查询,将新记录插入到[SalesLT].[Customer]
表中:
USE [OLTP_Source]
go
INSERT INTO [SalesLT].[customer]
([namestyle],
[title],
[firstname],
[middlename],
[lastname],
[suffix],
[companyname],
[salesperson],
[emailaddress],
[phone],
[passwordhash],
[passwordsalt],
[rowguid],
[modifieddate])
VALUES (1,
'Mr.',
'John',
'B',
'Doe',
NULL,
'MSSQLTips',
NULL,
NULL,
NULL,
'L/Rlwxzp4w7RWmEgXX+/A7cXaePEPcp+KwQhl2fJL7d=',
'1KjXYs4=',
'2005-08-01 00:00:00:000')
go
然后检查以确保您看到如图 11-30 所示的结果。您应该会看到刚刚插入的记录。
图 11-30
在 OLTP 客户表中选择插入的记录
以下是已经在图 11-30 中执行的 SQL 代码:
SELECT *
FROM [SalesLT].[customer]
WHERE companyname = 'MSSQLTips'
在您重新运行 ADF 管道之后,请注意图 11-31 中新的 OLTP 记录也被插入到[dbo].[DimCustomer]
表中,这确认了 ADF 管道考虑了插入。
图 11-31
选择 OLAP DimCustomer 表中的插入记录
以下是已经在图 11-31 中执行的 SQL 代码:
SELECT *
FROM [dbo].[dimcustomer]
WHERE companyname = 'MSSQLTips'
完成后,请记住关闭“数据流调试”模式,以防止数据工厂中未使用的功能产生不必要的成本。另外,记得根据需要清理并删除资源组中任何未使用的资源,如图 11-32 所示。
图 11-32
根据需要删除未使用的资源和/或资源组
摘要
在这一章中,我讨论了现代数据仓库以及 Azure Data Factory 的映射数据流及其在这一领域中的作用。您了解了如何设置源、目标和数据工厂资源,以便为使用映射数据流设计渐变维度类型 I ETL 模式做准备。此外,您还学习了如何在 Azure Data Factory 中设计和测试缓慢变化的 Dimension Type I 数据流和管道。
有几种不同类型的缓变尺寸可用于不同的目的。微软的 Azure Data Factory 提供了很多方法让快速上手使用 Data Factory 中的模板,还有为渐变维度类型 II、数据清理等添加的模板。记住要理解 Ralph Kimball 的数据仓库 工具包 作为维度建模的权威指南,这将有助于更深入地理解设计数据仓库的基本要素。
十二、使用映射数据流聚合和转换大数据
在数据湖中清理和转换大数据集的过程已经成为现代企业数据架构中越来越受欢迎和关键的一步。微软推出了几种大数据分析和编排工具,以满足大数据湖提取-加载-转换(ELT)的需求。客户正在寻求基于云的服务,这些服务可以轻松地清理、转换和聚合非常大的数据集,并且学习曲线较低。他们正在寻求了解哪些工具和技术可能符合大数据湖清理和转换的要求。
Azure Data Factory 的映射数据流已经成为大数据湖清理和转换的一个有前途的解决方案。在第十一章中,我讨论了现代数据仓库的概念,并展示了一个为企业数据仓库转换映射数据流的实际例子。在本章中,我将继续演示映射数据流的其他数据清理和聚合功能,特别是处理作为分层文件存储在 Azure Data Lake Storage Gen2 中的大数据文件。
将文件和文件夹添加到 Azure 数据湖存储二代
通过使用最佳实践来正确构建数据湖存储是关键。当数据存储在 Data Lake Storage Gen2 中时,文件大小、文件数量和文件夹结构会对性能产生影响。
文件大小
根据使用数据的服务和工作负载,文件的合适大小是 256 MB 或更大。如果在数据湖存储中无法对文件大小进行批处理,您可以进行单独的压缩作业,将这些文件合并成更大的文件。
文件夹结构
文件夹和文件的组织结构可以帮助某些查询只读取数据的子集,这通过优化较大的文件大小和每个文件夹中合理的文件数量来提高性能。了解性能调优和优化技术,以及文件夹和文件结构建议。
在本练习中,您将学习如何创建一个名为湖的 ADLS Gen2 容器,以及一些用于组织 2016 年数据的附加文件夹。首先,请确保您已经设置了 ADLS Gen2 帐户和 ADF 帐户。接下来,您需要将 2016 年的销售文件从以下 GitHub 账户(
https://github.com/ronlesteve/sales-datasets
)
上传到如图 12-1 所示的 ADLS Gen2 文件夹结构中。
从图 12-1 中我们可以看到,在 2016 年的销售文件夹中,额外的文件夹是按月份编号组织的。
图 12-1
按月份编号组织的 2016 年销售文件夹
每个月内,有。按天整理保存的 txt 文件,如图 12-2 所示。
图 12-2
按月日文本文件组织的 2016 年销售文件夹
最后,在打开其中一个文本文件时,请注意图 12-3 中的数据结构,该数据结构由以下选中的列组成。
图 12-3
文本文件的结构
创建 Azure 数据工厂资源
既然数据湖文件和文件夹已经被结构化了,是时候创建必要的 Azure 数据工厂资源了。数据工厂打开后,开始创建新的管道,如图 12-4 所示。
图 12-4
创建新的 ADF 管道
接下来,添加一个新的数据集,该数据集将引用具有以下连接属性的 lake 容器。请注意,图 12-5 中的目录和文件属性被留空,因为这可以在映射数据流属性中动态设置。另外,将列分隔符设置为制表符() 。
图 12-5
ADLS 第二代数据集连接属性
发布资源后,图 12-6 中的工厂资源部分将可用。这些资源由管道和数据集组成。
图 12-6
ADF 管道和数据集资源
在新创建的管道中,从 Activities 中展开 Move & Transform ,然后将如图 12-7 所示的数据流活动拖到画布上。
图 12-7
ADF 数据流活动
创建映射数据流
现在您已经准备好创建如图 12-8 所示的数据流活动。
图 12-8
ADF 销售订单数据流
首先,将图 12-9 中所示的源连接添加到上一节中创建的 SalesOrderDataset 中。
图 12-9
与 SalesOrderDataset 的 ADF 数据流源连接
确保允许模式漂移,因为文件中可能会有更改的列。此外,选择推断漂移柱类型允许自动检测漂移柱类型。这些选项如图 12-10 所示。
图 12-10
ADF 源数据流设置
将 2016 年参数化,这样就可以在硬编码路径之外维护这些值。要添加参数,单击映射数据流画布中的空白区域,然后选择并添加所需的参数,如图 12-11 所示。
图 12-11
ADF 源数据集参数
添加参数后,返回到“源选项”选项卡。在源选项下,在通配符路径中添加 2016 sales 文件夹的路径。此设置将覆盖数据集中设置的文件夹路径,从容器根目录开始。 ****** 将允许递归目录嵌套。最后,使用 *.txt. 指定所有需要的文本文件。信号源选项选项卡的这些设置已在图 12-12 中列出。
图 12-12
ADF 源选项
以下是添加到图 12-12 中源选项选项卡的通配符路径字段的代码:
'DataLakeCleansing/raw/sales/'+$Year+'/**/*.txt'
在图 12-13 所示的投影选项卡中,验证并更改列模式。
图 12-13
ADF 数据流源投影
接下来,添加一个如图 12-14 所示的选择模式修饰符来删除需要的列。为此,单击源活动旁边的+图标,并添加 Select schema 修饰符。请注意,还有许多其他选项可以用来转换数据和模式。
图 12-14
ADF 映射数据流“选择”修饰符活动
也可以选择跳过重复的选项,如图 12-15 所示。
图 12-15
ADF 数据流“选择设置”以跳过重复项
接下来,添加一个派生列模式修饰符来添加两个新列,如图 12-16 所示:
图 12-16
ADF 数据流派生列
-
基于
OrderDate
的订单月数 -
年数也基于
OrderDate
派生列非常适合通过表达式的力量进行数据清理。
正则表达式(Regex)
正则表达式是指定搜索模式的字符序列。通常,字符串搜索算法使用这种模式对字符串进行“查找”或“查找和替换”操作,或者进行输入验证。它是在理论计算机科学和形式语言理论中发展起来的一种技术。正则表达式函数与映射数据流兼容,可以添加到 ADP 管道内的活动中。以下是一些示例正则表达式及其预期用途:
-
RegexReplace(Address,
^a-zA-Z\d\s:,'')
:删除所有非字母数字字符 -
RegexReplace(Address,
[ ]{2}|.,' ')
:获取包含街道地址字符串的地址字段,并替换任何出现的两个空格或点“.”只有一个空格。 -
Regex_extract(Address,
^(\d+), 1)
:使用街道地址提取门牌号。
桑迪克斯
Soundex 是一种语音算法,用于通过声音索引姓名,如在英语中发音为。目标是将同音字编码为相同的表示,这样即使拼写有微小差异,它们也可以匹配。
当在湖中处理半结构化或非结构化数据时,这是一个很好的表达方式,可以用来解决在没有键的情况下连接和清理数据的问题。
接下来,添加一个如图 12-17 所示的聚合模式修饰符来聚合单价*数量。
图 12-17
ADF 数据流聚合架构修饰符
请记住按图 12-18 中所示的以下各列对该聚合进行分组。
图 12-18
按聚合设置分组的 ADF 数据流
图 12-19 显示了您需要输入总计算值的位置。
图 12-19
ADF 数据流聚合
现在聚合已经完成,添加一个 Windows 模式修饰符,如图 12-20 所示。
窗口转换是在数据流中定义基于窗口的列聚合的地方。在表达式生成器中,您可以定义基于数据或时间窗口(SQL OVER 子句,如 LEAD、LAG、NTILE、CUMEDIST、RANK 等)的不同类型的聚合。).将在您的输出中生成一个包含这些聚合的新字段。您还可以包括可选的分组依据字段。
图 12-20
ADF 数据流窗口架构修饰符
图 12-21 展示了如何通过CustomerName
对总数进行排序。
图 12-21
“结束”的 ADF Windows 设置
图 12-22 显示了如何按降序排列总数,从最高到最低排列总数。
图 12-22
“排序”的 ADF 窗口设置
将范围 by 设为无界,如图 12-23 所示。
图 12-23
“范围依据”的 ADF 窗口设置
接下来,在总数中添加一个密集排名函数。请注意,有一些秩和行数函数适合特定的需求和用例。
等级函数
RANK 函数用于根据 ORDER BY 子句的条件检索已排序的行。
表 12-1
秩函数样本输出
|易名中国
|
盐
|
等级
|
| --- | --- | --- |
| 史密斯 | eight hundred | one |
| 詹姆斯 | Nine hundred and fifty | Two |
| 亚当斯 | One thousand one hundred | three |
| 马丁 | One thousand two hundred and fifty | four |
| 病房 | One thousand two hundred and fifty | four |
| 车工 | One thousand five hundred | six |
下面是一个包含 RANK 函数的示例查询:
SELECT ename,
sal,
Rank()
OVER (
ORDER BY sal) RANK
FROM emp;
表 12-1 显示了在样本数据集上运行的 RANK 函数的样本输出。
稠密秩函数
DENSE_RANK 函数类似于 RANK 函数。但是,如果前面记录的等级之间存在关联,DENSE_RANK 函数不会跳过任何等级。
以下是包含 DENSE_RANK 函数的示例查询:
SELECT ename,
sal,
Dense_rank()
OVER (
ORDER BY sal) DEN_RANK
FROM emp;
表 12-2 显示了在样本数据集上运行的 DENSE_RANK 函数的样本输出。
表 12-2
DENSE_RANK 函数示例输出
|易名中国
|
盐
|
等级
|
| --- | --- | --- |
| 史密斯 | eight hundred | one |
| 詹姆斯 | Nine hundred and fifty | Two |
| 亚当斯 | One thousand one hundred | three |
| 马丁 | One thousand two hundred and fifty | four |
| 病房 | One thousand two hundred and fifty | four |
| 车工 | One thousand five hundred | five |
行数函数
与 RANK 和 DENSE_RANK 函数不同,ROW_NUMBER 函数只返回从 1 开始排序的记录的行号。ADF 中映射数据流转换任务的窗口设置如图 12-24 所示。
图 12-24
“窗口栏”的 ADF 窗口设置
窗口功能完成后,添加一个 sink 将丰富的结果存储在数据湖中,如图 12-25 所示。
图 12-25
用于存储丰富数据的 ADF 数据流接收器
使用图 12-26 中所示的以下 sink 数据集设置,并记住选中允许模式漂移选项。Azure Data Factory 本身支持灵活的模式,这些模式会随着执行的不同而变化,因此您可以构建通用的数据转换逻辑,而无需重新编译您的数据流。
模式漂移是数据源经常改变元数据的情况。可以动态地添加、删除或更改字段、列和类型。如果不处理模式漂移,您的数据流将很容易受到上游数据源更改的影响。当传入的列和字段发生变化时,典型的 ETL 模式会失败,因为它们往往与那些源名称联系在一起。
为了防止模式漂移,作为一名数据工程师,让数据流工具中的设施允许您
-
定义具有可变字段名、数据类型、值和大小的源。
-
定义可以处理数据模式而不是硬编码字段和值的转换参数。
-
定义理解模式的表达式以匹配传入字段,而不是使用命名字段。
图 12-26
ADF 数据流接收器数据集连接属性
另外,将设置配置为输出到单个文件并指定文件名,如图 12-27 所示。
图 12-27
ADF 数据流接收器设置
映射数据流的好处之一是数据流调试模式,它允许预览转换后的数据,而不必手动创建集群和运行管道。
记得打开调试模式以便预览如图 12-28 所示的数据,然后在退出 Azure Data Factory 之前关闭它。请注意,调试模式将在一段时间后自动终止。
图 12-28
ADF 数据流调试触发器
按客户排序的总结果将类似于图 12-29 中显示的结果。
图 12-29
按客户排列的总结果
下一个练习将向您展示如何将总计分割成一个新的分支,以创建一个具有不同窗口函数的新文件,这次将按月对总计进行排序,并将结果输出到数据湖中的不同文件,如图 12-30 所示。
图 12-30
将总聚合拆分为新分支
确保新窗口功能的设置如图 12-31 所示。
图 12-31
按月排列总数并将结果输出到文件的设置
一旦映射数据流完成,它将如图 12-32 所示。
图 12-32
完整的端到端 ADF 映射数据流
摘要
在本章中,我演示了如何创建一个指向数据湖容器的数据集。接下来,我向您展示了如何向 2016 sales 文件夹中的所有文本文件添加参数化通配符路径。然后,我向您展示了如何选择相关的列,添加几个关键的派生列,执行聚合,添加窗口函数,分割分支,以及将所需的结果导出到数据湖中的富文本文件。
输出数据集包含按客户名称和月份进行聚合和降序排列的总计(单价*数量)。所有这些都是通过利用 Azure Data Factory 的映射数据流特性完成的,并使用数据流调试功能进行了测试。
十三、增量插入数据
如果你还记得从第 4 到第六章,我演示了如何做到以下几点:
-
从 SQL 数据库完全加载 Azure 数据湖存储二代。
-
使用 Azure Data Factory 的复制活动,使用数据湖存储二代 parquet 文件完全加载 Azure Synapse Analytics DW。
这个 ELT 过程由元数据方法驱动,使用 SQL 表中填充的管道参数。虽然这是一种有用的 ELT 方法,但本章将重点推进这一过程,以解决以下问题:
-
从 SQL 源增量加载 Azure 数据湖存储。
-
将增量记录更新并插入 Azure Synapse Analytics 数据仓库目标。
在这一章中,我将演示 Azure Data Factory 的映射数据流的内置 upsert 功能,以更新 Azure Data Lake Storage gen 2 parquet 文件中的数据并将其插入 Azure Synapse Analytics DW。值得注意的是,映射数据流目前不支持本地数据源和接收器。因此,本练习将利用 Azure SQL 数据库作为创建数据集的源。此外,我将演示如何使用一种定制方法,根据 Azure SQL 数据库中的创建日期,用 parquet 文件增量填充 Data Lake Storage Gen2。本章假设您熟悉本书前面的章节,这些章节讨论了使用 Azure Data Factory 的元数据驱动的 ETL 方法。
创建参数表
让我们从在 Azure SQL 数据库中创建一个pipeline_parameter
表开始这个过程。您已经在前面的章节中创建了它,您只需要添加下面列出的附加列。正如我们在前面章节中回忆的那样,此表将包含用于控制 ADF 管道的参数值:
-
upsert_key_column :这是映射 upsert 流程的数据流必须使用的键列。它通常是一个 ID 列。
-
incremental _ watermark _ value:必须用源 SQL 表的值填充,以驱动增量过程。这通常是主键 ID 或创建/最后更新日期列。它可以通过存储过程进行更新。
-
incremental _ watermark _ column:这只是填充在
incremental_watermark_value
列中的值的列名。这通常是主键 ID 或创建/最后更新日期列。它可以通过存储过程进行更新。 -
process_type :必须设置为 incremental,ADF 才能知道这个表中哪些记录是增量的。
以下是复制更新后的pipeline_parameter
表的 SQL 代码:
SET ansi_nulls ON
go
SET quoted_identifier ON
go
CREATE TABLE [dbo].[pipeline_parameter]
(
[parameter_id] [INT] IDENTITY(1, 1) NOT NULL,
[server_name] NVARCHAR NULL,
[src_type] NVARCHAR NULL,
[src_schema] NVARCHAR NULL,
[src_db] NVARCHAR NULL,
[src_name] NVARCHAR NULL,
[dst_type] NVARCHAR NULL,
[dst_name] NVARCHAR NULL,
[include_pipeline_flag] NVARCHAR NULL,
[partition_field] NVARCHAR NULL,
[process_type] NVARCHAR NULL,
[priority_lane] NVARCHAR NULL,
[pipeline_date] NVARCHAR NULL,
[pipeline_status] NVARCHAR NULL,
[load_synapse] NVARCHAR NULL,
[load_frequency] NVARCHAR NULL,
[dst_folder] NVARCHAR NULL,
[file_type] NVARCHAR NULL,
[lake_dst_folder] NVARCHAR NULL,
[spark_flag] NVARCHAR NULL,
[dst_schema] NVARCHAR NULL,
[distribution_type] NVARCHAR NULL,
[load_sqldw_etl_pipeline_date] [DATETIME] NULL,
[load_sqldw_etl_pipeline_status] NVARCHAR NULL,
[load_sqldw_curated_pipeline_date] [DATETIME] NULL,
[load_sqldw_curated_pipeline_status] NVARCHAR NULL,
[load_delta_pipeline_date] [DATETIME] NULL,
[load_delta_pipeline_status] NVARCHAR NULL,
[upsert_key_column] NVARCHAR NULL,
[incremental_watermark_column] NVARCHAR NULL,
[incremental_watermark_value] [DATETIME] NULL,
PRIMARY KEY CLUSTERED ( [parameter_id] ASC )WITH (statistics_norecompute =
OFF, ignore_dup_key = OFF) ON [PRIMARY]
)
ON [PRIMARY]
go
为 ADF 管道创建源查询
现在您已经创建了pipeline_parameter
,编写一个定制的 SQL 查询,它将被用作 ADF 管道的源。注意添加了SQLCommand
和WhereValue
,它们可以用于根据流程类型是完整的还是增量的来动态创建定制的 SQL 语句和 where 子句。出于本练习的目的,仅对增量值应用过滤器,但是该查询展示了将全部负载合并到同一源查询中的灵活性。我们的疑问是:
SELECT src_schema,
src_db,
src_name,
dst_schema,
dst_type,
dst_name,
dst_folder,
process_type,
file_type,
load_synapse,
distribution_type,
upsert_key_column,
incremental_watermark_column,
CASE
WHEN process_type = 'FULL' THEN 'select * from ' + src_schema + '.' +
src_name
+ ' where 1 = '
WHEN process_type = 'Incremental' THEN
'select * from ' + src_schema + '.' + src_name
+ ' where ' + incremental_watermark_column
+ ' > '
END AS SQLCommand,
CASE
WHEN process_type = 'FULL' THEN '1'
WHEN process_type = 'incremental' THEN Cast(
Isnull(incremental_watermark_value, 'yyyy-MM-dd') AS VARCHAR(50))
END AS WhereValue,
dst_folder + '/' + dst_name + '/' + file_type + '/'
+ Format(Getdate(), 'yyyy-MM-dd') AS FolderName,
dst_name + '.' + file_type AS FileName
FROM dbo.pipeline_parameter
WHERE load_synapse = 1
AND process_type = 'incremental'
请注意,在本练习中,源查询将嵌入到 ADF 管道中。作为最佳实践,考虑将查询转换为存储过程,以便更容易地维护 ADF 管道之外的集中式 SQL 数据库中的 SQL 代码。
图 13-1 显示了在 SQL Server Management Studio (SSMS)中,在用一个您想要通过 ADF 管道运行的增量记录填充pipeline_parameter
之后,执行查询的结果。请注意,SQLCommand
列构建了将由 ADF 管道使用的增量源查询。
图 13-1
将用作 ADF 管道源的自定义 SQL 查询
以下是包含在图 13-1 中的SQLCommand
列中的 SQL 查询。这个SQLCommand
在与WhereValue
结合时动态形成源 SQL 查询,该查询可以作为 ADF 管道中的参数进行集成和调用。创建此流程的目的是展示动态构建源 SQL 查询,然后将它们集成到 ADF 管道中的强大功能:
select * from db.Log where CreatedDt >
添加 ADF 数据集
接下来,转到 ADF 并创建以下小节中描述的数据集。您需要创建三个数据集。您需要 Azure SQL 数据库中的源数据集、用于映射数据流的 Azure Data Lake Storage Gen2 数据集,以及最终作为目标的 Azure Synapse Analytics 数据集。
蓝色数据库
将需要 Azure SQL 数据库作为 ADF 管道中数据集的源。出于本练习的目的,您将需要使用驻留在这个 Azure SQL 数据库上的日志表。图 13-2 很好地展示了这个源连接在创建后在数据集视图中的样子。
图 13-2
ADF Azure SQL DB 源数据集
Azure 数据湖存储第二代
此外,还需要 Azure Data Lake Storage Gen2 数据集在映射数据流中使用,以创建拼花文件。这个 ADLS Gen2 帐户将作为来自 SQL 数据库的拼花文件的登录区。图 13-3 展示了一旦成功创建,该连接和文件路径设置将如何显示。注意参数化的文件夹名称,它来自源查询中的FolderName
列。
图 13-3
Azure 数据湖存储第二代数据集
还将以下参数添加到拼花配置部分,如图 13-4 所示。FolderName
和FileName
都来自前面几节中列出的源 SQL 查询。
图 13-4
拼花地板配置参数
Azure Synapse 分析数据仓库
最后,您将需要一个 Azure Synapse Analytics DW 目标数据集来存储从源系统中识别的初始和增量数据。将使用 ADF 中的映射数据流来构建这个转换步骤。图 13-5 显示了成功连接到 Synapse 分析数据集的情况。注意,表名有一个动态定义,模式将被一致地定义为“etl”。
图 13-5
Azure Synapse 分析数据仓库目标数据集
创建 ADF 管道
现在,您已经创建了所需的数据集,是时候开始配置 ADF 管道活动了,方法是添加一个查找活动来获取表列表,添加一个 ForEach 循环活动来复制每个表,添加一个映射数据流活动来将数据从 ADLS Gen2 增量复制到 Synapse Analytics DW。该管道将展示使用 ADF 的映射数据流将数据从源向上插入到接收器的端到端能力。
添加一个查找活动来获取表的列表
首先,向 ADF 管道画布添加一个查找活动,以获取 ADF 管道所需的表。图 13-6 显示了您需要添加在前面步骤中创建的查询的位置。
图 13-6
ADF 源数据集设置
添加一个 ForEach 活动来迭代和复制每个表
当连接到查找活动时,ForEach 循环活动将遍历每个表,并将该表从 ADLS Gen2 复制到 Synapse Analytics DW。图 13-7 显示了如何在 ADF 管道中配置 ForEach 循环活动设置。
图 13-7
ADF ForEach 循环设置
将 SQL 的数据流映射到 Lake 增量 ADF 管道
现在,您可以开始为从源 Azure SQL 数据库到接收器数据湖存储二代 parquet 文件夹和文件的增量负载构建映射数据流。FolderName
和FileName
是在源 ADLS Gen2 拼花数据集内创建的,并在制图数据流中用作源,如图 13-8 所示。
图 13-8
ADF SQL 到湖数据流设置
参数为SQLCommand
、WhereValue
、FileName
,如图 13-9 所示。这些参数将用于生成源增量查询字符串。
图 13-9
ADF SQL 到湖数据流参数
映射数据流的源设置如图 13-10 所示:
图 13-10
ADF SQL 到湖数据流源连接设置
-
允许模式漂移:如果源列经常改变,则选择允许模式漂移。此设置将允许来自源的所有传入字段通过转换流向接收器。
-
推断漂移列类型:允许自动检测漂移列类型。
-
验证模式:如果 Projection 选项卡中定义的任何列和类型与传入数据不匹配,设置该选项将导致数据流失败。
-
采样:如果投影选项卡中定义的任何列和类型与输入数据不匹配,设置此选项将导致数据流失败。
数据流的源选项配置如图 13-11 所示,使用映射数据流 ( https://docs.microsoft.com/en-us/azure/data-factory/concepts-data-flow-expression-builder
)内的字符串插值表达式特性。注意,SQLCommand
和WhereValue
字段被连接起来形成一个动态 SQL 查询。
图 13-11
ADF SQL 到湖数据流源选项
接下来,配置映射数据流的目的 sink,如图 13-12 所示。
图 13-12
ADF 数据流目标接收器连接属性
图 13-13 中显示的设置将指示从本章前面章节中列出的 SQL 查询生成的FileName,
的单个文件输出。
图 13-13
ADF 数据流目标设置
在优化选项卡中使用单一分区,如图 13-14 所示。
图 13-14
ADF 数据流目标分区优化属性
单一分区将所有分布式数据合并到一个分区中。这是一个非常慢的操作,还会显著影响所有下游转换和写入。Azure Data Factory 强烈建议不要使用此选项,除非有明确的业务原因。
通过选择 Set Partitioning 选项,您将看到以下分区选项。
一系列
循环调度在分区之间平均分配数据。当您没有合适的关键字候选来实现可靠的分区策略时,您可以使用循环法,因为循环法将数据平均分布在各个分区上,并允许您设置物理分区的数量。
混杂
ADF 创建列的散列来产生统一的分区,以便具有相似值的行落在同一个分区中。当您使用 Hash 选项时,测试可能的分区倾斜是很重要的。此外,您可以设置物理分区的数量。
动态量程
动态范围基于您提供的列或表达式使用 Spark 动态范围。您可以设置物理分区的数量。
固定范围
构建一个表达式,为分区数据列中的值提供固定的范围。为了避免分区倾斜,在使用这个选项之前,您应该对您的数据有一个很好的了解。您为表达式输入的值用作分区函数的一部分。您可以设置物理分区的数量。
钥匙
如果您对数据的基数有很好的理解,那么键分区可能是一个不错的策略。键分区为列中的每个唯一值创建分区。您不能设置分区数量,因为该数量基于数据中的唯一值。
默认情况下,选择“使用当前分区”,指示 Azure Data Factory 保持转换的当前输出分区。由于对数据进行重新分区需要时间,因此在大多数情况下,建议使用当前分区。
通过单击映射数据流画布的空白区域,将出现映射数据流参数选项卡。增加如图 13-15 所示的以下参数。
图 13-15
ADF 映射数据流参数
将数据流映射到从 Lake 到 Synapse Analytics 数据仓库的增量插入
既然您已经创建并配置了 SQL 到 lake 的增量映射数据流管道,那么是时候创建并配置 lake 到 Synapse 的增量上插管道了,如图 13-16 所示。
图 13-16
ADF 数据流湖到 Synapse 增量向上插入管道设置
务必为FolderName
和upsert_key_column
配置以下数据流参数,如图 13-17 所示。这些参数将用于增量数据摄取过程。
图 13-17
ADF 数据流湖到 Synapse 增量向上插入管道参数
该数据流将包含以下三项活动:
-
SrcLake :这是到 ADLS Gen2 账户的源连接。
-
AlterRow :这是通过识别哪些行需要向上插入到接收器中来开始向上插入过程的步骤。
-
dstSynapse :这是 Synapse Analytics DW 的接收连接。
首先配置湖源的设置,如图 13-18 所示。
图 13-18
ADF 数据流源设置
接下来,确保源选项选项卡包含参数化的FolderName
,如图 13-19 所示。
图 13-19
ADF 数据流源选项
图 13-20 显示了如何添加一个 AlterRow 转换活动,然后在行条件等于true()
时将 alter row 条件设置为 Upsert。
图 13-20
AlterRow 转换活动设置
在图 13-21 所示的优化选项卡中,使用当前分区,但也要注意可能有机会探索为大数据工作负载设置分区并提高性能。
图 13-21
AlterRow 转换活动分区优化选项
最后,配置目标 Synapse Analytics DW 数据集,如图 13-22 所示。
图 13-22
ADF 数据流接收器连接属性
在设置选项卡中,如图 13-23 所示,选择“允许上插”作为更新方法,并添加您创建并填充在管道参数表中的upsert_key_column
。在本练习中,您可以选择不启用转移,但这对于性能优化来说可能是一个不错的选择。
图 13-23
ADF 数据流接收器设置
最后,确保映射数据流参数包含图 13-24 所示的FolderName
和upsert_key_column,
。要获得这些参数,请记住单击映射数据流画布的空白区域。
图 13-24
ADF 数据流参数
运行 ADF 管道
现在 ADF 管道已经构建好了,是时候运行它们了,以便测试和验证 Azure SQL 到 ADLS Gen2 管道和 ADLS Gen2 到 Synapse Analytics DW 管道的结果。此外,作为验证步骤,本节将使用 SSMS 对源数据库和接收数据库运行 SQL 计数,以进一步测试、验证和确认结果的准确性。
验证增量 SQL 到 Lake 管道结果
运行此管道后,注意图 13-25 中端到端管道成功复制了一个表,因为pipeline_parameter
表中只有一条记录。
图 13-25
“成功”的 ADF 增量管道状态
图 13-26 显示管道从源 Azure SQL 数据库表复制了 493 行到 ADLS Gen2 中的一个 parquet 文件。
图 13-26
ADF 数据流增量管道处理详细信息
验证增量上插湖到 Synapse ADF 管道结果
是时候验证增量 ADF 管道已经将相关数据从 ADLS Gen2 转移到 Synapse Analytics DW。图 13-27 显示来自 ADLS Gen2 的增量 upsert 复制了超过 493 行到 Synapse Analytics DW。
图 13-27
ADF 数据流增量向上插入管道处理详细信息
验证源 SQL 记录计数
之所以有 493 行,如图 13-28 所示,是因为源包含 493 行,其创建日期大于 2020 年 4 月 1 日,并且由于这是您在pipeline_parameter
表中定义的incremental_watermark_value
,这就是 ADF 管道预计增量加载的记录数。
图 13-28
用于验证的 SSMS 记录计数
以下是图 13-28 中显示的 SQL 查询:
SELECT Count(logid) AS IncrementalRecordCount
FROM [dbo].[log]
WHERE createddt > '04-01-2020'
验证湖文件夹和拼花文件路径
还要确认 ADLS Gen2 文件夹和一个拼花文件已经创建,如图 13-29 所示。
图 13-29
包含来自 ADF 管道的拼花文件的 ADLS Gen2 文件夹
验证目标 Synapse 记录计数
最后,在目标 Synapse Analytics DW 表上运行 SQL count 语句后,图 13-30 中显示的计数确认有 493 条记录,证明增量管道按预期工作。
图 13-30
接收器中增量管道记录的 SSMS 计数
以下是图 13-30 中显示的 SQL 查询:
SELECT Count(logid) AS IncrementalRecordCount
FROM [etl].[log]
WHERE createddt > '04-01-2020'
插入源 SQL 记录
既然您已经确认了 Synapse Analytics DW 管道的增量 SQL 按预期工作,那么还需要通过向源 SQL 表添加一条创建日期大于 2020 年 4 月 1 日的额外记录来验证 Upsert 命令的插入部分是否按预期工作。
添加记录并运行计数后,请注意查询现在返回 494 条记录,而不是 493 条,如图 13-31 所示。
图 13-31
插入源记录的 SQL 计数
以下是图 13-31 中显示的 SQL 查询:
SELECT Count(logid) AS IncrementalRecordCount
FROM [dbo].[log]
WHERE createddt > '04-01-2020'
验证 Lake ADF 管道结果的增量 SQL
再次运行管道,注意新的管道日志结果从 SQL 到 lake 返回计数 494,如图 13-32 所示。
图 13-32
ADF 数据流增量管道执行详细信息
验证增量上插湖到 Synapse ADF 管道结果
此外,请注意,新的管道日志结果从 lake 向 Synapse Analytics DW 返回 494 的计数,如图 13-33 所示。
图 13-33
ADF 数据流增量向上插入管道执行详细信息
验证目标 Synapse Analytics 数据仓库记录计数
最后,图 13-34 中所示的目标 Synapse Analytics DW 表也包含 494 条记录,这证实了插入按预期工作。
图 13-34
目标 Synapse Analytics 数据仓库记录的 SQL 计数
以下是图 13-34 中显示的 SQL 查询:
SELECT Count(logid) AS IncrementalRecordCount
FROM [etl].[log]
WHERE createddt > '04-01-2020'
更新源 SQL 记录
运行最后一个测试,以确保映射数据流 upsert 的更新命令按预期工作。对于这个测试,更新表,将FacilityId
设置为等于 100,其中创建日期大于 2020 年 4 月 1 日。图 13-35 显示了这个脚本如何更新源 SQL 表中的两行。
图 13-35
更新源记录的 SQL
验证目标 Synapse Analytics 数据仓库记录计数
正如所料,目标 Synapse Analytics DW 表当前没有FacilityID
= 100 的记录,如图 13-36 所示。
图 13-36
验证目标表上的预更新的 SQL
以下是图 13-36 中显示的 SQL 查询:
SELECT Count(logid) AS IncrementalRecordCount
FROM [etl].[log]
WHERE facilityid = 100
再次运行管道后,请注意图 13-37 中的目标 Synapse Analytics DW 表仍然包含 494 行,并且有两条记录的FacilityId
已经更新为 100。这最终确认了更新和插入命令以及从源 SQL 表到 ADLS Gen2 并最终到 Synapse Analytics DW 的增量加载都按预期工作。
图 13-37
验证目标表的更新记录的 SQL
以下是图 13-37 中显示的 SQL 查询:
SELECT Count(logid) AS IncrementalRecordCount
FROM [etl].[log]
SELECT Count(logid) AS IncrementalRecordCount
FROM [etl].[log]
WHERE facilityid = 100
摘要
在这一章中,我展示了 Azure Data Factory 的 Mapping Data Flows upsert 特性的一些功能,这些功能用于更新数据并将数据从 Azure Data Lake Storage gen 2 parquet 文件插入 Azure Synapse Analytics DW。我向您展示了如何构建一个定制方法,根据 Azure SQL 数据库中的创建日期用 parquet 文件增量填充 Data Lake Storage Gen2,并测试和验证结果。值得一提的是,这种从源到接收器递增加载数据的定制方法是可以使用的许多可能方法之一。Microsoft、ADF 产品团队和各种社区贡献者经常在博客上讨论使用 ADF 从源到接收器增量加载数据的替代方法。
十四、将 Excel 表加载到 Azure SQL 数据库表中
将 Excel 电子表格中的数据加载到 SQL 数据库中是许多组织多年来的一项长期需求。以前,诸如 VBA、SSIS、C#等工具被用来执行这个数据摄取编排过程。微软 Azure 的Excel connector(
https://docs.microsoft.com/en-us/azure/data-factory/format-excel
)
for Azure Data Factory(ADF)是一个很有前途的基于云的连接器,它允许使用 Excel 的易用、低代码体验,很像内部部署的 SSIS Excel 连接器。
Azure Data Factory 中的 Excel 连接器提供了利用动态和参数化管道的能力,以便使用 ADF 将 Excel 电子表格加载到 Azure SQL 数据库表中。在这一章中,我将演示如何动态地将包含多个工作表的 ADLS Gen2 帐户中的 Excel 电子表格加载到单个 Azure SQL 表中,以及每个工作表的多个表中。
先决条件
成功创建端到端 ADF 管道以将 Excel 文件加载到关系 SQL 数据库需要几个设置步骤。首先,您需要做一些准备工作来创建所需的 Excel 电子表格。然后你需要把它上传到 ADLS 第二代账户。最后,您需要在 ADF 中创建相应的链接服务和数据集,为 ADF 管道的创建做准备。
创建 Excel 电子表格
图 14-1 中的图像显示了一个包含四个工作表的 Excel 电子表格示例,每个工作表都包含相同的标题和模式,您将需要在 ADF 管道中使用它们来加载 Azure SQL 表中的数据。期望这四个表都有相同的模式、列顺序和标题。该过程不测试极限情况,例如模式漂移、Excel 文件中的嵌入图像等等。你可以在我的 GitHub repo 中找到一个样本 Excel 文件,SampleExcelFiles,在下面: https://github.com/ronlesteve/SampleExcelFiles
。
图 14-1
包含四张数据工作表的 Excel 电子表格示例
上传到 Azure 数据湖存储二代
创建 Excel 电子表格后,将电子表格上传至您的 ADLS Gen2 账户,如图 14-2 所示。
图 14-2
Excel 文件已加载到 ADLS Gen2
创建链接的服务和数据集
在数据工厂中,为 Excel 电子表格的文件路径添加一个 ADLS Gen2 链接服务,该服务已经添加到data/raw/ExcelSpreadSheet
文件夹路径中,如图 14-3 所示。提醒一下,由于 ADLS Gen2 是一个分层的文件系统,ADF 管道将能够轻松地遍历多个文件夹层次结构来定位文件。
图 14-3
Excel 电子表格位置的 ADLS Gen2 链接服务
图 14-4 显示了 ADLS 第二代连接的正确配置属性。确保 ADLS 第二代链接服务凭据配置准确。
图 14-4
ADLS 第二代链接服务凭据
创建新数据集时,注意图 14-5 中我们有一个 Excel 格式的选项,可以选择。
图 14-5
Excel 数据集格式
Excel 数据集的连接配置属性可在图 14-6 中找到。工作表名称属性需要用动态参数化的@dataset().SheetName
值进行配置。此外,由于文件中存在标题,请选中“第一行作为标题”同样,本练习假设电子表格中没有浮动图像。此外,本练习中没有测试模式漂移和额外的头。
图 14-6
Excel 数据集连接属性
在参数页签内,添加SheetName
,如图 14-7 所示。该参数将在 Excel 文件中存储工作表的名称,该文件提供 ForEach 循环活动,该循环活动遍历每个工作表并将它们加载到 SQL 数据库中。
图 14-7
Excel 数据集参数属性
接下来,将一个接收数据集添加到目标 Azure SQL 表,并连接到适当的链接服务,如图 14-8 所示。请注意,虽然您已经指定了包括模式和表名的硬编码表路径,但是您不需要担心在 SQL 数据库中创建这个对应的表。在 ADF 中,当在管道中配置接收器数据集属性时,您需要启用一个属性,以便根据源 Excel 文件的传入架构“自动创建”表,您将在本章后面了解该属性。
图 14-8
Azure SQL 接收器数据集连接属性
概括地说,在本节中,您已经创建了必要的先决条件,包括创建 Excel 电子表格并将其上传到 ADLS Gen2,以及创建数据集和链接服务。至此,您已经准备好进入下一部分,在这里您将学习如何创建实际的 ADF 管道来将 Excel 电子表格加载到 Azure SQL 数据库表中。
创建一个管道,将电子表格中的多个 Excel 表加载到单个 Azure SQL 表中
现在,让我们创建一个管道,将单个电子表格文件中的多个 Excel 表加载到单个 Azure SQL 表中。在 ADF 窗格中,创建一个新管道,然后将 ForEach 循环活动添加到管道画布中。接下来,单击管道中画布的空白区域,添加一个名为SheetName
的新数组变量,该变量包含电子表格中从 Sheet1 到 Sheet4 的所有工作表的默认值,如图 14-9 所示。
图 14-9
ADF ForEach 循环连接变量
接下来,点击 ForEach 循环活动将其启用,然后将@variables('SheetName')
添加到 ForEach 循环活动的设置页签的 Items 属性中,如图 14-10 所示。
图 14-10
ADF ForEach 连接设置
接下来,点击图 14-10 中的 Activities 选项卡,导航至 ForEach 循环活动。或者,您可以通过单击 ForEach 循环活动中显示的铅笔图标来访问活动。添加一个带有源配置的复制数据活动,如图 14-11 所示。
图 14-11
ADF 复制数据源数据集连接属性
在图 14-12 所示的水槽配置中,将表格选项属性设置为“自动创建表格”,因为表格尚未创建。
图 14-12
ADF 复制活动接收器连接属性
在执行管道之后,注意图 14-13 中的四张表已经被加载到 Azure SQL 表中。
图 14-13
成功的 ADF Excel 到 SQL 管道执行状态
导航到 Azure SQL 表并查询它。注意在图 14-14 中,所有 Excel 表中的数据都被加载到一个 Azure SQL 表中。
以下是在图 14-14 中执行的 SQL 查询:
SELECT [orderdate],
[region],
[rep],
[item],
[units],
[unit cost],
[total]
FROM [dbo].[orders]
图 14-14
从 SSMS 查询 Azure SQL 表以确认数据可用
创建一个管道将电子表格中的多个 Excel 表加载到多个 Azure SQL 表中
在下一个示例中,让我们测试将多个 Excel 工作表从一个 Excel 电子表格加载到同一个数据库中的多个 Azure SQL 表中。首先,创建一个新的 Excel 查找表,如图 14-15 所示,包含SheetName
和TableName
,将被动态 ADF 管道参数使用。
图 14-15
创建包含 SheetName 和 TableName 的 Excel 查找表
以下脚本用于创建图 14-15 中的查找表:
SET ansi_nulls ON
go
SET quoted_identifier ON
go
CREATE TABLE [dbo].[exceltablelookup]
(
[sheetname] NVARCHAR NULL,
[tablename] NVARCHAR NULL
)
ON [PRIMARY]
textimage_on [PRIMARY]
表格创建完成后,将SheetNames
和相应的TableNames
插入表格,如图 14-16 所示。
图 14-16
将工作表名称和相应的表格名称插入表格
以下是已经在图 14-16 中执行的 SQL 查询:
SELECT [sheetname],
[tablename]
FROM [dbo].[exceltablelookup]
接下来,添加一个连接到 Excel 查找表的新数据集,如图 14-17 所示。
图 14-17
查找表的 ADF 数据集连接属性
图 14-18 显示 Excel 电子表格的连接属性将类似于之前我们参数化SheetName
的管道。
图 14-18
ADF Excel 数据集连接属性
在这个场景中,为 Azure SQL 数据库数据集连接中的TableName
添加一个参数,如图 14-19 所示。
图 14-19
Azure SQL 数据库连接参数
在 Azure SQL DB Connection 选项卡中,将模式保留为硬编码,并为TableName
添加参数,如图 14-20 所示。
图 14-20
Azure SQL 数据库参数化连接
在这个管道中,将需要一个查找表,它将通过对表的select *
查找来服务于在 SQL 查找表中查找值的目的,如图 14-21 所示。
图 14-21
ADF 查找设置
Note
出于本练习的目的,已经选择了查询选项,并且嵌入了源 SQL 查询。作为 ADF 管道中低嵌入式 SQL 代码维护的替代选项,可以考虑使用表或存储过程查询选项类型。
图 14-22 显示了如何将查找的值传递给设置选项卡的 ForEach 循环活动的项目属性。
图 14-22
ADF ForEach 循环设置
接下来,在 ForEach 循环活动中,添加一个复制数据活动,其源数据集属性包含参数化的SheetName
值,如图 14-23 所示。
图 14-23
ADF 复制数据源数据集连接属性
接下来,sink 数据集属性还需要包含参数化的TableName
值,如图 14-24 所示。请注意,表选项再次设置为“自动创建表”,这将基于源 Excel 文件的传入模式创建表。
图 14-24
ADF 接收器数据集连接属性
在您完成这个 ADF 管道的执行之后,请注意图 14-25 中的管道成功了,并且在您的 Azure SQL 数据库中创建了四个表。
图 14-25
成功的 ADF Excel 到 SQL 管道状态
导航到 Azure SQL 数据库,注意在图 14-26 中,所有四个表都是基于您在 SQL 查找表中定义的TableName
值用适当的名称创建的。
图 14-26
从 Excel 表加载到 Azure SQL 数据库的表格的 SSMS 视图
作为最后一项检查,查询图 14-27 中所示的所有四个表格,注意它们都包含来自 Excel 表格的数据,这确认了管道成功执行,表格到多个表格的正确映射在查找表中定义。
图 14-27
所有表的 SSMS 视图,以验证数据是否存在
以下是已经在图 14-27 中执行的 SQL 查询:
SELECT [orderdate],
[region],
[rep],
[item],
[units],
[unit cost],
[total]
FROM [dbo].[table1]
SELECT [orderdate],
[region],
[rep],
[item],
[units],
[unit cost],
[total]
FROM [dbo].[table2]
SELECT [orderdate],
[region],
[rep],
[item],
[units],
[unit cost],
[total]
FROM [dbo].[table3]
摘要
在本章中,我演示了如何使用 Azure Data Factory 的 Excel 连接器以及参数化管道,将位于 ADLS Gen2 中的包含多个工作表的 Excel 电子表格动态加载到单个 Azure SQL 表中,以及每个工作表的多个表中。
十五、DeltaLake
在使用 Azure Data Lake Storage Gen2 和 Apache Spark 时,用户已经了解了 Apache Spark 的局限性和许多数据湖实现挑战。在数据湖环境中,对 ACID 兼容功能集的需求至关重要,Delta Lake 针对标准 Azure 数据湖存储二代帐户的当前限制提供了许多解决方案。
Delta Lake 是一个开源存储层,它保证了湖中数据的原子性、一致性、隔离性和持久性。简而言之,DeltaLake 泊是酸性的。除了提供 ACID 事务、可伸缩的元数据处理等等,Delta Lake 运行在现有的数据湖之上,并且与 Apache Spark APIs 兼容。DeltaLake 有几种入门方法。Databricks 提供笔记本以及兼容的 Apache Spark APIs 来创建和管理 DeltaLake 泊。或者,Azure Data Factory 的映射数据流(使用向外扩展的 Apache Spark 集群)可用于通过 GUI 设计的 ETL 管道执行符合 ACID 的 CRUD 操作。本章将通过如何在 Delta Lake 中创建、插入、更新和删除的示例,演示如何使用 Azure Data Factory 的 Delta Lake 连接器开始使用 Delta Lake。
为什么是酸性 DeltaLake
将 Delta Lake 引入现代云数据架构有许多优势。传统上,数据湖和 Apache Spark 不符合 ACID。Delta Lake 引入了这种酸性合规性,以解决以下许多酸性合规性问题:
-
原子性 : 要么写全部数据,要么什么都不写。Apache Spark 保存模式不使用任何锁定,并且不是原子的。这样,失败的作业可能会留下不完整的文件,并可能会损坏数据。此外,失败的作业可能会删除旧文件并损坏新文件。虽然这似乎令人担忧,但 Spark 确实有内置的数据帧编写器 API,这些 API 不是原子的,但对于追加操作却是如此。然而,使用云存储会带来性能开销。当前可用的 Apache Spark 保存模式包括 ErrorIfExists、Append、Overwrite 和 Ignore。
-
一致性 : 数据始终处于有效状态。如果 Spark API writer 删除一个旧文件并创建一个新文件,并且该操作不是事务性的,那么在删除旧文件和创建新文件之间总会有一段时间文件不存在。在这种情况下,如果覆盖操作失败,这将导致旧文件的数据丢失。此外,可能无法创建新文件。这是一个典型的与一致性相关的 Spark 覆盖操作问题。
-
隔离 : 多个交易独立发生,互不干扰。这意味着写入数据集时,同一数据集上的其他并发读取或写入不应受到写入操作的影响。典型的事务数据库提供多种隔离级别,如未提交读、提交读、可重复读、快照和可序列化。虽然 Spark 有任务级和作业级提交,但由于它缺乏原子性,所以它没有隔离类型。
-
耐久性 : 提交的数据永不丢失。当 Spark 没有正确执行提交时,它会覆盖云存储选项提供的所有强大的持久性功能,并损坏和/或丢失数据。这违反了数据持久性。
先决条件
现在,您已经了解了当前的数据湖,了解了 Spark 挑战以及符合 ACID 的 Delta 湖的好处,让我们开始练习吧。
对于本练习,请确保成功创建以下先决条件:
图 15-1
ADLS 第二代区域/文件夹
-
创建数据工厂 V2 :数据工厂将用于执行 ELT 编排。此外,ADF 的地图数据流 DeltaLake 连接器将用于创建和管理 DeltaLake。
-
创建数据湖存储二代 : ADLS Gen2 将是数据湖存储,在其之上将创建 Delta 湖。
-
创建 Data Lake Storage Gen2 容器和区域:创建 Data Lake Storage Gen2 帐户后,还要创建适当的容器和区域。再次访问第三章,了解有关设计 ADLS 第二代区域的更多信息,我将在其中讨论如何设计 ADLS 第二代存储客户。本练习将使用原始区域来存储示例源拼花文件。此外,临时区域将用于增量更新、插入、删除和其他转换。尽管在本练习中不会使用策划区域,但有一点很重要,即该区域可能包含最终的 ETL、高级分析或数据科学模型,这些模型是从临时区域进一步转换和策划的。一旦在你的 ADLS 第二代账户中创建了不同的区域,它们看起来将类似于图 15-1 中的图示。
图 15-2
示例 userdata1.parquet 文件
- 上传数据到原始区域:最后,这个练习你需要一些数据。通过在网上或公开可用的数据集中搜索“样本拼花文件”,您将获得大量免费样本拼花文件。对于本练习,您可以在下面的GitHub repo
(
https://github.com/Teradata/kylo/tree/master/samples/sample-data/parquet
)
中下载示例拼花文件,然后将其上传到您的 ADLS Gen2 存储帐户,如图 15-2 所示。
图 15-3
ADF 中的 userData1 连接设置
- 创建一个指向原始区域的数据工厂拼花数据集:最后一个先决条件是在新创建的 ADF V2 实例中创建一个拼花格式数据集,如图 15-3 所示,指向原始区域中存储的样本拼花文件。
创建并插入 DeltaLake
现在,所有先决条件都已就绪,您可以创建初始增量表,并将原始区域中的数据插入到增量表中。
通过创建一个新的数据工厂管道并向其添加一个新的“映射数据流”来开始这个过程。还记得命名管道和数据流的合理名称,很像图 15-4 中所示的示例。
图 15-4
映射用于插入的数据流画布
在数据流中,添加一个源,其配置设置如图 15-5 所示。此外,选中“允许模式漂移”选项当与字段、列和类型相关的元数据频繁更改时,这被称为模式漂移。如果没有适当的过程来处理模式漂移,ETL 管道可能会失败。ADF 支持经常变化的灵活模式。ADF 将模式漂移视为后期绑定。因此,您将无法在数据流中查看漂移的架构。
当启用模式漂移时,所有传入的字段都在执行期间从源中读取,并通过整个流传递到接收器。默认情况下,所有新检测到的列都是字符串数据类型。如果需要自动推断漂移列的数据类型,则需要在源设置中启用推断漂移列类型。
允许自动检测漂移的色谱柱类型。采样提供了一种限制源中行数的方法,主要用于测试和调试目的。
图 15-5
为插入操作映射数据流 ETL 流源设置
由于 Delta Lake 利用了 Spark 的分布式处理能力,它能够适当地对数据进行分区。然而,为了探索手动设置分区的能力,在 ID 列上配置 20 个散列分区,如图 15-6 所示。
图 15-6
优化 MDF 分区的设置
添加目的地活动后,确保在 Azure 数据工厂 (
https://docs.microsoft.com/en-us/azure/data-factory/format-delta
)
中将如图 15-7 所示的 sink 类型设置为 Delta 格式。请注意,DeltaLake 在绘制数据流图时既可以作为源,也可以作为汇。此外,一旦选择了 Delta Lake 的汇类型,您将需要选择链接的服务。
图 15-7
MDF 接收器设置
在图 15-8 所示的设置选项卡下,确保暂存文件夹被选中,并选择允许插入作为更新方法。此外,如果需要在加载前截断增量表,请选择 Truncate table 选项。
在湖(
https://docs.databricks.com/spark/latest/spark-sql/language-manual/delta-vacuum.html
)
中清空增量表的过程将删除增量表不再引用的文件以及超过保留阈值(小时)的文件。如果该值保留为 0 或为空,则默认值为 30 天。
图 15-8
在 MDF 中插入水槽的设置
最后,在图 15-9 所示的优化选项卡中,使用当前分区,因为源分区将向下游流向接收器。
图 15-9
用于优化接收器的分区选项
正如预期的那样,一旦您触发了管道,并且在它完成运行之后,从图 15-10 中可以注意到,在 20 个不同的分区中创建了 13 个新列。
图 15-10
ADF MDF 管道运行详细信息
在查看 ADLS Gen2 暂存文件夹时,请注意图 15-11 中的一个 delta_log 文件夹以及 20 个快速压缩的拼花文件已经创建。
图 15-11
DeltaLake 分区文件
打开 delta_log 文件夹查看两个事务日志文件,如图 15-12 所示。事务日志捕获了许多重要的特性,包括 ACID 事务、可伸缩的元数据处理、时间旅行,以及更多的(
https://databricks.com/blog/2019/08/21/diving-into-delta-lake-unpacking-the-transaction-log.html
)
。
图 15-12
增量日志文件
在检查了 Staging Delta Lake 中的新数据后,注意到有新的记录被插入。要通过绘制数据流图从 ADF 轻松探索 DeltaLake,只需切换数据预览选项卡即可查看数据流的详细信息,如图 15-13 所示。
图 15-13
插入从拼花文件读取的数据结果
更新 DeltaLake
到目前为止,在上一节中已经介绍了到 Delta Lake 的插入。接下来,让我们看看 Data Factory 如何处理对增量表的更新。类似于您在上一节中对插入所做的,创建一个新的 ADF 管道,带有用于更新的映射数据流,如图 15-14 所示。
图 15-14
MDF 更新 DeltaLake
在这个更新练习中,更新用户的名字和姓氏,并将其转换为小写。为此,向更新映射数据流画布添加一个派生的 column 和 AlterRow 转换活动,如图 15-15 所示。
图 15-15
用于更新映射数据流拼花的源设置
在图 15-16 所示的源选项选项卡中,源数据仍然是您的暂存 Delta Lake,它也是为插入而配置的。ADF 中的 Delta Lake source 连接器还为大规模数据湖引入了 delta time travel,以审计数据更改、重现结果、处理回滚等。时光旅行可以按时间戳或版本查询数据( https://databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
) )。
图 15-16
更新源选项
派生的列转换活动使用表达式lower(first_name)
和lower(last_name)
将名字和姓氏转换成小写,如图 15-17 所示。映射数据流能够在这个阶段处理极其复杂的转换。
图 15-17
用于更新的派生列设置
对于更改行设置,您需要指定一个更新 if 条件true()
来更新所有符合条件的行,如图 15-18 所示。
图 15-18
AlterRow 更新的设置
确保您验证了 Sink 选项卡的配置设置,如图 15-19 所示。
图 15-19
更新 MDF 的接收器设置
确保接收器仍然指向暂存的 DeltaLake 数据。另外,选择“允许更新”作为更新方法。为了显示可以同时选择多个键列,在图 15-20 中选择了三列。
图 15-20
更新 MDF 接收器的方法设置
保存并触发管道后,注意 ADF 数据预览选项卡的结果,如图 15-21 所示。名字和姓氏已更新为小写值。
图 15-21
显示预期更新的数据
从 DeltaLake 删除
概括地说,到目前为止,已经讨论了插入和更新。接下来,让我们看一个映射数据流如何处理 Delta Lake 中的删除的例子。类似于建立插入和更新 MDF 管道的过程,创建一个新的数据工厂映射数据流,如图 15-22 所示。
图 15-22
用于从 Delta Lake 删除的 MDF
根据需要配置增量源设置,如图 15-23 所示。
图 15-23
mdf_delete_deltalake 的源设置
由于您仍在使用相同的暂存 DeltaLake,这些源设置(如图 15-24 所示)将按照您在前面章节中配置插入和更新的方式进行配置。
图 15-24
mdf_delete_deltalake 的源选项
对于本例,删除所有gender = male
处的记录。为此,您需要将更改行条件配置为 Delete if gender == 'Male' ,如图 15-25 所示。
图 15-25
更改 mdf_delete_deltalake delta 的行设置
最后,图 15-26 显示了 sink delta 配置设置。
图 15-26
mdf_delete_deltalake 的接收器设置
选择 sink 的 Staging Delta Lake,选择【允许删除】,同时选择需要的id``registration_dttm``and ip_address
按键栏,如图 15-27 所示。
图 15-27
mdf_delete_deltalake 的目标
发布并触发该管道后,请注意图 15-28 中gender = Male
处的所有记录是如何被删除的。
图 15-28
按预期删除数据文件
浏览增量日志
最后,让我们看一下增量日志,以简要了解日志是如何创建和填充的。主提交信息文件生成并存储在插入、更新和删除 JSON 提交文件中。此外,还会创建 CRC 文件。CRC 是一种用于检查数据完整性的流行技术,因为它具有出色的错误检测能力,使用很少的资源,并且易于使用。从 ADF 增量插入、更新和删除 MDF 管道创建的增量日志存储在您的 ADLS Gen2 帐户的 _delta_log 文件夹中,如图 15-29 所示。
图 15-29
插入、更新和删除后的增量日志
插入
打开图 15-30 所示的插入 JSON 提交文件,注意它包含插入操作的提交信息,由以单词“添加”开头的行项目引用。在构建 ETL 管道和过程时,通常不需要使用或打开这些文件。但是,日志总是以 JSON 格式保存在这个文件夹中,所以您总是可以选择在需要时打开日志。对于本练习,打开这些日志将使您更深入地了解这些日志是如何捕获信息的,从而有助于更好地理解该过程的机制。
图 15-30
增量日志插入
{"commitInfo":{"timestamp":1594782281467,"operation":"WRITE","operationParameters":{"mode":"Append","partitionBy":"[]"},"isolationLevel":"WriteSerializable","isBlindAppend":true}}
更新
类似于插入增量日志,打开图 15-31 所示的更新 JSON 提交文件,注意它包含更新操作的提交信息。以“删除”开头的行项目显示了已删除数据文件的路径,以“添加”开头的行项目显示了更新过程中添加的数据。此外,这些日志中还提供了与提交信息、时间戳等相关的重要细节。同样,在常规的 ADF 管道过程中,您不需要研究这些增量日志,这意味着是一个信息性和探索性的练习。
图 15-31
增量日志更新
{"commitInfo":{"timestamp":1594782711552,"operation":"MERGE","operationParameters":{"predicate":"(((source.`id` = target.`id`) AND (source.`registration_dttm` = target.`registration_dttm`)) AND (source.`ip_address` = target.`ip_address`))","updatePredicate":"((NOT ((source.`ra2b434a305b34f2f96cd5b4b4149455e` & 2) = 0)) OR (NOT ((source.`ra2b434a305b34f2f96cd5b4b4149455e` & 8) = 0)))","deletePredicate":"(NOT ((source.`ra2b434a305b34f2f96cd5b4b4149455e` & 4) = 0))"},"readVersion":0,"isolationLevel":"WriteSerializable","isBlindAppend":false}}
删除
最后,打开图 15-32 所示的删除 JSON 提交文件,注意它包含了删除操作的提交信息。已删除的文件由以“删除”开头的行项目捕获。现在您已经了解了这些 delta 事务日志,以及如何打开和解释它们,您将更好地理解 Delta Lake 的相关性,以及它在处理数据湖中符合 ACID 的事务方面的定位。
图 15-32
增量日志删除
"commitInfo":{"timestamp":1594783812366,"operation":"MERGE","operationParameters":{"predicate":"(((source.`id` = target.`id`) AND (source.`registration_dttm` = target.`registration_dttm`)) AND (source.`ip_address` = target.`ip_address`))","updatePredicate":"((NOT ((source.`ra079d97a688347b581710234d2cc4b63` & 2) = 0)) OR (NOT ((source.`ra079d97a688347b581710234d2cc4b63` & 8) = 0)))","deletePredicate":"(NOT ((source.`ra079d97a688347b581710234d2cc4b63` & 4) = 0))"},"readVersion":1,"isolationLevel":"WriteSerializable","isBlindAppend":false}}
摘要
在这一章中,我通过使用 Azure Data Lake Storage Gen2 作为存储帐户在 Delta Lake 中创建、插入、更新和删除的示例,演示了如何使用 Azure Data Factory 的 Delta Lake 连接器开始使用 Delta Lake。由于 Delta Lake 是一个开源项目,旨在支持在现有存储系统的基础上构建 lakehouse 架构,因此它当然可以用于其他存储系统,如亚马逊 S3、谷歌云存储、HDFS 等。此外,通过在 Databricks 笔记本中编写 Spark、Python 和/或 Scala 代码,您可以轻松地使用 Delta Lake。
有了这样的灵活性,lakehouse 数据管理范式正在获得动力,它有望成为行业标准,并推动数据湖和数据仓库的发展。数据湖的低成本存储使得这种选择对于那些对成本敏感和追求增长的组织来说非常有吸引力。data lakehouse 的其他优势包括减少数据冗余、消除简单的 ETL 作业、将计算与存储分离、实时流支持、简化数据管理以及直接连接到现代 BI 工具的能力。虽然还处于起步阶段,但 data lakehouse 和 Delta Lake 确实有一定的局限性,使它们无法完全取代传统的数据仓库设备,如 SQL Server 数据库和仓库。然而,本章展示了以无代码方式直接使用 Delta Lake 的能力,并展示了如何轻松地使用 Delta Lake 开始探索数据湖库的构建块。
十六、流分析异常检测
许多企业越来越需要处理大数据实时流。众多行业的客户都在寻求利用实时大数据的力量来获得有价值的见解。他们正在寻求一种易于使用、灵活、可靠且可扩展的解决方案来处理和转换其物联网项目的实时数据流。此外,伴随这些大型实时数据流而来的是数据中的异常。各行各业的客户都对使用机器学习算法和运算符进行实时异常检测的概念感兴趣。
Azure Stream Analytics 是一个事件处理引擎,允许检查来自设备、传感器、网站、社交媒体源、应用等的大量数据流。它易于使用并且基于简单的 SQL。此外,它是 Azure 上的一个完全托管(PaaS)产品,可以运行针对成本进行了优化的大规模分析作业,因为用户只需为所消耗的流单元付费。
Azure Stream Analytics 现在提供内置的基于机器学习的异常检测功能,以监控临时和持久的异常。这种异常检测功能与 Power BI 的实时流服务相结合,形成了一种强大的实时异常检测服务。在这一章中,我将展示一个实例,展示如何使用 Azure Stream Analytics 创建实时异常检测来处理流,并使用 Power BI 来可视化数据。
先决条件
要开始实现本章的示例解决方案,您需要创建并运行一些 Azure 资源。这些是
-
流分析工作 : Azure Stream Analytics 是一个实时分析和复杂事件处理引擎,旨在同时分析和处理来自多个来源的大量快速流数据。
-
物联网中心:物联网中心是托管在云中的托管服务,充当物联网应用和其管理的设备之间双向通信的中央消息中心。
-
Power BI 服务:对于中小型企业而言,Power BI Pro 是向所有用户提供全面商业智能功能的最佳选择。Power BI Premium 最适合需要大量人员使用 Power BI 查看仪表板和报告的大型企业组织。请重新阅读第一章,我在这一章的最后讨论了 Power BI Pro 与 Premium 的优缺点。在本练习中,将使用 Power BI Premium。
-
设备模拟器:设备模拟器 app,这是一个 Visual Studio 项目,可以从以下 GitHub 位置(
https://github.com/Azure/azure-stream-analytics/tree/master/Samples/DeviceSimulator
)下载,用于模拟从设备发送到物联网 Hub 的异常。一旦你下载并打开这个设备模拟器 Visual Studio 项目,你将能够运行它来查看设备模拟器 UI,它可以被配置为将事件从模拟器传递到你将在 Azure 中创建的物联网中心。模拟器数据的模式使用温度和传感器 ID。然后,这些事件可以由 Azure 流分析作业使用,该作业被配置为从该物联网中心读取。
下面几节将带您创建这些先决条件。
创建 Azure 流分析作业
让我们通过简单地搜索流分析,在 Azure Portal 中创建新的流分析作业,如图 16-1 所示。
图 16-1
Azure 门户中的新流分析作业
图 16-2 说明你需要将作业命名为asa-001
。另外,选择相应的订阅、资源组和位置。我建议在一个资源组中为这个项目创建所有的资源。也就是说,您可以为此流分析作业创建一个新的资源组。此外,尽量在同一位置创建所有资源,以减少数据和网络延迟,尤其是因为这是一个实时流解决方案。对于本练习,选择“Cloud”将作业部署到 Azure cloud,因为这是典型的选择。选择“边缘”将作业部署到内部物联网网关边缘设备。做出选择后,单击创建。
图 16-2
新流分析作业详细信息
您现在已经创建了一个流分析作业。您还需要创建一个物联网中心,它将用于弥合设备模拟器和流分析作业之间的差距。
创建物联网中心
物联网中心是托管在云中的托管服务,充当物联网应用及其管理的设备之间双向通信的中央消息中心。物联网中心本质上是一个事件中心,具有额外的功能,包括每设备身份、云到设备的消息传递以及其他一些功能。在第一章中,我已经更详细地讨论了物联网和活动中心之间的异同。图 16-3 展示了如何从 Azure 门户创建物联网中心。
图 16-3
创建 Azure 门户物联网中心
在图 16-4 所示的基本选项卡中,为您的物联网中心命名,并确保订阅、资源组和区域配置正确。回想一下上一节,最好让物联网中心与流分析作业位于相同的资源组和区域。
图 16-4
物联网中心基础选项卡
还可以选择调整物联网中心的大小和规模,如图 16-5 所示。对于本练习,使用自由层,因为它最适合测试场景。物联网集线器的标准层支持所有功能,并且是任何想要利用双向通信功能的物联网解决方案所必需的。基本层支持部分功能,适用于仅需要从设备到云的单向通信的物联网解决方案。两层都提供相同的安全和身份验证功能。阅读微软的文档,了解何时以及如何根据能力需求选择合适的层( https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-scaling
)。
图 16-5
物联网中心管理选项卡
选择所需的层后,查看图 16-6 中显示的选择,然后单击创建以部署物联网资源。
图 16-6
物联网中心审查+创建
部署物联网中心资源后,导航至图 16-7 所示的资源管理器下的物联网设备,然后单击物联网中心导航菜单下的新建,添加一个新设备,然后我们可以使用它来配置设备模拟器,该模拟器将向该物联网设备发送模拟事件。
图 16-7
物联网中心物联网设备
然后添加一个设备 ID,点击保存,如图 16-8 所示。设备 ID 只是设备的标识,用于设备认证和访问控制。对称密钥必须是有效的 base-64 格式,密钥长度在 16 到 64 字节之间。通过将证书指纹或证书颁发机构(CA)上传到 Azure IoT Hub,您可以使用任何 X.509 证书通过 IoT Hub 对设备进行身份验证。使用证书指纹的身份验证验证提供的指纹是否与配置的指纹匹配。选择“自动生成密钥”为该设备自动生成对称密钥。最后,支持设备与物联网中心的交互。
图 16-8
创建物联网中枢设备
一旦设备被添加,它将显示“启用”状态,如图 16-9 所示。单击设备以打开设备详细信息,包括密钥、身份和附加配置。
图 16-9
ASA 设备状态和 ID
接下来,复制如图 16-10 所示主键的连接字符串,它将被用作物联网设备的连接。
图 16-10
ASA 物联网设备的连接详细信息
创建 Power BI 服务
要开始使用 Power BI,请从以下网址下载免费桌面版: https://powerbi.microsoft.com/en-us/downloads/
。在考虑生产就绪型 Power BI 服务时,请探索专业版和高级版选项。在第一章中,我简单地比较了专业版和高级版。Pro 的每用户许可费为 9.99 美元,Premium 的每用户许可费为 20 美元。在本练习中,使用了 Power BI Premium。请检查各种选项,并选择最适合您和您的组织的选项。
下载设备模拟器
设备模拟器用于模拟从设备发送到物联网集线器的异常情况。该模式使用温度和传感器 ID。然后,这些事件可以被配置为从该物联网中心读取的 Azure 流分析作业消费。从下面的 URL (
https://github.com/Azure/azure-stream-analytics/tree/master/Samples/DeviceSimulator
)
下载设备模拟器,然后打开相应的 Visual Studio 解决方案文件并运行模拟器。打开设备模拟器解决方案文件时,该文件应类似于图 16-11 。
图 16-11
设备模拟器项目的 VS 视图
当设备模拟器开始运行时,请注意各种可用的设置。请务必查看 readme.md GitHub 文件,以了解可用的各种配置和设置。例如,模拟模式是一种用模拟器和各种异常模式进行实验的方法,无需向实时物联网中心发送数据。
一旦您有了可用的物联网集线器名称空间(例如 rl-iothub-001)、设备 ID (ASAIoTDevice)和设备密钥(主键),在运行模拟器之前,在物联网集线器配置部分输入这些信息,如图 16-12 所示,以确保消息和数据被发送到物联网设备。
图 16-12
设备模拟器
创建流分析输入和输出
流分析作业由输入、查询和输出组成。需要对其进行定义和运行,以便获取物联网中枢设备输入,使用查询对其进行处理,并将其输出到 Power BI 实时流仪表板。
添加流输入
您的第一步是捕获输入。首先添加一个物联网集线器流输入,如图 16-13 所示。请注意,还有其他选项可以使用事件中心、Blob 存储和 ADLS gen 2——它们也是流输入。
图 16-13
添加物联网集线器流输入
接下来,图 16-14 显示了如何配置输入流细节。以下是高级配置选项的一些附加详细信息:
图 16-14
配置输入流详细信息
-
消费群体:物联网枢纽将一个消费群体内的阅读器数量限制在 5 个。Microsoft 建议对每个作业使用单独的组。将此字段留空将使用' $Default '使用者组。
-
共享访问策略名称:当您创建物联网集线器时,您也可以在物联网集线器设置中创建共享访问策略。每个共享访问策略都有一个名称、您设置的权限和访问密钥。
-
共享访问策略键:当您创建物联网中心时,您也可以在物联网中心设置中创建共享访问策略。每个共享访问策略都有一个名称、您设置的权限和访问密钥。
-
端点:对从设备到云的消息使用“消息”端点。将“操作监控”端点用于设备遥测和元数据。
-
分区键:如果你的输入被一个属性分区,你可以在这里添加这个属性的名称。这是可选的,如果在该属性中包含 PARTITION BY 或 GROUP BY 子句,则用于提高查询的性能。如果此作业使用 1.2 或更高的兼容级别,则默认情况下会添加“PartitionId”,因此您无需在此处显式添加它。
-
事件序列化格式:为了确保您的查询按照您期望的方式工作,Stream Analytics 需要知道您对传入的数据流使用哪种序列化格式。
-
编码 : UTF-8 是目前唯一支持的编码格式。
-
事件压缩类型:压缩选项使您能够指定压缩类型 Gzip、Deflate 或无压缩。
一旦指定了输入流的详细信息并获得了您想要的信息,请单击 Save 按钮。您将被带到如图 16-15 所示的屏幕,在这里您可以看到已经为您创建了物联网中心源流。
图 16-15
物联网中心源流
添加流输出
同样,也添加一个输出流,如图 16-16 所示。这将定义事件需要流向的接收器。请注意各种可用的接收器选项,包括 ADLS Gen2、SQL 数据库、Cosmos DB、Power BI 等等。在本练习中,选择 Power BI。
图 16-16
到 PBI 的物联网输出流
接下来,授权 Power BI 访问流分析作业,如图 16-17 所示。
图 16-17
授权 Power BI 访问 ASA
这将显示输入您的 Azure 门户凭据的提示,然后单击下一步,如图 16-18 所示。考虑使用服务帐户进行生产授权和身份验证,而不是简单地使用个人帐户。
图 16-18
登录到 Azure 门户网站
配置数据集和表,并将验证模式设置为“用户令牌”,因为这将在开发/演示模式下临时运行,如图 16-19 所示。
图 16-19
配置数据集和表,并设置身份验证模式
您还可以使用托管身份来认证您的 Azure 流分析作业,以支持 BI 。用于输出到 Power BI 的托管身份认证使流分析作业能够直接访问您的 Power BI 帐户中的工作区。该特性允许流分析作业的部署完全自动化,因为用户不再需要通过 Azure Portal 交互式登录 Power BI。此外,写入 Power BI 的长期运行的作业现在得到了更好的支持,因为您将不再需要定期重新授权作业(
https://docs.microsoft.com/en-us/azure/stream-analytics/powerbi-output-managed-identity
)
。
最后,图 16-20 显示 IoTPowerBIOutput 接收流已经创建。
图 16-20
IoTPowerBIOutput 接收器流
编写流分析查询
创建流分析作业的最后一步是为异常检测编写 SQL 查询。在这个场景中,让我们使用峰值和下降函数。Azure Stream Analytics 提供内置的基于机器学习的异常检测功能,可用于监控两种最常见的异常:暂时的和持久的。使用 AnomalyDetection _ SpikeAndDip 和 AnomalyDetection_ChangePoint 函数,您可以直接在流分析作业中执行异常检测。Azure Stream Analytics 中的异常检测采用基于机器学习的异常检测运算符,如 Spike 和 Dip 以及 Change Point。图 16-21 显示了在哪里添加包含内置异常检测峰值和下降函数的 SQL 查询。
图 16-21
异常检测的 ASA SQL 查询
这是用作图 16-21 所示的源流分析查询的代码。此源查询将获取传入的流事件,并对其应用 SQL 查询,其中包括添加别名、转换以及使用峰值和下降异常检测功能,该功能是流分析 SQL 查询功能的一部分:
WITH anomalydetectionstep AS
(
SELECT eventenqueuedutctime
AS time,
Cast(temperature AS FLOAT)
AS temp,
anomalydetection_spikeanddip(Cast(temperature AS FLOAT), 95, 120, 'spikesanddips') OVER(limit duration(second, 120)) AS spikeanddipscores
FROM iothub )
SELECT time,
temp,
cast(getrecordpropertyvalue(spikeanddipscores, 'Score') AS float) AS spikeanddipscore,
cast(getrecordpropertyvalue(spikeanddipscores, 'IsAnomaly') AS bigint) AS isspikeanddipanomaly
INTO iotpowerbioutput
FROM anomalydetectionstep
启动流分析作业
创建成功的流分析作业的最后一步是启动作业。这将确保从物联网集线器设备接收事件,并实时传递给 Power BI 服务。配置完作业的所有必要组件后,启动流分析作业,如图 16-22 所示。请注意,有一个物联网集线器输入和一个电源 BI 输出。
图 16-22
从 Azure 门户启动 ASA 作业
开始作业时,系统会提示您设置作业输出开始时间,如图 16-23 所示。此作业将从特定数量的流单元开始。您可以在缩放部分下更改流单位。作业将默认为 3 个流单位。您可以将配置为在流分析提供的标准多租户环境或您拥有的专用流分析集群中运行此作业。该作业将默认为标准环境。作业可能需要提前读取输入数据,以确保结果的准确性。要恢复停止的作业而不丢失数据,请选择上次停止。请注意,如果您是第一次运行作业,此选项不可用。在本练习中,确保作业输出开始时间设置为“Now ”,然后单击“start”。
图 16-23
ASA 开始作业详细信息
一旦工作开始,注意“运行”状态,如图 16-24 所示。
图 16-24
处于运行状态的 ASA 作业
创建实时电源 BI 仪表板
一旦作业开始运行,就可以使用 Power BI 开始构建实时仪表板。在这个控制面板上,您将能够看到您的监控查询的结果。密切关注仪表板是您知道异常情况何时出现的方法。
创建数据集
首先导航到包含图 16-25 所示数据集部分中的 IoTPowerBIDataSet 的工作空间。请注意,流分析作业必须正在运行,并且必须为要创建的数据集处理了至少一个事件。
图 16-25
PBI 创建数据集
创建仪表板
验证数据集已创建后,还要创建一个新的仪表板,如图 16-26 所示。
图 16-26
PBI 创建了一个仪表板
为仪表板命名。在本练习中,它被称为 IoTPowerBIDashboard,如图 16-27 所示。
图 16-27
PBI 命名仪表板
添加单幅图块
图块是数据的快照,固定在仪表板上。可以从报表、数据集、仪表板等创建切片。仪表板和仪表板磁贴是 Power BI 服务的一项功能,而不是 Power BI Desktop 的功能,因此您需要确保启动并运行 Power BI 服务。为实时自定义流数据添加一个图块,如图 16-28 所示。
图 16-28
PBI 添加一个瓷砖
选择数据集,如图 16-29 所示。请注意,数据集是您导入或连接到的数据的集合。Power BI 允许您连接和导入各种数据集,并将它们集中在一个地方。数据集与工作空间相关联,单个数据集可以是许多工作空间的一部分。
图 16-29
PBI 添加了一个自定义的流数据块
卡片可视化是 Power BI 仪表板中唯一的数字,也是您需要在仪表板或报告中跟踪的最重要的东西。在本练习中,异常是需要跟踪的最重要的指标。添加卡片可视化以跟踪峰值和谷值异常的计数,如图 16-30 所示。
图 16-30
PBI 添加了一个卡片可视化
折线图是由点表示并由直线连接的一系列数据点。折线图可以有一条或多条线。折线图有一个 X 轴和一个 Y 轴。还要添加一个折线图可视化来跟踪峰值和谷值,如图 16-31 所示。
图 16-31
PBI 瓷砖详情
运行设备模拟器
现在回到设备模拟器,配置您在本章前几节中积累的物联网集线器详细信息。详细配置完成后,点击设备模拟器中的“更新物联网集线器配置”,如图 16-32 所示。
图 16-32
物联网集线器配置详细信息
选择正常事件的异常设置,如图 16-33 所示,启动装置模拟器。这将简单地启动模拟器,并开始生成一组正常的事件,这些事件将被传递到物联网中心和 Power BI 仪表板。
图 16-33
正常事件的设备模拟器异常设置
监控实时电源 BI 流
一旦设备启动,回到您的 Power BI 仪表板开始监控流。请注意图 16-34 中的流细节现在可以在 Power BI 仪表板上看到。还要注意 SpikeandDip 异常卡仍然为 0,因为我们目前只流式传输正常事件。
图 16-34
带有正常事件的 PBI 实时流仪表板
然后回到模拟器,将异常设置改为峰值/下降,每 2 秒重复一次。从图 16-35 中注意到模拟器中已经开始出现异常。
图 16-35
设备模拟器创建异常事件
回到实时功率 BI 仪表板后,请注意尖峰和下降异常已经开始流入仪表板,并且尖峰和下降异常卡开始显示进入的异常,如图 16-36 所示。
图 16-36
PBI 尖峰和倾斜异常
装置模拟器中还有一些额外的异常设置,可作为下一步探索,如液位变化和缓慢趋势,如图 16-37 所示。
图 16-37
设备模拟器中的 PBI 异常设置
一旦测试完成,确保你回到 Azure Portal 并停止流分析作业和设备模拟器,如图 16-38 所示。
图 16-38
停止流式作业
摘要
在本章中,我展示了一个实际的端到端示例,说明如何使用设备模拟器创建实时事件并将这些事件发送到物联网中心,该中心将收集这些事件,并使用 Azure Stream Analytics 的内置峰值和谷值异常检测功能进行下游异常检测。最后,您学习了如何使用 Power BI 将实时流数据可视化到仪表板中。您还了解了 Azure 中实时异常检测和报告的一些功能。
十七、使用 Apache Spark 的实时物联网分析
实时物联网分析、高级分析和实时机器学习洞察都是许多组织渴望推进其业务和目标的领域。Apache Spark 先进的 API 产品为大数据工作负载的高级流分析带来了许多机会。Apache Spark 提供的一个这样的 API 以结构化流为中心,支持大数据和实时高级分析功能。
如图 17-1 所示,Apache Spark 的结构化流适合整个 Databricks 统一数据分析平台,是一个基于 Spark SQL 引擎构建的流处理框架。一旦指定了计算以及源和目的地,结构化流引擎将随着新数据的可用而递增并连续地运行查询。结构化流将数据流视为一个表,并不断追加数据。在本章中,我将带您完成一个端到端的练习,使用一个设备模拟器来实现一个结构化的流解决方案,该模拟器将生成随机的设备数据,这些数据将被馈送到 Azure IoT Hub,并由 Apache Spark 通过 Databricks 笔记本进行处理,然后进入一个 Delta Lake 来持久存储数据。此外,我将向您展示如何定制结构化的流输出模式,比如 append vs. update vs. complete,并向您介绍代码中的触发器。
图 17-1
Apache Spark 的结构化流和 DeltaLake 框架
先决条件
作为本练习的基础,请确保您已经阅读并理解了第十六章,该章讨论了如何完成以下步骤:
-
安装并运行物联网设备模拟器 Visual Studio 解决方案文件。该设备模拟器将创建一个随机设备数据流,该数据流将被输入物联网中枢设备,并由 Spark 结构化流使用。
-
创建和配置物联网集线器设备。这项服务将弥合设备模拟器和 Spark 结构化流服务之间的鸿沟。
-
此外,Databricks 服务需要在 Azure Portal 中创建。Databricks 的 Spark 计算集群将用于结构化流处理。或者,Synapse Analytics 也可以用于这一过程。
创建物联网中心
一旦创建了物联网中心,并向该中心添加了物联网设备,则向物联网中心的内置端点部分添加一个新的消费群,如图 17-2 所示。应用使用消费者群体从物联网中心获取数据。因此,当您开始编写结构化流代码时,拥有一个可识别的别名将非常有用。
图 17-2
内置端点事件中心详细信息
创建数据块集群
接下来,需要创建一个 Databricks 集群。出于本练习的目的,使用图 17-3 所示的配置创建一个标准集群。
图 17-3
标准数据块集群
安装 Maven 库
在开始在 Databricks 笔记本中编写结构化流代码之前,还有一个设置和配置步骤。用下面列出的坐标安装一个 Maven 库。这些坐标取自 MvnRepository,可以通过以下网址找到: https://mvnrepository.com/artifact/com.microsoft.azure/azure-eventhubs-spark
。
在集群库配置界面输入 Maven 库中的坐标com.microsoft.azure:azure-eventhubs-spark_2.12:2.3.15
,如图 17-4 所示。请注意,有各种库源选项可供选择和安装。对于这个场景,您将使用 Maven。或者,您还可以指定要排除的源存储库和依赖项。
图 17-4
安装 Databricks Maven 库
一旦选定的 Maven 库被安装到集群上,它将显示“已安装”状态,如图 17-5 所示。重新启动群集,以便在群集上正确安装库。
图 17-5
查看 Databricks 集群上安装的库
创建笔记本并运行结构化流查询
在下一节中,您将了解如何在 Databricks 笔记本中实现 Scala 代码,该笔记本将连接到您的物联网中心,并启动一个结构化的传入设备模拟器事件流。这些实时流事件将显示在您笔记本电脑的仪表板上,并保存在增量表中,以便为进一步的处理和转换准备数据。此外,您将了解触发器的概念以及如何在事件流处理代码中实现它们。
配置笔记本连接
现在,您已经准备好创建一个新的 Databricks 笔记本,如图 17-6 所示,并将安装了 Maven 库的标准集群附加到它上面。此外,使用 Scala 作为将在本 Databricks 笔记本中实现的代码的语言。
图 17-6
创建新的数据块笔记本
以下代码将使用 IoT Hub 连接详细信息构建连接字符串,并启动结构化流。在本节中,您将需要改进这个通用代码,它目前包括连接配置的占位符。在运行代码之前,替换以下示例中的物联网集线器连接。此外,记得根据 Azure Portal 中的 IoT Hub 中定义的内容来验证代码中的消费者组:
import org.apache.spark.eventhubs._
import org.apache.spark.eventhubs.{ ConnectionStringBuilder, EventHubsConf, EventPosition }
import org.apache.spark.sql.functions.{ explode, split }
// To connect to an Event Hub, EntityPath is required as part of the connection string.
// Here, we assume that the connection string from the Azure portal does not have the EntityPath part.
val connectionString = ConnectionStringBuilder("—Event Hub Compatible Endpoint--")
.setEventHubName("—Event Hub Compatible Name--")
.build
val eventHubsConf = EventHubsConf(connectionString)
.setStartingPosition(EventPosition.fromEndOfStream)
.setConsumerGroup("delta")
val eventhubs = spark.readStream
.format("eventhubs")
.options(eventHubsConf.toMap)
.load()
在 Azure Portal 的物联网中心的内置端点部分,复制图 17-7 中所示的事件中心兼容名称,并将其替换在提供的代码块的—Event Hub Compatible Name--
部分。
图 17-7
事件中心-内置端点中兼容的名称
接下来,复制图 17-8 所示的事件中枢兼容端点,并将其替换到代码块的—Event Hub Compatible Endpoint--
部分。
图 17-8
事件中心–内置端点中兼容的端点
开始结构化流
本 Databricks 笔记本的第二部分将添加下面提供的代码,该代码旨在获取上一部分中定义的连接,读取流,然后将数据保存到增量表中。图 17-9 中的结果表明流已被成功读取。
图 17-9
用于读取和验证流细节的笔记本代码
接下来,运行以下代码来显示流的详细信息:
display(eventhubs)
图 17-10 显示流正在初始化。
图 17-10
正在初始化流
启动物联网设备模拟器
完成上一步后,前往设备模拟器,输入与集线器名称空间、设备 ID 和设备密钥相关的物联网集线器设备详细信息,然后运行设备模拟器。一旦设备产生事件,这些事件将开始出现在图 17-11 所示设备模拟器底部的折线图中。请注意,正常事件正在生成,因此事件数据在整个过程中相当一致。
图 17-11
设备模拟器详细信息
显示实时流数据
在导航回 Databricks 笔记本并展开display(eventhubs)
代码块的仪表板部分后,请注意与输入相关的输入流的处理指标与处理速率、批处理持续时间和聚集状态,如图 17-12 所示。
图 17-12
显示流的处理度量的仪表板
导航至原始数据选项卡,注意数据流的结构和数据,如图 17-13 所示。
图 17-13
流的结构和数据
创建 Spark SQL 表
由于数据现在是流式的,因此通过在同一个 Databricks 笔记本中的新代码块中运行以下代码来创建一个 Spark SQL 表。请记住根据您的物联网设备数据定义列。在本练习中,使用设备模拟器中的列body
和sequenceNumber
:
import org.apache.spark.sql.types._
import org.apache.spark.sql.functions._
val schema = (new StructType)
.add("body", DoubleType)
.add("sequence_number", DoubleType)
val df = eventhubs.select(($"enqueuedTime").as("Enqueued_Time"),($"systemProperties.iothub-connection-device-id")
.as("Device_ID"),(from_json($"body".cast("string"), schema)
.as("telemetry_json"))).select("Enqueued_Time","Device_ID", "telemetry_json.*")
预期输出将显示spark.sqlDataFrame
的结果,如图 17-14 所示。
图 17-14
spark.sqlDataFrame 的结果
运行以下代码,创建 Spark SQL 表来存储设备遥测数据:
df.createOrReplaceTempView("device_telemetry_data")
图 17-15 显示了该代码在 Databricks 笔记本中的执行结果。
图 17-15
创建 Spark SQL 表
将流写入增量表
将流写入增量表,并开始运行以下代码来定义最终数据帧:
val finalDF = spark.sql("Select Date(Enqueued_Time) Date_Enqueued, Hour(Enqueued_Time) Hour_Enqueued, Enqueued_Time, Device_ID, body AS Body,sequence_number as Sequence_Number from device_telemetry_data")
图 17-16 显示了 Databricks 笔记本中代码的执行结果。
图 17-16
定义最终数据帧的代码
将图 17-17 中所示的下一个代码块复制并粘贴到同一个 Databricks 笔记本中的一个新单元格中。这段代码将把流写入增量表。请注意,您可以定义分区、格式、检查点位置和输出模式。正在使用默认的检查点位置,该位置由 Databricks 定义和管理,但是您也可以轻松地自己定义该位置,并将数据保存到不同的文件夹中:
finalDF.writeStream
.outputMode("append")
.option("checkpointLocation", "/delta/events/_checkpoints/device_delta")
.format("delta")
.partitionBy("Date_Enqueued", "Hour_Enqueued")
.table("delta_telemetry_data")
图 17-17 显示了 Databricks 笔记本中代码的执行结果。
图 17-17
将流写入增量表的代码
注意,在图 17-17 中,输出模式被设置为附加。支持以下输出模式:
-
追加(仅向输出接收器添加新记录)
-
更新(就地更新已更改的记录)
-
完成(重写完整输出)
还可以将触发器添加到写入流中,以定义流数据的处理时间,以及该查询是作为具有固定批处理间隔的微批处理查询还是作为连续处理查询来执行。
这里有几个触发器的例子。Apache Spark 的文档包含更多关于触发器的细节,可以在下面的 URL 中找到: https://spark.apache.org/docs/2.3.0/structured-streaming-programming-guide.html#triggers
.trigger(Trigger.ProcessingTime("2 seconds"))
.trigger(Trigger.Once())
.trigger(Trigger.Continuous("1 second"))
请注意图 17-18 所示的原始数据选项卡,设备数据持续流入,您现在可以查看样本流数据及其结构。
图 17-18
显示设备数据持续流动的原始数据选项卡
最后,编写并执行图 17-19 所示的以下 SQL 查询,以检索结构化流数据正在写入的增量表。然后,该表可用于执行额外的高级分析和/或构建机器学习模型,以获得对物联网设备数据的更有价值的实时洞察:
%sql
SELECT *
FROM delta_telemetry_data
图 17-19 显示了 Databricks 笔记本中代码的执行结果。
图 17-19
查询结构化流数据正在写入的增量表
摘要
在这一章中,我演示了如何使用设备模拟器实现结构化的流解决方案,该模拟器将随机设备数据生成到 Azure IoT Hub 中,由 Apache Spark 通过 Databricks 笔记本进行处理,并流入 Delta Lake 以持久存储数据。我还向您展示了如何定制结构化的流输出模式,包括追加、更新和完成。最后,我介绍了触发器的概念以及如何在您的 Databricks 笔记本代码中实现它们。
在 Databricks 中使用 Apache Spark 进行实时分析是流分析的替代方案,最适合大数据场景或数据非常非结构化的情况,需要 Databricks 中提供的一些高级功能,如模式进化等。它也非常适合将您的实时流与高级分析和机器学习工作流相集成。潜力是无限的,这一章仅仅触及了其中一些功能的表面。
十八、用于 Cosmos DB 的 Azure Synapse 链接
对存储在诸如 Cosmos DB 之类的事务系统中的数据进行近乎实时的洞察,是许多组织的长期目标和需求。Azure Synapse Link for Azure Cosmos DB 是一种云原生混合事务和分析处理(HTAP)功能,允许用户对 Azure Cosmos DB 中的运营数据进行近实时分析。数据工程师、业务分析师和数据科学家现在能够使用 Spark 或 SQL 池获得对其数据的近乎实时的洞察,而不会影响其在 Cosmos DB 中的事务性工作负载的性能。
Azure Synapse Link for Azure Cosmos DB 有许多优势,包括降低复杂性,因为接近实时的分析存储减少或消除了对复杂 ETL 或更改 feed 作业流程的需求。此外,对运营工作负载几乎没有影响,因为分析工作负载是独立于事务工作负载呈现的,不会消耗调配的运营吞吐量。此外,它还通过利用 Spark 和 SQL 按需池的功能,针对大规模分析工作负载进行了优化,由于具有高度弹性的 Azure Synapse 分析计算引擎,这使得它具有成本效益。Azure Synapse Link for Azure Cosmos DB 针对运营数据上的工作负载(包括聚合等)提供了一个面向列的分析存储,以及分析工作负载的解耦性能,支持对交易数据的自助式、近实时洞察,如图 18-1 所示。
图 18-1
Azure Synapse Link 的架构图
在本章中,您将通过实际的端到端练习了解如何实现以下目标:
-
创建一个支持分析存储的基本 Azure Cosmos DB 帐户。
-
在 Azure Synapse Analytics 中创建 Cosmos DB 链接服务。
-
使用 Synapse Workspace 笔记本中的 Spark 来聚合和查询 Cosmos DB 数据。
创建一个 Azure Cosmos DB 帐户
Azure Cosmos DB 是一个完全托管的 NoSQL 数据库服务,用于现代应用开发。你需要从 Azure Portal 创建一个 Azure Cosmos DB 帐户,如图 18-2 所示。
图 18-2
创建一个宇宙数据库
如图 18-3 所示,确保帐户详细信息配置正确,并创建 Azure Cosmos DB 帐户。
图 18-3
配置 Cosmos DB 帐户详细信息
概括地说,在本节中,您使用核心(SQL) API 创建了一个 Azure Cosmos DB 帐户。有许多 API 可供选择,包括 native Core (SQL) API、MongoDB API、Cassandra API、Gremlin API 和 Table API。此外,选择调配吞吐量作为容量模式,因为它最适合具有持续流量、需要可预测性能的工作负载,而无服务器最适合具有间歇或不可预测流量以及较低的平均峰值流量比的工作负载。有关容量模式的更多详情,请参见 https://docs.microsoft.com/en-us/azure/cosmos-db/throughput-serverless
.
启用 Azure Synapse 链接
一旦创建了 Cosmos DB 帐户,您将需要启用 Azure Synapse 链接,默认设置为“关闭”这可以通过首先点击图 18-4 所示的 Azure Synapse 链接功能来实现。
图 18-4
为 Cosmos DB 启用 Synapse Link 的步骤
然后点击“启用”,如图 18-5 所示。
图 18-5
启用 Synapse 链接
图 18-6 显示一旦 Azure Synapse Link 被启用,状态将变为“开启”
图 18-6
Synapse 链接已打开
创建一个 Cosmos DB 容器和数据库
既然已经为 Azure Synapse Link 启用了 Azure Cosmos DB 帐户,那么就创建一个数据库和容器。首先,Cosmos DB 中的 Quick start 部分可以让您更轻松地选择平台、创建数据库和容器,然后开始使用 Cosmos DB 笔记本来运行代码以导入数据。
出于本练习的目的,请使用 Python 平台。然而,请注意可供选择的更多平台选项,如图 18-7 所示。
图 18-7
用 Python 创建新笔记本
图 18-8 显示了如何通过用户界面创建一个数据库和容器。还有一些选项可用于从一个新的笔记本或带有预定义代码的样本笔记本开始。
图 18-8
创建新的 Cosmos DB 容器
您需要配置数据库名称、吞吐量、容器名称和分区键,如图 18-9 所示。您总是可以从包含 400 RU/s 和 5 GB 存储的空闲层开始,然后相应地纵向扩展。
图 18-9
配置容器数据库 id 和吞吐量详细信息
最后,一定要记住设置分区键并打开分析存储器,如图 18-10 所示。分区键用于跨多个服务器自动分区数据,以实现可伸缩性。它是一个分析商店,允许您对数据进行实时分析。
图 18-10
配置剩余的容器详细信息
将数据导入 Azure Cosmos DB
既然您已经创建并配置了数据库和容器的细节,那么创建一个新的笔记本来将数据导入到 Cosmos 数据库容器中,如图 18-11 所示。
图 18-11
在 Cosmos DB 中添加新笔记本
首先读取您在上一步中创建的数据库和容器,如图 18-12 所示。 Azure Cosmos DB Python 示例 ( https://docs.microsoft.com/en-us/azure/cosmos-db/sql-api-python-samples
)有额外的 API 引用命令,可以在笔记本代码中使用。请访问前面的 URL,了解有关为 Azure Cosmos DB 配置和使用 Azure Synapse Link 的更多信息,并查看其他代码片段,包括如何使用analytical_storage_ttl
命令定义和更新分析存储生存时间。
图 18-12
创建或读取新的数据库和容器
下面是如图 18-12 所示的代码,用于读取您在上一节中创建的数据库和容器名称:
import azure.cosmos
from azure.cosmos.partition_key import PartitionKey
database = cosmos_client.get_database_client('RetailDemo')
print('Database RetailDemo Read')
container = database.get_container_client('WebsiteData')
print('Container WebsiteData Read')
一旦数据被读取,您可以通过使用图 18-13 所示的代码来更新容器的吞吐量,以允许更快的上传。
图 18-13
加载前扩大吞吐量
以下是图 18-13 中所示的代码,用于更新容器的吞吐量,以加快上传速度:
old_throughput = container.read_offer().offer_throughput
new_throughput = container.replace_throughput(1000).offer_throughput
print("Container WebsiteData's throughput updated from {} RU/s to {} RU/s".format(old_throughput, new_throughput))
接下来,使用图 18-14 所示的%%upload magic 函数将物品插入容器。
图 18-14
将数据加载到 Cosmos DB
下面是图 18-14 所示的代码,它使用%%upload 魔法函数将项目插入容器:
%%upload --databaseName RetailDemo --containerName WebsiteData --url https://cosmosnotebooksdata.blob.core.windows.net/notebookdata/websiteData.json
图 18-15 显示了一旦数据加载完成,如何通过编程降低容器的吞吐量。
图 18-15
加载完成后,缩减吞吐量
下面是图 18-15 所示的代码,用于在数据加载完成后按比例降低容器的吞吐量:
lowered_throughput = container.replace_throughput(400).offer_throughput
print("Container WebsiteData's throughput lowered from {} RU/s to {} RU/s".format(new_throughput, lowered_throughput))
在 Azure Synapse Analytics 中创建 Cosmos DB 链接服务
在 Cosmos DB 数据库容器中提供数据后,按照图 18-16 中所示的步骤,在 Azure Synapse Analytics 工作区中创建一个链接服务。
图 18-16
在 Synapse Analytics 中创建 Cosmos DB 链接
记得选择 Azure Cosmos DB (SQL API),如图 18-17 所示,因为这是 Azure Cosmos DB API 的配置。注意,还有一个 MongoDB API 选项。
图 18-17
创建到 Cosmos DB 的链接的步骤
填写图 18-18 中所示的所需连接配置细节,并创建新的链接服务。
图 18-18
创建新的链接服务
使用 Synapse Spark 加载和查询数据
从 Azure Synapse Analytics 创建一个新的链接到 Cosmos DB 的服务后,按照图 18-19 所示的步骤创建一个新的笔记本并将数据加载到数据框中。
图 18-19
将数据加载到数据框进行分析
我想说明支持分析存储的容器和不支持分析存储的容器之间的视觉差异。基本上,启用分析存储的容器将有额外的三行,代表分析工作负载的列存储,如图 18-20 所示。
图 18-20
启用非分析存储
创建链接服务后,运行以下代码,该代码将在数据加载到上一步中的数据框时自动创建。在运行代码之前,记得创建一个 Synapse Spark pool 并将其连接到笔记本:
# Read from Cosmos DB analytical store into a Spark DataFrame and display 10 rows from the DataFrame
# To select a preferred list of regions in a multi-region Cosmos DB account, add .option("spark.cosmos.preferredRegions", "<Region1>,<Region2>")
df = spark.read\
.format("cosmos.olap")\
.option("spark.synapse.linkedService", "LS_CosmosDb_RetailDemo")\
.option("spark.cosmos.container", "WebsiteData")\
.load()
display(df.limit(10))
请注意图 18-21 中的插图,代码运行成功,并使用了两个执行器和八个内核来完成任务。请注意,这可以进行定制,以适应您所需的工作负载。此外,可以在 Spark UI 中查看作业细节。
图 18-21
要加载到数据框的代码
图 18-22 显示了数据框中前十条记录的预览,这证实了实时查询功能处于活动状态。
图 18-22
返回的样本数据的图像
接下来,使用以下代码聚合数据集以获得价格列的总和,然后显示数据框:
from pyspark.sql.functions import *
df = df.agg(sum(col('Price')))
df.show()
在作业完成运行后,图 18-23 显示了操作性 Cosmos DB 数据上成功聚合的价格列,而无需利用任何定制的 ETL 过程。这展示了利用这种 Azure Synapse Link for Cosmos DB 功能的未来方法的能力,以使自助服务数据用户能够以接近实时的速度获得对其数据的洞察。
图 18-23
汇总价格数据
摘要
在本章中,我向您展示了如何创建一个支持分析存储的基本 Azure Cosmos DB 帐户,如何在 Azure Synapse Analytics 中创建一个 Cosmos DB 链接服务,以及如何使用 Synapse Workspace 笔记本中的 Spark 来聚合和查询 Cosmos DB 数据。
通过设置这一流程,您的组织能够从对事务性数据的实时分析中获得有价值的见解,这使得业务分析师、数据科学家、数据工程师和其他公民开发人员能够分析大型数据集,而不会影响事务性工作负载的性能。除了其他各种好处之外,这个过程减少了构建和管理复杂 ETL 作业的需要。
十九、部署数据工厂更改
使用 Azure DevOps 持续集成和部署流程的最佳实践将 Azure Data Factory 从一个环境部署到另一个环境的迫切需求为成功完成部署流程带来了许多复杂性。在本章中,我将介绍如何利用 PowerShell 脚本和 Azure 资源组部署任务来启动/停止 ADF 触发器,并通过 Azure DevOps 的 Azure 数据工厂 CI/CD 更改的端到端部署来更改 ADF 环境连接配置属性。
先决条件
要继续这个练习,你需要一些必备的 Azure 资源。本节展示了在构建端到端 CI/CD 流程之前必须创建和运行的内容。
图 19-1 显示了一个包含一些 Azure 资源的 DEV 资源组的图像。类似地,图 19-2 显示了一个 QA 资源组的图像,它包含与 DEV 资源组相同的 Azure 资源。在本练习中,您将重点关注通过自动化的 DevOps CI/CD 管道将 ADF 变更从一个环境部署到另一个环境。对于这个练习,您需要手动创建 QA 数据工厂。您还需要一个 DEV 和 QA 密钥库,它将存储本章中用到的相关凭证和秘密。另请注意,还创建了 SQL Server、SQL 数据库和 ADLS Gen2 帐户,主要是为了显示较低环境(DEV)中的资源与较高环境(QA)中的资源的一致性,并将这些资源用作 DEV 资源组的 ADF 中的链接服务连接,该 ADF 将部署到 QA ADF。
创建如图 19-1 所示的开发资源组。该资源组将包含下层环境(DEV) Azure 数据工厂、ADLS Gen2 和 SQL 数据库,其更改将作为 DevOps CI/CD 管道的一部分持续部署到上层环境(QA)。
图 19-1
Azure 门户开发资源组
然后创建如图 19-2 所示的 QA 资源组。该资源组将包含上层环境(QA) Azure 数据工厂、ADLS Gen2 和 SQL 数据库。
图 19-2
Azure 门户 QA 资源组
在图 19-3 所示的 DEV 资源组和图 19-4 所示的 QA 资源组中创建以下密钥库帐户机密。请注意,出于部署目的,DEV 和 QA 帐户中的机密名称必须相同。然而,实际的秘密在开发和 QA 之间是独特的:
-
ls-adls2-akv :这将包含 DEV 和 QA ADLS Gen2 账户的访问密钥,可在各自的 DEV 和 QA 数据湖存储账户的访问密钥部分找到。
-
ls-sql-akv :这将包含用于验证目的的开发和 QA Azure SQL 服务器和数据库的管理员密码。
图 19-3 显示了您在 DEV 资源组中创建并启用的秘密。
图 19-3
Azure 门户开发密钥保管库机密
类似地,图 19-4 显示了您在 QA 资源组中创建和启用的秘密。
图 19-4
Azure 门户 QA 密钥库机密
在 DEV 密钥库内,记住通过添加密钥库访问策略来授予 DEV 数据工厂对密钥库的 get 和 list 权限访问,如图 19-5 所示。
图 19-5
Azure 门户开发密钥库访问策略
类似地,在 QA 密钥库中,记得通过添加密钥库访问策略来授予 QA 数据工厂对密钥库的 get 和 list 权限,如图 19-6 所示。
图 19-6
Azure 门户 QA 密钥库访问策略
出于测试目的,在开发数据工厂中创建以下链接服务,如图 19-7 所示。
图 19-7
开发数据工厂中的链接服务
以下是 Azure 数据湖存储链接服务连接的 JSON 脚本:
{
"name": "LS_AzureDataLakeStorage",
"properties": {
"annotations": [],
"type": "AzureBlobFS",
"typeProperties": {
"url": "https://adls2dev.dfs.core.windows.net",
"accountKey": {
"type": "AzureKeyVaultSecret",
"store": {
"referenceName": "LS_AzureKeyVault",
"type": "LinkedServiceReference"
},
"secretName": "ls-adls2-akv",
"secretVersion": ""
}
}
}
}
以下是 Azure Key Vault 链接服务连接的 JSON 脚本:
{
"name": "LS_AzureKeyVault",
"properties": {
"annotations": [],
"type": "AzureKeyVault",
"typeProperties": {
"baseUrl": "https://rl-kv-001-dev.vault.azure.net/"
}
}
}
以下是 Azure SQL 数据库链接服务连接的 JSON 脚本:
{
"name": "LS_AzureSqlDatabase",
"type": "Microsoft.DataFactory/factories/linkedservices",
"properties": {
"annotations": [],
"type": "AzureSqlDatabase",
"typeProperties": {
"connectionString": "Integrated Security=False;Encrypt=True;Connection Timeout=30;Data Source=rl-sqlserver-001-dev.database.windows.net;Initial Catalog=rl-sql-001-dev;User ID=devadmin",
"password": {
"type": "AzureKeyVaultSecret",
"store": {
"referenceName": "LS_AzureKeyVault",
"type": "LinkedServiceReference"
},
"secretName": "ls-sql-akv"
}
}
}
}
图 19-8 显示了您将需要在开发数据工厂中启动的触发器,用于测试目的并演示触发器如何影响从一个环境到另一个环境的 ADF 变更的部署,例如,它将需要由 Azure DevOps CI/CD 管道停止并重新启动。图 19-8 将帮助你理解这个触发器将存在于何处。
图 19-8
开发数据工厂中的触发器
一旦添加了链接的服务连接和触发器,发布 DEV 数据工厂以将更改提交到 adf_publish 分支,并为 DevOps CI/CD 流程做准备。请注意,这个方法将使用 adf_publish 分支,而不是 CI/CD 部署流程的主分支。请确认数据工厂的添加和变更已经发布到 GitHub repo 中的 adf_publish 分支,如图 19-9 所示。
图 19-9
发布到 adf_publish 分支的更改
最后,添加示例预部署和后部署脚本,它包含在 ADF (
https://docs.microsoft.com/en-us/azure/data-factory/continuous-integration-deployment#script
)
中微软关于持续集成和交付的文章的底部。还要确保将文件添加到与图 19-10 所示的 DEV ADF 资源相同的文件夹中,并将其命名为 cicd。ps1 。这个文件的详细内容也可以在我的 GitHub repo (
https://github.com/ronlesteve/demo-dev-adf/blob/adf_publish/rl-adf-001-dev/cicd.ps1
)中找到。
图 19-10
部署前和部署后脚本示例
创建 DevOps 持续集成构建管道
在创建所有必要的先决条件后,您可以通过在 Azure DevOps pipelines 中单击“新建管道”来开始创建 Azure DevOps 持续集成构建管道,如图 19-11 所示。
图 19-11
新构建管道
选择图 19-12 所示用户界面底部的“使用经典编辑器”链接,以避免使用 YAML 代码创建管道。作为参考,YAML 是一种人类可读的数据序列化语言,通常用于配置文件和存储或传输数据的应用中。
图 19-12
使用经典编辑器
选择 GitHub,因为那是保存代码报告的地方。同时选择回购名称和 adf_publish 分支,如图 19-13 所示。
图 19-13
选择 GitHub 源和回购详细信息
从一个空的作业模板开始,如图 19-14 所示。
图 19-14
从一个空的作业模板开始
单击代理作业上的+图标添加新任务。还要添加发布构建工件任务,这可以在图 19-15 中看到。
图 19-15
添加发布构建工件任务
配置发布构建工件任务,如图 19-16 所示,然后点击保存&队列,启动运行管道的过程。
图 19-16
配置发布构建工件任务
验证图 19-17 中的运行管线细节,并点击运行开始手动运行管线。
图 19-17
运行管道
一旦作业成功完成运行,验证工件是否已经发布,如图 19-18 所示。
图 19-18
验证已发布的工件
正如所料,图 19-19 所示的文件夹似乎包含了创建和配置发布管道所需的所有工件。
图 19-19
Azure DevOps 中发布的工件
创建 DevOps 持续部署发布渠道
既然已经成功完成并验证了持续集成(CI)构建管道,那么是时候创建新的持续部署(CD)发布管道了。如图 19-20 所示,点击新建发布管道开始此过程。
图 19-20
新发布管道
点击添加工件,如图 19-21 所示。请注意,在图表中,您还可以在必要时设置自动运行计划。工件可能由项目源代码、依赖项、二进制文件或资源组成。对于这个场景,工件将直接来自您在构建阶段创建的输出。
图 19-21
添加工件
选择“构建”作为来源类型。另外,选择在上一节中创建的构建管道,并填充额外的必需细节,如图 19-22 所示。最后,单击添加完成这一步。
图 19-22
添加构建工件详细信息
接下来,添加一个阶段,如图 19-23 所示。阶段由作业和任务组成,您可以将管道中的部署作业组织成阶段,这些阶段是发布管道中的主要部分。
图 19-23
添加一个阶段
从图 19-24 所示的空作业模板开始。作业是作为一个单元按顺序运行的一系列步骤,每个管道必须至少有一个作业。
图 19-24
从一个空的作业模板开始
接下来,点击链接添加任务,如图 19-25 所示。任务是定义管道中自动化的构建块。任务只是一个打包的脚本或过程,已经用一组输入进行了抽象。
图 19-25
添加任务的链接
首先添加一个 Azure PowerShell 脚本任务,如图 19-26 所示。这将用于停止数据工厂触发器。
图 19-26
Azure PowerShell 脚本任务
另外增加一个 ARM 模板部署任务,如图 19-27 所示。这将用于将数据工厂工件和参数部署到期望的环境中。
图 19-27
ARM 模板部署任务
最后,还要添加另一个 Azure PowerShell 任务,如图 19-28 。这将用于重新启动数据工厂触发器。
图 19-28
Azure PowerShell 任务重新启动 ADF 触发器
在配置之前,确保所有三个任务按照图 19-29 所示的顺序组织。第一个 PowerShell 脚本任务将停止您在 DEV ADF 中创建的 ADF 触发器。第二个 ARM 模板部署任务将 ADF 更改从开发环境部署到 QA 环境,第三个 PowerShell 脚本任务将重新启动触发器。
图 19-29
组织代理作业任务
Azure PowerShell 任务停止触发器
开始配置 Azure PowerShell 脚本,停止 QA 环境中的数据工厂触发器,如图 19-30 所示。确保脚本路径指向您在先决条件步骤中添加到 GitHub repo 的 cicd.ps1 文件。
图 19-30
配置 Azure PowerShell 脚本以停止 ADF 触发器
请确保添加脚本路径和参数。以下是您在图 19-30 中看到的数值:
预部署脚本路径:应为全限定路径或相对于默认工作目录,如以下代码所示:
$(System.DefaultWorkingDirectory)/_ADF-Demo-Project-CI1/dev/cicd.ps1
预部署脚本参数:传递给 PowerShell 的附加参数,可以是序号参数,也可以是命名参数,如以下代码所示:
-armTemplate "$(System.DefaultWorkingDirectory)/_ADF-Demo-Project-CI1/dev/ARMTemplateForFactory.json" -ResourceGroupName rl-rg-001-dev -DataFactoryName rl-adf-001-dev -predeployment $true -deleteDeployment $false
ARM 模板部署任务
这个发布管道任务将使用您从构建管道发布到 DevOps 工件的开发数据工厂的模板和模板参数来增量更新 QA 资源组。这些工件在开发数据工厂中发布,并提交到 adf_publish 分支 GitHub repo。务必选择合适的armtemplateforfactory . JSON和armtemplateparametersforfactory . JSON文件,如图 19-31 所示。
图 19-31
创建或更新资源组的任务
一旦图 19-31 中的所有其他 Azure 细节配置完成,通过点击…图标选择覆盖模板参数,如图 19-32 所示。
图 19-32
覆盖模板参数
部署任务中定义了以下模板和参数,如图 19-31 和 19-32 所示:
部署模板:指定指向 Azure 资源管理器模板的路径或模式。有关模板的更多信息,请访问以下网址( https://aka.ms/azuretemplates
),
),要开始使用示例模板,请访问以下网址: https://aka.ms/sampletemplate
。
$(System.DefaultWorkingDirectory)/_ADF-Demo-Project-CI1/dev/ARMTemplateForFactory.json.
模板参数:确保选择指向 Azure 资源管理器模板参数文件的路径或模式:
$(System.DefaultWorkingDirectory)/_ADF-Demo-Project-CI1/dev/ARMTemplateParametersForFactory.json
覆盖模板参数:覆盖模板参数文本框旁边的“…”将显示模板参数。您还可以在文本框中键入要覆盖的模板参数,例如,–storageName fabrikam –adminUsername $(vmusername) -adminPassword $(password) –azureKeyVaultName $(fabrikamFibre).
如果您将使用的参数值有多个单词,请确保用引号将它们括起来,即使您使用变量传递它们,例如,-name " parameter value "-name 2 " $(var)"。要覆盖对象类型参数,请使用字符串化的 JSON 对象,例如,-options[" option 1 "]-map { " key 1 ":" value 1 " }。
-factoryName "rl-adf-001-qa" -LS_AzureSqlDatabase_connectionString "Integrated Security=False;Encrypt=True;Connection Timeout=30;Data Source=rl-sqlserver-001-qa.database.windows.net;Initial Catalog=rl-sql-001-qa;User ID=qaadmin" -LS_AzureDataLakeStorage_properties_typeProperties_url "https://adls2qa.dfs.core.windows.net" -LS_AzureKeyVault_properties_typeProperties_baseUrl "https://rl-kv-001-qa.vault.azure.net/"
将覆盖模板参数更改为图 19-33 所示的 QA 资源和连接属性,并点击确定保存配置设置。
图 19-33
将覆盖模板参数更改为 QA
Azure PowerShell 任务启动触发器
最后,配置 Azure PowerShell 脚本以在 QA 环境中启动数据工厂触发器。确保脚本路径指向您在先决条件步骤中添加到 GitHub repo 的 cicd.ps1 文件。如图 19-34 所示。
图 19-34
重新启动 ADF 触发器的 PowerShell 任务
另外,将以下部署后脚本路径添加到任务配置中,如图 19-34 所示:
$(System.DefaultWorkingDirectory)/_ADF-Demo-Project-CI1/dev/cicd.ps1
您还需要将以下部署后脚本参数添加到任务配置中,如图 19-34 所示:
-armTemplate "$(System.DefaultWorkingDirectory)/_ADF-Demo-Project-CI1/dev/ARMTemplateForFactory.json" -ResourceGroupName rl-rg-001-dev -DataFactoryName rl-adf-001-dev -predeployment $false -deleteDeployment $true
运行发布管道
添加和配置如图 19-35 所示的持续部署(CD)发布管道任务后,运行发布管道。
图 19-35
运行发布管道
不出所料,图 19-36 显示释放成功。
图 19-36
发布成功
导航到图 19-37 所示的日志后,验证发布管道中的所有步骤都已成功完成。
图 19-37
代理作业部署流程成功
验证部署的数据工厂资源
作为确保 QA 数据工厂更改已正确部署的最后一项检查,导航到 QA 数据工厂并检查链接的服务连接。正如所料,请注意图 19-38 中所示的三个链接的服务连接。
图 19-38
ADF QA 链接的服务连接
此外,还添加并启动了一个触发器。这是在增量 DevOps CI/CD 过程中将要停止和重新启动的触发器,如图 19-39 所示。
图 19-39
处于“已启动”状态的 ADF QA 触发器
进一步深入,注意数据湖的连接字符串已经改变,并且连接已经成功测试,如图 19-40 所示。
图 19-40
ADF QA 与 ADLS Gen2 的连接
图 19-41 显示密钥库连接也被更改为 QA 并已成功测试。
图 19-41
更新了与密钥库的 ADF QA 连接
最后,请注意,SQL Server 和数据库连接也被更改为 QA,并且测试连接已被成功验证,如图 19-42 所示。
图 19-42
到 SQL Server 和数据库的 ADF QA 连接已更新
摘要
在本章中,我演示了如何使用 PowerShell 脚本和 Azure 资源组部署任务来启动/停止 ADF 触发器,并通过 Azure DevOps 的 Azure 数据工厂 CI/CD 更改的端到端部署来更改 ADF 环境连接配置属性。有关本练习的更多信息,特别是要找到本章涉及的示例,请访问以下 URL 查看我的 GitHub repo:https://github.com/ronlesteve/demo-dev-adf/tree/adf_publish
。对于为 ADF 管道部署 JSON 的替代方法,除了 ARM 模板部署,探索发布 ADF 任务( https://marketplace.visualstudio.com/items?itemName=SQLPlayer.DataFactoryTools
),该任务可以在 Visual Studio marketplace 中找到,并且可以作为任务添加到 Azure DevOps CI/CD 管道中。
二十、部署 SQL 数据库
开发和测试应用的 DevTest 环境与生产环境之间的基础结构差异和不一致性是 IT 专业人员和软件开发人员可能会遇到的常见情况。尽管应用最初是以正确的方式部署的,但是对生产环境所做的配置更改可能会导致差异。客户经常会问,是否有一种无缝的方式来自动创建 Azure 资源,同时确保跨多个环境的一致性。
基础设施即代码是创建模板的过程,该模板定义并随应用一起部署环境,以确保一致性。Azure 资源管理器(ARM)是 Azure 的部署和管理服务。它提供了一致的管理层,使您能够创建、更新和删除 Azure 订阅中的资源。部署后,您可以使用其访问控制、审计和标记功能来保护和组织您的资源。
通过使用 ARM 模板,您可以通过声明性模板而不是脚本来管理您的基础架构,并作为一个组来部署、管理和监控您的解决方案的所有资源,而不是单独处理这些资源。此外,您可以在整个开发生命周期中重复部署您的解决方案,并且确信您的资源以一致的状态部署。
Visual Studio 中有几个源代码管理选项。GitHub 是这些源代码控制选项之一,它提供了许多好处,包括高级安全选项。集成多个应用,如 Visual Studio、GitHub、Azure DevOps 和 Azure SQL 数据库,以实现无缝 CI/CD 流程,这是许多企业在实现数据和基础架构平台现代化的过程中日益增长的需求。在本章中,我将展示图 20-1 所示架构流程的端到端解决方案,通过 GitHub 存储库将 AdventureWorksLT2019 数据库从 Visual Studio 部署到 Azure SQL 数据库,然后通过 Azure DevOps 构建(CI)和发布(CD)管道进行部署。
图 20-1
使用 GitHub repo 和 Visual Studio Azure SQL 数据库项目的 Azure DevOps CI/CD
先决条件
在您开始图 20-1 所示的架构模式的开发和部署过程之前,您需要创建以下先决资源:
-
SSDT 版 Visual Studio 2019:您将使用 Visual Studio 2019 和 SSDT 版 Visual Studio 来部署这个数据库项目解决方案。你可以从这个网址下载最新版本的 Visual Studio:
https://visualstudio.microsoft.com/downloads/
。此外,您可以从以下网址下载 SQL Server Data Tools(SSDT)for Visual Studio:https://docs.microsoft.com/en-us/sql/ssdt/download-sql-server-data-tools-ssdt?view=sql-server-ver15
。 -
GitHub 帐户和回购:由于您将把您的 Visual Studio 项目与 GitHub 源代码控制帐户相关联,因此您可以使用该 URL 来了解更多有关如何在 GitHub
(
www.wikihow.com/Create-an-Account-on-GitHub
)
中创建帐户的信息。此外,您可以从这个 URL:https://docs.github.com/en/enterprise/2.16/user/github/getting-started-with-github/create-a-repo
了解更多关于如何创建 GitHub repo 的信息。 -
Azure DevOps 帐户和项目:最后,您将需要一个 Azure DevOps 帐户和项目,用于构建 CI/CD 流程。您可以使用以下 URL 作为参考来创建组织和项目:
https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/create-organization?view=azure-devops
。
创建 Visual Studio SQL 数据库项目
首先在 Visual Studio 2019 中创建新的 SQL 数据库项目,如图 20-2 所示。在项目中,您将导入示例 AdventureWorks 数据库。
图 20-2
创建 VS 项目的步骤
接下来,图 20-3 显示了您应该如何通过输入项目名称、位置和解决方案来配置和创建新的 SQL 数据库项目。
图 20-3
配置项目的步骤
安装 Visual Studio GitHub 扩展
由于这个 Visual Studio 解决方案将链接到 GitHub 源代码控制库,您将需要安装如图 20-4 所示的 GitHub 扩展,这将把 GitHub 流引入 Visual Studio。
图 20-4
安装 GitHub 扩展的步骤
此时,您应该关闭 Visual Studio 以完成 GitHub 扩展安装,这将启动如图 20-5 所示的安装。
图 20-5
显示扩展安装程序的图像
导入 AdventureWorks 数据库
重新打开 Visual Studio 项目,导入 AdventureWorksLT2019 Dacpac 文件,如图 20-6 所示。您可以从以下 URL 下载 AdventureWorks 示例数据库,用于导入过程: https://docs.microsoft.com/en-us/sql/samples/adventureworks-install-configure?view=sql-server-ver15&tabs=ssms
。
图 20-6
导入数据层的步骤
点击数据层应用选项后,会出现如图 20-7 所示的导入数据层应用文件界面,您需要选择合适的 Dacpac 文件并点击开始。
图 20-7
步骤 2 导入数据层 Dacpac
点击完成继续导入过程,如图 20-8 所示。请注意,状态和导入步骤显示在这个摘要 UI 中。
图 20-8
摘要导入进度的图像
一旦导入了数据层应用,模式将作为文件夹列在 SQL Server 数据库项目中,如图 20-9 所示。
图 20-9
AdventureWorks 解决方案项目的图像
确保从图 20-10 中的数据库项目属性 GUI 将数据库项目目标平台设置为 Microsoft Azure SQL Database。
图 20-10
项目属性和目标平台的图像
连接到 GitHub Repo 源代码控制
现在项目已经被导入并配置好了,将解决方案添加到 GitHub 源代码控制中,如图 20-11 所示。开始连接过程时,会要求您登录 GitHub。
图 20-11
向源代码管理添加解决方案的步骤
此时,继续从 Visual Studio GUI 提示符连接到 GitHub,如图 20-12 所示,使用您的 GitHub 凭证登录。
图 20-12
登录 GitHub 的步骤
会出现一个提示,授权 Visual Studio 和 GitHub 集成在一起。查看配置设置,然后点击授权 github,如图 20-13 所示。
图 20-13
授权 Visual Studio 的步骤
将 Visual Studio 解决方案签入 GitHub Repo
现在,解决方案已经添加到 GitHub 存储库中,单击 home,然后单击 sync,将解决方案签入并同步到 GitHub 存储库中,如图 20-14 所示。
图 20-14
同步到回购的步骤
此时,验证同步细节并点击发布,如图 20-15 所示,将解决方案同步到所需的 GitHub repo。
图 20-15
发布到回购的步骤
成功发布同步设置后,验证 Visual Studio 解决方案是否已签入选定的 GitHub repo 和分支。在图 20-16 中,注意解决方案和数据库已经被登记到存储库中。
图 20-16
GitHub repo 的图像
从 GitHub 安装 Azure 管道
既然已经将 Azure GitHub 与 Visual Studio 集成在一起,那么是时候从 GitHub Marketplace 安装 Azure Pipelines 来将 GitHub 与 Azure DevOps 集成在一起了。前往市场,搜索并点击 Azure Pipelines,如图 20-17 所示,这将导航到 Azure Pipelines 设置页面。
图 20-17
添加 Azure 管道
Azure Pipelines 自动构建和测试代码项目,以使它们对其他人可用。它几乎适用于任何语言或项目类型。Azure Pipelines 结合了持续集成(CI)和持续交付(CD ),以持续一致地测试和构建您的代码,并将其发送到任何目标。通过点击图 20-18 所示的设置计划来设置 Azure Pipelines 计划。
图 20-18
建立 Azure 管道计划
查看定价详情(
https://azure.microsoft.com/en-us/pricing/details/devops/azure-devops-services/
)
了解更多关于 Azure DevOps 管道的详情。我通常建议从免费层开始,并根据需要进行扩展。在这个练习中,您可以选择免费帐户,它有许多免费的好处。点击免费安装,如图 20-19 所示,开始 Azure 管道安装过程。
图 20-19
安装 Azure 管道计划的步骤
您将被要求检查您的订单,然后完成订单以开始安装。请注意图 20-20 中的内容,使用免费计划,您将不会按月支付任何费用。
图 20-20
完成 Azure 管道安装计划的步骤
此时,选择是将 Azure Pipelines 安装到所有还是选定的存储库,点击安装,如图 20-21 所示。请注意,读写访问权限显示在安装页面上。
图 20-21
安装 Azure 管道的步骤
出现提示时,选择您的 Azure DevOps 管道项目和组织,点击继续,如图 20-22 所示。
图 20-22
设置 Azure 管道项目
出现提示时,授权 Azure Pipelines 和 GitHub 之间的集成,如图 20-23 所示。
图 20-23
授权 Azure 管道的步骤
从 GitHub Repo 构建 CI 管道
现在,您已经准备好从 GitHub repo 构建一个持续集成(CI)管道了。点击使用经典编辑器,如图 20-24 所示,创建没有 YAML 的构建管道。
图 20-24
选择代码位置的步骤
请注意,还有一个选项是创建需要 YAML 代码的 YAML 管道。想了解更多关于 YAML 的信息,我推荐阅读这篇文章,在 www.cloudbees.com/blog/yaml-tutorial-everything-you-need-get-started/
几分钟内开始了解 YAML。图 20-25 展示了一个 YAML 代码块的示例,以及你如何编写和配置它作为一个新的管道选项运行。在本练习中,使用经典编辑器创建管道。
图 20-25
显示 YAML 代码选项的图像
对于不使用 YAML 的经典选项,从空工单开始,如图 20-26 所示。
图 20-26
选择一个空作业模板
接下来,选择 GitHub 作为源。请注意图 20-27 中有许多可用的信号源选项可供选择。此外,选择所需的回购和分支。
还有一些额外的可用设置,通常设置为图 20-27 中列出的默认值。这些选项包括以下内容:
图 20-27
选择 GitHub 源
-
Clean :允许您在构建运行之前对私有代理的工作目录进行各种清理。
-
标记源代码:允许您在构建完成后标记源代码文件,以识别每个文件的哪个版本包含在完成的构建中。
-
报告构建状态:在源存储库上显示一个标记,指示构建是成功还是失败。
-
签出子模块:签出您的 Git 子模块,如果它们在同一个存储库中或者在一个公共存储库中。
-
从 LFS 检出文件:配置本地工作目录,但跳过同步源。
-
不同步源:限制从每个远程分支历史的尖端获取指定数量的提交,并允许您在获取深度选项中指定提交数量。
搜索并添加 MSBuild 任务到管道中,如图 20-28 所示。此任务将生成 Visual Studio 解决方案。
图 20-29
MSBuildConfig 的图像
图 20-28
添加 MSBuild 任务
验证图 20-29 中所示的 MSBuild 配置。**/*的相对通配符路径。sln 足以识别解决方案文件。
另外,添加如图 20-30 所示的复制文件任务,该任务将文件复制到工件暂存目录。空的源文件夹指定了存储库的根目录。在 Contents 中,复制指定源文件夹中的所有文件,**复制指定源文件夹中的所有文件以及所有子文件夹中的所有文件, * *从任何 bin 文件夹中递归复制所有文件。最后,使用变量构建目标文件夹。
图 20-30
添加复制文件任务
在复制文件任务中,验证图 20-31 所示的可用配置选项。
图 20-31
拷贝文件配置的图像
最后,添加如图 20-32 所示的发布构建工件任务,将暂存目录工件发布到 Azure 管道。
图 20-32
添加发布构建工件的步骤
验证图 20-33 中所示的发布构建工件配置。注意,要发布的路径是由一个变量指定的。
图 20-33
显示发布构建工件配置的步骤
验证构建管道任务的顺序是否正确,如图 20-34 所示。点击&保存队列。
图 20-34
构建任务摘要
验证图 20-35 所示的运行管线参数,点击保存并运行。
图 20-35
运行管道任务配置的图像
注意图 20-36 中的构建管道摘要,它包含了工作的细节和状态。
图 20-36
构建管道摘要
代理作业完成运行后,您将能够确认成功的作业状态。图 20-37 中的绿色复选框表示工作中所有任务步骤的成功完成。
图 20-37
构建作业摘要的图像
从 DevOps 项目报告中释放 CD 管道
既然已经创建并成功部署了构建管道,那么是时候创建发布管道了。首先添加一个发布管道工件,如图 20-38 所示。
图 20-38
添加发布工件的步骤
选择构建工件作为源类型,如图 20-39 所示。请注意其他可用的来源选项,其中包括各种来源回购。完成其他必需详细信息的配置,然后单击添加。
图 20-39
将构建工件添加到发布中
当提示选择模板时,为该阶段添加一个空作业。这可以通过点击表示空工单的蓝色链接找到,如图 20-40 所示。
图 20-40
选择空作业模板
验证图 20-41 所示的载物台属性。
图 20-41
验证阶段属性
在阶段内增加一个任务,如图 20-42 所示。
图 20-42
添加阶段任务
验证新发布管道中的代理作业详细信息,如图 20-43 所示。
图 20-43
发布代理配置的图像
首先添加一个 Azure Key Vault 任务,作为存储您的 SQL 数据库凭证的安全方式,这些凭证包括您的用户名和密码,它们作为秘密存储在 Azure Key Vault 中,如图 20-44 所示。
图 20-44
添加 Azure Key Vault 任务
实现这一点所需的步骤如图 20-45 所示,首先通过点击管理添加你的 Azure 订阅,然后登录到你的 Azure 帐户,从你的 Azure 订阅中选择你的密钥库帐户,最后选择秘密,在这种情况下将是登录密码和登录用户。
图 20-45
配置 Azure 密钥库任务
接下来,您需要添加一个 Azure SQL 数据库部署任务,如图 20-46 所示,该任务将使用 Dacpac 文件部署 Azure SQL 数据库。
图 20-46
添加 Azure SQL 数据库部署任务
填充必要的 Azure SQL 数据库部署参数,如图 20-47 所示。
图 20-47
填充必要的 Azure SQL 数据库部署参数
此外,在 Azure SQL Dacpac 任务中,选择 AdventureWorksLT2019 Dacpac 文件,该文件是从以前的构建管道中构建并存储在工件放置目录中的,如图 20-48 所示,然后单击确定。
图 20-48
选择 Dacpac 文件
继续创建新的发布管道,点击创建,如图 20-49 所示。
图 20-49
创建新版本
验证释放管道已经成功,如图 20-50 的阶段部分所示。
图 20-50
显示发布管道运行状态的图像
此外,验证代理作业初始化作业、下载工件、部署 Azure SQL Dacpac 任务以及成功完成作业的步骤。这些成功完成的代理作业步骤可以在图 20-51 中看到。
图 20-51
该图显示了发布代理作业摘要
验证部署的 Azure SQL AdventureWorks 数据库
在该过程的最后一步中,通过 SSMS 登录到 Azure SQL 数据库,以验证 AdventureWorksLT2019 数据库是否存在于指定的部署位置。请注意图 20-52 中的所有数据库对象都已成功部署到 Azure SQL 数据库。
图 20-52
通过 SSMS 验证 Azure SQL 数据库是否存在
摘要
在本章中,我演示了如何在 Visual Studio 中使用数据库 Dacpac 文件设计和实现一个端到端的解决方案来部署 AdventureWorksLT2019 数据库更改。该 Visual Studio 解决方案连接到 GitHub 库进行源代码控制,并链接到 Azure DevOps 管道。练习最后向您展示了如何使用 Azure DevOps 构建(CI)和发布(CD)管道,通过持续集成和部署方法将此 AdventureWorksLT2019 数据库部署到 Azure SQL 数据库。
二十一、将 Apache Spark 的 GraphFrame API 用于图形分析
图形技术使用户能够以图形的形式存储、管理和查询数据,其中实体被称为顶点或节点,实体之间的关系被称为边。图形分析支持通过查询和算法分析深度关系的能力。
Apache Spark 的 GraphFrame API 是一个 Apache Spark 包,它通过 Java、Python 和 Scala 中的高级 API 提供基于数据帧的图形,并包括用于主题查找、基于数据帧的序列化和高度表达的图形查询的扩展功能。使用 GraphFrames,您可以轻松地在图形中搜索模式,找到重要的顶点,等等。
图是一组点,称为节点或顶点,它们通过一组称为边的线相互连接,如图 21-1 所示。
图 21-1
描绘边和顶点
有向图有带方向的边。这些边表示一种单向关系,即每条边只能在一个方向上遍历,如图 21-2 所示。常见的有向图是家谱树,它映射了父母和子女之间的关系。
无向图有没有方向的边,如图 21-2 。这些边表示双向关系,因为每个边都可以在两个方向上遍历。一个常见的无向图是计算机网络中的连接拓扑。该图是无向的,因为我们可以假设,如果一个设备连接到另一个设备,那么第二个设备也连接到第一个设备。值得一提的是,孤立顶点是指不是任何边的端点的顶点。
图 21-2
定向与非定向
在本章中,您将通过实现以下内容来了解使用 GraphFrame API 的实际示例:
-
安装 JAR 库
-
加载新数据表
-
将数据加载到数据块笔记本的数据框中
-
使用 GraphFrame API 运行查询和算法
安装 JAR 库
现在您已经对图形有了基本的了解,让我们开始使用 Apache Spark GraphFrame API 进行图形分析的练习。
在本章的练习中,我选择利用 Databricks 笔记本来运行图表分析。然而,您可以通过在 Synapse Analytics(
https://docs.microsoft.com/en-us/azure/synapse-analytics/spark/apache-spark-job-definitions
)
中添加和配置 Apache Spark 作业定义,并将 GraphFrame API JAR 文件添加到 Spark 定义中,来轻松使用 Synapse Workspace 笔记本。
兼容 GraphFrame 版本的完整列表可以在这里 : https://spark-packages.org/package/graphframes/graphframes
找到。在本练习中,使用 0.8.1-spark2.4-s_2.12 版本的 JAR 文件,并将其安装在标准数据块集群的库中,如图 21-3 所示。
图 21-3
安装 JAR 库的步骤
一旦安装完成,请注意图 21-4 中的 JAR 已安装在集群上,它将用于运行后续部分中的笔记本代码。
图 21-4
带库 JAR 的集群
加载新数据表
因为 GraphFrame API JAR 和集群已经准备好了,所以通过 DBFS 上传一些数据。在本练习中,使用了 CTA 站数据和行程数据。网上有很多免费的数据集可以利用。Kaggle 是一个允许用户查找和发布数据集的网站,这里有 CTA 站数据可用: www.kaggle.com/chicago/chicago-transit-authority-cta-data
.
首先使用图 21-5 所示的 UI 创建 station_data 表。您也可以在我的 GitHub 存储库 GraphAnalyticsSampleFiles 中找到这些示例文件,可以从以下 URL 获得: https://github.com/ronlesteve/GraphAnalyticsSampleFiles
.
图 21-5
创建站数据表
验证模式,确保选中“第一行是标题”,然后点击“创建表格”,如图 21-6 所示。
图 21-6
查看表格属性
图 21-7 显示了如何对 trip_data 执行相同的过程,并使用创建新表 UI 创建表。
图 21-7
创建行程数据表
一旦表格被创建,它们都将出现在表格部分,如图 21-8 所示。
图 21-8
验证是否创建了表
将数据加载到数据块笔记本中
现在您已经创建了数据表,运行如图 21-9 所示的 Python 代码将数据加载到两个数据框中。
图 21-9
将数据加载到数据框中
以下是您将需要在 Databricks 笔记本中运行的 Python 代码,如图 21-9 所示:
stationData = spark.sql("select * from station_data")
tripData = spark.sql("select * from trip_data")
用顶点和边构建一个图
既然数据已加载到数据框中,那么是时候定义边和折点了。由于您将创建一个有向图,图 21-10 中显示的代码定义了行程的开始和结束位置。
图 21-10
为顶点和边创建数据框
以下是您将需要在 Databricks 笔记本中运行的 Python 代码,如图 21-10 所示:
stationVertices = stationData.withColumnRenamed("station_name", "station_id").distinct()
tripEdges = tripData\
.withColumnRenamed("Start Location", "src")\
.withColumnRenamed("End Location", "dst")
接下来,您需要构建一个 GraphFrame 对象,它将使用前面定义的边和顶点数据框来表示您的图形。此外,您应该缓存数据以便以后更快地访问。图 21-11 显示了你需要运行的 Python 代码块。
图 21-11
构建图表框架
以下是您将需要在 Databricks 笔记本中运行的 Python 代码,如图 21-11 所示:
from graphframes import GraphFrame
stationGraph = GraphFrame(stationVertices, tripEdges)
stationGraph.cache()
查询图表
既然您已经上传了将要处理的数据,并且定义了您的边和顶点,那么是时候运行图 21-12 中所示的基本计数查询来了解您将要处理的数据量了。这些查询将让您了解车站总数、图表中的行程以及原始数据中的行程。从图 21-12 中的执行结果消息中注意到,大约有 354K 次行程跨越 71 个车站。
图 21-12
查询图表
以下是您将需要在 Databricks 笔记本中运行的 Python 代码,如图 21-12 所示:
print ("Total Number of Stations:" + str(stationGraph.vertices.count()))
print ("Total Number of Trips in Graph:" + str(stationGraph.edges.count()))
print ("Total Number of Trips in Original Data:" + str(tripData.count()))
为了确定哪个出发地和目的地的旅行次数最多,运行图 21-13 中所示的查询。
图 21-13
运行图表查询
以下是您将需要在 Databricks 笔记本中运行的 Python 代码,如图 21-13 所示:
from pyspark.sql.functions import desc
stationGraph.edges.groupBy("src", "dst").count().orderBy(desc("count")).show(10)
类似地,也运行图 21-14 中所示的以下查询来查找进出特定车站的车次。
图 21-14
运行更多图表查询
以下是您将需要在 Databricks 笔记本中运行的 Python 代码,如图 21-14 所示:
stationGraph.edges\
.where("src = 'Cicero-Forest Park' OR dst = 'Cicero-Forest Park'")\
.groupBy("src", "dst").count()\
.orderBy(desc("count"))\
.show(10)
寻找有图案的图案
在对图形数据运行了一些基本查询之后,下一步让我们更深入一点,通过寻找具有所谓主题的模式,这是一种在图形中表达结构模式的方式,并查询数据中的模式而不是实际数据。例如,如果您对查找数据集中在三个站点之间形成三角形的所有行程感兴趣,您可以使用以下内容:"(a)-[ab]->(b);(b)-[BC]->(c);(c)-[ca]->(a)。”基本上(a)、(b)、(c)代表你的顶点,[ab]、[bc]、[ca]代表你的被排除在查询之外的边以下面的运算符为例:(a)-[ab]->(b),如图 21-15 。
图 21-15
带图案的样品图案
可以使用自定义模式运行 motif 查询,如图 21-16 所示的代码块。
图 21-16
模体的模式算法
以下是您将需要在 Databricks 笔记本中运行的 Python 代码,如图 21-16 所示:
motifs = stationGraph.find("(a)-[ab]->(b); (b)-[bc]->(c); (c)-[ca]->(a)")
motifs.show()
一旦将主题添加到数据帧中,就可以在以下查询中使用该主题,例如,通过利用时间戳找到从站(a)到(b)到(c)再回到(a)的最短时间:
from pyspark.sql.functions import expr
motifs.selectExpr("*",
"to_timestamp(ab.`Start Date`, 'MM/dd/yyyy HH:mm') as abStart",
"to_timestamp(bc.`Start Date`, 'MM/dd/yyyy HH:mm') as bcStart",
"to_timestamp(ca.`Start Date`, 'MM/dd/yyyy HH:mm') as caStart")\
.where("ca.`Station_Name` = bc.`Station_Name`").where("ab.`Station_Name` = bc.`Station_Name`")\
.where("a.id != b.id").where("b.id != c.id")\
.where("abStart < bcStart").where("bcStart < caStart")\
.orderBy(expr("cast(caStart as long) - cast(abStart as long)"))\
.selectExpr("a.id", "b.id", "c.id", "ab.`Start Date`", "ca.`End Date`")
.limit(1).show(1, False)
用 PageRank 发现重要性
GraphFrames API 还利用图论和算法来分析数据。 PageRank 就是这样一种图形算法,它通过计算一个页面链接的数量和质量来确定一个网站重要性的粗略估计,如图 21-17 所示。潜在的假设是,更重要的网站可能会从其他网站收到更多的链接。
图 21-17
PageRank 示例图像
PageRank 的概念可应用于您的数据,以了解接收大量自行车流量的火车站。在图 21-18 所示的例子中,重要的站点将被赋予较大的 PageRank 值。
图 21-18
PageRank 代码
以下是您将需要在 Databricks 笔记本中运行的 Python 代码,如图 21-18 所示:
from pyspark.sql.functions import desc
ranks = stationGraph.pageRank(resetProbability=0.15, maxIter=10)
ranks.vertices.orderBy(desc("pagerank")).select("station_id", "pagerank").show(10)
探索入度和出度度量
测量和计算进出车站的行程可能是一项必要的任务,您可以使用称为入度和出度的度量来完成这项任务。这可能更适用于社交网络的情况,在社交网络中,我们可以找到拥有更多关注者(内度)的人,而不是他们关注的人(度外)。图 21-19 中说明了这种入度和出度的概念。
图 21-19
入和出度图像
使用 GraphFrames,您可以运行图 21-20 中所示的查询来查找 in-degrees。
图 21-20
入学位代码
以下是您将需要在 Databricks 笔记本中运行的 Python 代码,如图 21-20 所示:
inDeg = stationGraph.inDegrees
inDeg.orderBy(desc("inDegree")).show(5, False)
类似地,运行图 21-21 所示的代码块,找出出度并注意结果。
图 21-21
外向度代码
以下是您将需要在 Databricks 笔记本中运行的 Python 代码,如图 21-21 所示:
outDeg = stationGraph.outDegrees
outDeg.orderBy(desc("outDegree")).show(5, False)
最后,运行图 21-22 所示的代码,找出入度和出度之间的比率。较高的比率值将指示许多行程结束的位置(但很少开始),而较低的值告诉我们行程经常开始的位置(但很少结束)。
图 21-22
入度和出度比率
以下是您将需要在 Databricks 笔记本中运行的 Python 代码,如图 21-22 所示:
degreeRatio = inDeg.join(outDeg, "id")\
.selectExpr("id", "double(inDegree)/double(outDegree) as degreeRatio")
degreeRatio.orderBy(desc("degreeRatio")).show(10, False)
degreeRatio.orderBy("degreeRatio").show(10, False)
进行广度优先搜索
广度优先搜索可用于连接两组节点,根据图中的边找到通往不同站点的最短路径。使用 maxPathLength ,您可以指定要连接的最大边数,并指定一个 edgeFilter 来过滤掉不符合特定要求的边。运行图 21-23 所示的代码,完成广度优先搜索。
图 21-23
广度优先搜索代码
以下是您将需要在 Databricks 笔记本中运行的 Python 代码,如图 21-23 所示:
stationGraph.bfs(fromExpr="station_id = 'Belmont-North Main'",
toExpr="station_id = 'Cicero-Forest Park'", maxPathLength=2).show(10)
查找连接的组件
连通分量定义了一个(无向)子图,该子图与自身有连接,但不与更大的图连接。
如图 21-24 所示的两个子图所示,如果一个图中的每对顶点之间都包含一条路径,则该图是强连通的,如果任意两对顶点之间不存在任何路径,则该图是弱连通的。
图 21-24
强连接组件与弱连接组件
图 21-25 所示的代码将生成连接的组件。注意结果。
图 21-25
查找连接组件时要运行的代码
以下是您将需要在 Databricks 笔记本中运行的 Python 代码,如图 21-25 所示:
spark.sparkContext.setCheckpointDir("/tmp/checkpoints")
minGraph = GraphFrame(stationVertices, tripEdges.sample(False, 0.1))
cc = minGraph.connectedComponents()
cc.where("component != 0").show()
此外,图 21-26 中所示的基本代码可用于寻找强连接组件。
图 21-26
寻找强连通分量的代码
以下是您将需要在 Databricks 笔记本中运行的 Python 代码,如图 21-26 所示:
scc = minGraph.stronglyConnectedComponents(maxIter=3)
scc.groupBy("component").count().show()
摘要
在这一章中,我演示了几个实际例子,说明如何使用 Databricks GraphFrame API 轻松地搜索图形和顶点中的模式,然后查询它们以获得对数据的洞察。在 Azure 中,图形数据库服务可以通过 Cosmos DB Gremlin API 获得。Cosmos DB 是一个多模型、全球分布的 NoSQL 数据库,它的 Gremlin API 支持由顶点和边组成的结构。SQL Server 等其他微软技术也增加了对图形数据库的支持,以处理包含复杂实体关系的数据。所有这些不同的图形技术都显示了对超大型图形数据集(如使用 Apache Spark 的社交媒体提要)进行分析的价值。
二十二、Synapse 分析工作区
微软 Azure 数据平台的众多新增功能已经围绕许多类似的产品及其在现代 Azure 数据平台中的用途产生了兴奋和困惑。Azure Synapse Analytics work spaces 就是这样一种产品,不要与 Azure Synapse Analytics DW 混淆,后者传统上是下一代 Azure 数据仓库,现已更名为 Synapse Analytics 专用 SQL 池(Synapse Analytics DW)。Azure Synapse Analytics work spaces 是统一的现代数据和分析平台的发展,它将各种 Azure 服务集中到一个集中的位置。
azure Synapse Analytics work spaces 是一种 web 原生体验,它为数据工程师统一了端到端分析解决方案,使他们能够通过利用 SQL 或 Spark 池的单一体验来获取、浏览、准备、编排和可视化他们的数据。此外,它还带来了调试、性能优化、数据治理以及与 CI/CD 集成的能力。在本章中,我将通过利用 Synapse Analytics workspaces 知识中心提供的一些实际示例、代码和用例,介绍如何开始使用 Synapse Analytics Workspaces。
创建 Synapse 分析工作区
首先创建一个新的 Azure Synapse 分析工作区,如图 22-1 所示。
图 22-1
Synapse Analytics 工作区创建
接下来,配置并完成“创建 Synapse 工作区”部分。请注意,您将需要在工作区创建过程中创建和使用 Azure Data Lake Storage Gen2,如图 22-2 所示。
图 22-2
查看并创建 Synapse 工作区
一旦创建了工作空间,它将在 Azure Portal 中的所选资源组中可用,并如图 22-3 所示。无服务器 SQL 将在提供工作空间后立即可用,并将包括按查询付费的计费模式。
图 22-3
门户中部署的 Synapse 工作区
既然已经创建了工作区,请注意添加新的专用 SQL 池和新的 Apache Spark 池的选项。SQL 专用池(以前称为 SQL DW)是指 Azure Synapse Analytics 中提供的企业数据仓库功能,代表使用 Synapse SQL 时配置的分析资源的集合。专用 SQL 池(以前称为 SQL DW)的大小由数据仓库单元(DWU)决定。在 Synapse Analytics 工作区中,您可以创建和配置一个无服务器的 Apache Spark 池来处理 Azure 中的数据。继续点击图 22-4 所示的“打开 Synapse Studio”。
图 22-4
从门户启动 Synapse Studio
Synapse Analytics Studio 工作区启动后,导航到知识中心并单击“立即使用样本”,如图 22-5 所示,立即浏览自动为您提供的脚本、笔记本、数据集和池。
图 22-5
使用知识中心的示例
使用 Spark 探索样本数据
知识中心有三个样本可供即时探索,如图 22-6 所示。第一个用 Spark 探索样本数据,包括样本脚本,甚至为您创建一个新的 Spark 池,或者您也可以自己创建。
图 22-6
使用 Spark 探索样本数据
选择第一个样本,然后单击“使用样本”将创建一个笔记本,其中包含许多包含来自 Azure ML OpenDatasets 包 (
https://docs.microsoft.com/en-us/python/api/azureml-opendatasets
)
的数据的脚本。具体来说,本笔记本使用纽约市黄色出租车数据集。点击“Run all”执行笔记本,并从图 22-7 中的已完成执行结果中注意到,该作业使用了两个 Spark 执行器和八个内核来接收数据。
图 22-7
纽约市出租车数据样本笔记本
以下是在图 22-7 所示的笔记本插图中执行的代码:
# Read NYC yellow cab data from Azure Open Datasets
from azureml.opendatasets import NycTlcYellow
from datetime import datetime
from dateutil import parser
end_date = parser.parse('2018-05-08 00:00:00')
start_date = parser.parse('2018-05-01 00:00:00')
nyc_tlc = NycTlcYellow(start_date=start_date, end_date=end_date)
nyc_tlc_df = nyc_tlc.to_spark_dataframe()
该过程的下一步演示了如何将数据复制到关联的 Azure Data Lake Store Gen2 帐户。笔记本中的脚本,如图 22-8 所示,将通过用复制的数据创建一个火花表、一个 CSV 和一个拼花文件来完成这个复制数据任务。你可以只使用数据框;但是,此步骤将演示如何集成 ADLS Gen2 并持久存储数据。
图 22-8
使用 Spark pool 复制数据示例
以下是在图 22-8 所示的笔记本插图中执行的代码:
nyc_tlc_df.createOrReplaceTempView('nyc_tlc_df')
nyc_tlc_df.write.csv('nyc_tlc_df_csv', mode='overwrite')
nyc_tlc_df.write.parquet('nyc_tlc_df_parquet', mode='overwrite')
作业运行完成后,导航到 Azure Data Lake Storage Gen2 帐户,验证 CSV 和 parquet 文件是否都已创建。请注意图 22-9 中显示的两个包含纽约出租车数据集的新文件夹。
图 22-9
在 ADLS Gen2 中创建的文件夹和文件
打开拼花文件夹,注意如图 22-10 所示的压缩拼花文件的数量。
图 22-10
在 ADLS 创建的拼花文件 Gen2
接下来,导航回 Azure Synapse Studio 工作区并运行图 22-11 中所示的 select 语句,以确保数据也被摄取到 Spark 表中。
图 22-11
选择笔记本中的所有数据
以下是在图 22-11 所示的笔记本插图中执行的代码:
%%sql
SELECT * FROM myc_tlc_df
从这里开始,您可以通过开始聚合数据来获得更高级的数据探索,如图 22-12 所示。
图 22-12
汇总笔记本中的数据
以下是在图 22-12 所示的笔记本插图中执行的代码:
from pyspark.sql import functions as F
df_nyc = nyc_tlc_df.groupBy("passengerCount").agg(F.avg('tripDistance').alias('AvgTripDistance'), F.sum('tripDistance').alias('SumTripDistance'))
display(df_nyc)
此时,您可以使用 matplotlib 和 seaborn 等流行的库来渲染折线图,从而使您的分析更加高级,如图 22-13 所示。
图 22-13
使用 Spark 和笔记本电脑定制数据可视化
以下是在图 22-13 所示的笔记本插图中执行的代码:
import matplotlib.pyplot
import seaborn
seaborn.set(style = "whitegrid")
pdf_nyc = df_nyc.toPandas()
seaborn.lineplot(x="passengerCount", y="SumTripDistance" , data = pdf_nyc)
seaborn.lineplot(x="passengerCount", y="AvgTripDistance" , data = pdf_nyc)
matplotlib.pyplot.show()
最后,通过结束连接的会话来清理资源,以确保 Spark 实例被关闭。注意,当达到 Apache Spark 池中指定的空闲时间时,这个池就会关闭。您也可以从笔记本底部的状态栏中选择结束会话。
用 SQL 查询数据
接下来,让我们继续第二个示例,它包括一个示例脚本和一个 SQL 随需应变池来使用 SQL 查询数据,如图 22-14 所示。无服务器 SQL 池是对数据湖中数据的查询服务,它使用按查询付费的模式。它使您能够通过 T-SQL 语法访问您的数据,并针对查询和分析 ADLS Gen2 中的大数据进行了优化。因为它是无服务器的,所以不需要维护基础架构或集群。数据工程师、数据科学家、数据分析师和 BI 专业人员可以使用它在湖中的原始数据或不同数据上执行基本的数据探索、转换和数据抽象。
图 22-14
Synapse Studio 中使用 SQL 查询数据的示例
与第一个示例类似,创建了一个新的 SQL 脚本,演示如何通过使用标准 SQL 命令和 OPENROWSET 函数来查询 Azure Data Lake Storage Gen2 帐户,如图 22-15 所示。OPENROWSET 是一个 T-SQL 函数,允许从许多来源读取数据,包括使用 SQL Server 的大容量导入功能。代码中的格式参数允许拼花地板和 CSV 类型。
图 22-15
样本查询数据湖
以下是在图 22-15 所示的笔记本插图中执行的代码:
SELECT TOP 100 * FROM
OPENROWSET(
BULK 'https://azureopendatastorage.blob.core.windows.net/nyctlc/yellow/puYear=2019/puMonth=*/*.parquet',
FORMAT='PARQUET'
) AS [nyc];
下一个查询,如图 22-16 所示,通过添加额外的过滤器和子句增加了更多的复杂性,并且在展示 Synapse Studio 工作区的功能方面做得很好,可以从熟悉的 SQL 体验中直接查询 Azure Data Lake Storage Gen2 帐户。使用 SQL on demand 分析 Azure 开放数据集,并在 Azure Synapse Studio 中可视化结果。您可以在以下 URL 中找到更多代码示例: https://docs.microsoft.com/en-us/azure/synapse-analytics/sql/tutorial-data-analyst
。
图 22-16
更复杂的数据湖查询
以下是在图 22-16 所示的笔记本插图中执行的代码:
SELECT
YEAR(tpepPickupDateTime) AS current_year,
COUNT(*) AS rides_per_year
FROM
OPENROWSET(
BULK 'https://azureopendatastorage.blob.core.windows.net/nyctlc/yellow/puYear=*/puMonth=*/*.parquet',
FORMAT='PARQUET'
) AS [nyc]
WHERE nyc.filepath(1) >= '2014' AND nyc.filepath(1) <= '2019'
GROUP BY YEAR(tpepPickupDateTime)
ORDER BY 1 ASC;
用 SQL 创建外部表
本章的最后一个练习包括使用 SQL 创建和查询外部表,如图 22-17 所示。与前面的示例类似,将在工作区中为您创建一个示例脚本和表。
图 22-17
在 Synapse Studio 中创建外部表的示例
图 22-18 所示的 SQL 代码块(包含在示例中)将演示如何创建外部表。
图 22-18
创建外部表的示例脚本
以下是您需要在图 22-18 所示的笔记本插图中运行的代码:
/* Note: this script is filtered on a specific month. You can modify the location to read the entire dataset. */
IF NOT EXISTS (SELECT * FROM sys.external_file_formats WHERE name = 'SynapseParquetFormat')
CREATE EXTERNAL FILE FORMAT [SynapseParquetFormat]
WITH ( FORMAT_TYPE = PARQUET)
GO
IF NOT EXISTS (SELECT * FROM sys.external_data_sources WHERE name = 'nyctlc_azureopendatastorage_blob_core_windows_net')
CREATE EXTERNAL DATA SOURCE [nyctlc_azureopendatastorage_blob_core_windows_net]
WITH (
LOCATION = 'wasbs://nyctlc@azureopendatastorage.blob.core.windows.net',
TYPE = HADOOP
)
GO
CREATE EXTERNAL TABLE nyc_tlc_yellow_trip_ext (
[vendorID] varchar(8000),
[tpepPickupDateTime] datetime2(7),
[tpepDropoffDateTime] datetime2(7),
[passengerCount] int,
[tripDistance] float,
[puLocationId] varchar(8000),
[doLocationId] varchar(8000),
[startLon] float,
[startLat] float,
[endLon] float,
[endLat] float,
[rateCodeId] int,
[storeAndFwdFlag] varchar(8000),
[paymentType] varchar(8000),
[fareAmount] float,
[extra] float,
[mtaTax] float,
[improvementSurcharge] varchar(8000),
[tipAmount] float,
[tollsAmount] float,
[totalAmount] float
)
WITH (
LOCATION = 'yellow/puYear=2014/puMonth=3/',
-- LOCATION = 'yellow'
DATA_SOURCE = [nyctlc_azureopendatastorage_blob_core_windows_net],
FILE_FORMAT = [SynapseParquetFormat],
REJECT_TYPE = VALUE,
REJECT_VALUE = 0
)
GO
SELECT TOP 100 * FROM nyc_tlc_yellow_trip_ext
GO
创建表后,运行一个简单的 SQL select 语句,如图 22-19 所示,查询新创建的外部表。请注意,还有一个“查询计划”按钮可用。
图 22-19
查询外部表的示例
以下是您需要在图 22-19 所示的笔记本插图中执行的代码:
SELECT TOP 100 * FROM nyc_tlc_yellow_trip_ext
GO
可以下载查询计划并在 SQL Server Management Studio (SSMS)中打开它,如图 22-20 所示,与使用 SSMS 在传统 SQL Server 体验中分析查询计划相比,这是一项非常有用的功能。
图 22-20
查询计划功能
请注意,在图 22-21 中,作为这些练习的一部分,已经创建了一个专用的 SQL 池和 Apache Spark 池。记得删除任何未使用的资源和 Spark/ SQL 池,以防止任何额外的成本。
图 22-21
示例演示中在 Azure 门户中创建的 SQL 和 Spark 池的图像
摘要
在本章中,我演示了如何创建新的 Azure Synapse Analytics Studio 工作区,然后向您展示了如何从知识中心创建三个示例来实现以下目标:
-
使用 Spark 探索数据。
-
用 SQL 查询数据。
-
用 SQL 创建一个外部表。
Azure Synapse workspace 还有许多我们在本章中没有探讨的其他优势,例如连接到 Power BI 帐户以可视化和构建交互式报告的能力;创建、调度和监控 ETL 作业,就像您在 Azure 数据工厂体验中所做的那样;并通过与微软的新数据治理产品 Azure without 集成来搜索您的数据资产。有了图 22-22 所示的所有可用资源和易于使用的导航 UI,开始 Azure Synapse Analytics 之旅再简单不过了。Azure Synapse 分析工作区确实有潜力成为各种业务和技术专业人员的统一现代数据和分析平台。
图 22-22
Azure Synapse 分析主页
二十三、数据块中的机器学习
寻求利用机器学习(ML)和人工智能能力的组织和开发人员花费大量时间构建 ML 模型,并寻求一种方法来简化他们的机器学习开发生命周期,以跟踪实验,将代码打包成可重复运行的代码,以及构建、共享和部署 ML 模型。
MLflow 是一个管理端到端机器学习生命周期的开源平台,如图 23-1 所示。它处理四个主要功能:
-
跟踪实验以比较和记录参数和结果
-
打包 ML 代码以与其他数据科学家共享或转移到生产中。
-
使用各种可用的库管理和部署 ML 模型
-
注册模型以便于模型管理,并提供模型作为 REST 端点
在本章中,我将介绍如何使用 Azure Databricks 开始使用 MLflow。Databricks 为跟踪和保护 ML 模型培训运行以及运行 ML 项目提供了集成的 MLflow 体验。除了提供 MLflow 的全面管理版本,Databricks 还集成了企业安全功能、高可用性、实验和运行管理以及笔记本版本捕获。
图 23-1
描述 MLflow 功能的图像
创建 MLflow 实验
让我们从在 Azure Databricks 中创建一个 MLflow 实验开始。首先导航至主页菜单并选择“新 MLflow 实验”,如图 23-2 所示。
图 23-2
从主页菜单创建新的 MLflow 实验
选择“新建 MLflow 实验”打开一个新的“创建 MLflow 实验”界面。填充实验名称,然后创建实验,如图 23-3 所示。
图 23-3
为 MLflow 创建实验
一旦实验被创建,它将有一个与之相关联的实验 ID,当您配置包含 ML 模型代码的笔记本时,您将需要这个 ID。注意图 23-4 所示的实验用户界面包含比较多个模型、按模型状态过滤、按标准搜索和下载 CSV 细节的选项。
图 23-4
实验用户界面的示例图像
安装 MLflow 库
创建 MLflow 实验后,创建一个新的集群,并在其上安装 MLflow PyPI 库。如果您正在运行用于机器学习的 Databricks 运行时,则 MLflow 已经安装,不需要任何设置。如果您正在运行 Databricks 运行时,请按照图 23-5 中所示的步骤安装 MLflow 库。
图 23-5
安装 MLflow PyPI 库
一旦库成功安装,可以在集群的库上看到 installed 状态,如图 23-6 所示。
图 23-6
已安装的 MLflow 库
创建笔记本
在安装了一个实验、一个集群和 MLflow 库之后,您需要创建一个新的笔记本来构建 ML 模型,然后将它与 MLflow 实验相关联。请注意,如果开始运行时没有活动的实验,Databricks 会自动创建一个笔记本实验。
使用以下代码开始运行。因为您有一个实验 ID,所以使用
mlflow.start_run().
mlflow.start_run(experiment_id=1027351307587712)
或者,您可以如下定义实验名称,这将简单地使用实验名称而不是 ID:
experiment_name = "/Demo/MLFlowDemo/"
mlflow.set_experiment(experiment_name)
选择性测井
从日志的角度来看,可以选择自动记录特定于模型的指标、参数和工件。或者,可以根据需要通过向笔记本代码添加以下命令来定义这些指标、参数或模型:
数字度量:mlflow.log_metric("accuracy", 0.9)
训练参数:mlflow.log_param("learning_rate", 0.001)
型号:mlflow.sklearn.log_model(model, "myModel")
其他工件(文件):mlflow.log_artifact("/tmp/my-file", "myArtifactPath")
下面的代码从 scikit-learn 导入一个数据集,并创建训练和测试数据集。这段代码旨在演示一个 ML 模型示例。将此添加到 Databricks 笔记本中的代码块:
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_diabetes
db = load_diabetes()
X = db.data
y = db.target
X_train, X_test, y_train, y_test = train_test_split(X, y)
下一个代码块将导入 MLflow 和 sklearn,开始实验,并记录执行运行的详细信息。只需将此代码添加到您的 Databricks 笔记本中并运行它:
import mlflow
import mlflow.sklearn
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error
# In this run, neither the experiment_id nor the experiment_name parameter is provided. MLflow automatically creates a notebook experiment and logs runs to it.
# Access these runs using the Experiment sidebar. Click Experiment at the upper right of this screen.
with mlflow.start_run(experiment_id=1027351307587712):
n_estimators = 100
max_depth = 6
max_features = 3
# Create and train model
rf = RandomForestRegressor(n_estimators = n_estimators, max_depth = max_depth, max_features = max_features)
rf.fit(X_train, y_train)
# Make predictions
predictions = rf.predict(X_test)
# Log parameters
mlflow.log_param("num_trees", n_estimators)
mlflow.log_param("maxdepth", max_depth)
mlflow.log_param("max_feat", max_features)
# Log model
mlflow.sklearn.log_model(rf, "random-forest-model")
# Create metrics
mse = mean_squared_error(y_test, predictions)
# Log metrics
mlflow.log_metric("mse", mse)
图 23-7 显示了需要记录的已定义参数、指标和模型。
图 23-7
代码中定义的参数
点击图 23-8 中高亮显示的图标,查看实验运行详情。另外,点击底部的实验界面打开界面。如果没有创建实验,将为您创建一个新的随机实验,这将特别有用。
图 23-8
单击打开用户界面
由于之前已经创建了一个 MLflow 实验,点击 MLFlowDemo 打开它,如图 23-9 所示。
图 23-9
打开 MLflow 实验
请注意,该实验运行了两次,并注意与之相关的参数和指标。此外,现在可以选择比较两次运行,如图 23-10 所示。
图 23-10
比较多次运行
点击比较,注意两次运行之间的所有相关细节,如图 23-11 所示。
图 23-11
比较两次模型运行的参数
此外,您可以通过图 23-12 所示的散点图、等高线图或平行坐标图来可视化比较。要查看绘图,只需在各种绘图选项卡之间切换。这个特殊的图显示了平行坐标。
图 23-12
样本地块 1
自动记录
在测试了定义的日志选项之后,还要测试自动日志。您可以使用图 23-13 中所示的代码的以下变体来实现,它基本上用对mlflow.sklearn.autolog()
的调用来替换所有已定义的度量、参数等等。
图 23-13
自动登录代码示例
以下是您需要在 Databricks 笔记本中运行的代码,如图 23-13 所示:
import mlflow
import mlflow.sklearn
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error
mlflow.sklearn.autolog()
# In this run, neither the experiment_id nor the experiment_name parameter is provided. MLflow automatically creates a notebook experiment and logs runs to it.
# Access these runs using the Experiment sidebar. Click Experiment at the upper right of this screen.
with mlflow.start_run():
n_estimators = 100
max_depth = 6
max_features = 3
# Create and train model
rf = RandomForestRegressor(n_estimators = n_estimators, max_depth = max_depth, max_features = max_features)
rf.fit(X_train, y_train)
# Make predictions
predictions = rf.predict(X_test)
在运行这个新模型两次并导航回 MLflow 实验后,请注意实验 UI 中记录的新运行,这一次在捕获的指标中有一些差异,正如预期的那样,如图 23-14 所示。
图 23-14
实验 UI 2
点击其中一个运行,查看各种细节,包括图,如图 23-15 所示。
图 23-15
样地 2
注册一个模型
在创建、记录和比较模型之后,您可以通过点击想要记录的模型并向下滚动到运行细节中的工件来注册模型,如图 23-16 所示。
图 23-16
从实验界面选择模型
选择型号,点击【注册型号】,如图 23-17 所示。
图 23-17
单击从工件注册模型
在图 23-18 所示的注册模型界面中,新建一个模型,命名并注册模型。
图 23-18
注册模型的步骤
一旦注册,Details 选项卡将包含与版本、注册时间戳、模型创建者和阶段相关的所有细节,如图 23-19 所示。
图 23-19
显示“详细信息”选项卡的图像
图 23-20 显示了各种版本以及每个阶段的其他细节。
图 23-20
显示版本详细信息的图像
图 23-21 显示了如何将阶段从暂存过渡到生产再到存档。
图 23-21
从一个阶段到另一个阶段的步骤
启用模型服务时,Databricks 会自动为模型创建一个唯一的单节点集群,并在该集群上部署模型的所有非归档版本。点击图 23-22 所示的启用上菜开始。
图 23-22
启用上菜的步骤
此时,您会看到服务和详细信息标签,如图 23-23 所示。MLflow 模型服务允许托管注册的 ML 模型作为 REST 端点,这些端点根据模型版本的可用性及其阶段自动更新。
图 23-23
该图显示了新的“服务”选项卡属性
样本服务页面可能如图 23-24 所示。
图 23-24
上菜标签的示例图像
最后,当一个模型被注册后,您可以通过导航到 Databricks UI 中的 Models 选项卡来找到它,如图 23-25 所示。
图 23-25
“模型”选项卡图标的图像
摘要
在本章中,我演示了如何创建 MLflow 实验、安装 MLflow 库以及创建 MLflow 笔记本。我还向您展示了选择性和自动日志记录的实际例子,最后向您展示了如何注册一个模型。随着 MLflow 通过 Databricks 体验的集成,您现在有能力管理 ML 生命周期,包括实验、再现性、部署和中央模型注册。
二十四、数据治理的权限
许多组织需要建立数据治理流程、标准和方法,并且已经能够使用内部 SQL Server 工具(如 Master Data Services)来完成这些工作。然而,在 Azure 空间中,这种数据治理产品还存在很大的缺口。此前,微软试图通过在 Azure 托管实例上托管 MDS 数据库或通过 Azure 数据目录将数据治理引入 Azure,这还不是一个真正成熟的数据治理产品。azure without 是一个基于云的数据治理产品,用于集中管理您的数据资产中的数据治理,涵盖云和内部环境。
Azure 权限易于使用的用户界面和目录使得管理数据的用户可以很容易地发现和理解数据源。azure without 提供了一个基于云的服务,用户可以在其中注册数据源,同时维护索引元数据的副本以及对源位置的引用。此外,可以通过标签、描述等进一步丰富这些元数据的范围。Azure 权限旨在解决数据消费者和生产者面临的一些挑战。在这一章中,我将向你展示如何开始使用 Azure 权限,然后演示如何探索权限工作室中的一些特性和功能。
创建 azure 预览帐户
Azure 权限提供了自动化和管理元数据、加速大规模分类、支持数据消费者发现数据资产、分配所有权、管理敏感数据等功能。在本节中,您将学习如何创建 Azure 权限帐户。Azure 权限可以通过 Azure Portal 访问,如图 24-1 所示。继续操作并单击 Create 开始创建新的权限帐户。
图 24-1
创建新的预览帐户
与所有 Azure 资源一样,view 也需要项目和实例细节,如图 24-2 所示。
图 24-2
新预览帐户详细信息
还可以选择其他配置选项,如图 24-3 所示:
图 24-3
新预览帐户配置详细信息
-
平台大小:下面的链接
(
https://azure.microsoft.com/en-us/pricing/details/azure-purview/
)
捕获容量单位,这是一组用于保持权限数据图最新和运行的资源。至少需要选择四个单元。 -
目录和数据要素:允许您为权限帐户指定要素集级别。有一些可用的选项,包括业务术语表和谱系可视化、源注册、数据发现、自动扫描和分类,以及目录和敏感数据洞察。
最初,当试图创建 Azure 权限实例时,您可能会遇到错误,如图 24-4 所示,因为权限需要作为订阅级别的提供者添加。此外,用户必须对 Azure 权限拥有适当的 Azure Active Directory 权限。权限数据读取器可以访问权限工作室,并且可以读取除扫描绑定之外的所有内容。权限数据管理员拥有与数据读者相同的访问权限,并且能够编辑分类和术语表术语并将其应用于资产。最后,权限数据源管理员无权访问权限工作室,也无权读取或写入权限中除扫描之外的内容。
图 24-4
创建新的预览帐户时出错
图 24-5 展示了在订阅级别添加资源提供者权限所需的步骤。首先,导航到将部署 Azure 权限的订阅。接下来,点击资源提供者,最后搜索并注册Microsoft.Purview
为资源提供者。
图 24-5
在资源提供者中注册
添加Microsoft.Purview
为资源提供者,从图 24-6 中可以看到,权限已经成功通过验证,可以创建了。回到 Azure Portal 中的权限帐户创建 UI,创建您的权限帐户。
图 24-6
创建权限帐户的验证通过
探索 azure 预览
现在,您已经成功创建了具有相关访问权限的权限帐户,您可以开始探索权限的各种功能,包括创建和注册数据源、管理凭证和访问权限、创建扫描、探索术语表以及浏览资产。首先点击“打开权限工作室”,如图 24-7 所示,启动 Azure 权限。
图 24-7
单击以从 azure 门户打开预览
创建和注册数据源
在 Azure 范围内工作时,创建和注册数据源是关键的第一步。一旦你进入了权限工作室,点击 sources 图标,如图 24-8 所示,添加数据源并注册为权限内的资产。
图 24-8
预览工作室主页
要添加新源,首先通过完成以下步骤创建一个集合,如图 24-9 所示:
图 24-9
创建新预览集合的步骤
-
单击来源。
-
单击新建收藏。
-
给新收藏命名。
-
单击完成。
接下来,您需要从图 24-10 所示的已注册信号源列表中搜索并选择一个信号源进行注册。随着范围的不断成熟,将会添加更多的源,希望它也能够容纳 Azure 之外的多个源。
图 24-10
注册信号源的步骤
选择 Azure Data Lake Storage Gen2 作为您的源。另外,输入源的详细信息,如图 24-11 所示。
图 24-11
注册 ADLS Gen2
注意图 24-12 中,源被添加到它们注册的集合中。一个收藏可以有多个来源,画布中也可以有多个收藏。
图 24-12
源的预览集合的显示
管理凭证和访问
在 Azure 范围内,需要凭据来快速重用保存的身份验证信息,并将其应用于数据源扫描。权限强制要求使用密钥库存储密码和秘密,作为存储凭证(
https://docs.microsoft.com/en-us/azure/purview/manage-credentials
)
的最低要求。按照图 24-13 所示的步骤添加新的密钥库凭证。(1)首先单击管理中心图标,(2)单击凭据,(3)单击新建,(4)命名您的密钥库连接,(5)指定您的密钥库名称,以及(6)单击创建。
图 24-13
注册预览凭据和密钥库的步骤
权限将显示如图 24-14 所示的消息,以确认授予权限访问密钥库。单击确认继续。
图 24-14
授予权限访问权的步骤
图 24-15 说明了通过 Azure 门户从 Azure Key Vault 向权限提供必要的 GET 访问权限所采取的步骤。只需导航到正在使用的密钥库帐户,选择访问策略,然后选择添加访问策略。
图 24-15
权限的关键保管库访问策略
图 24-16 显示了添加访问策略所需的步骤。选择获取机密权限,从选择主体部分选择您的权限帐户,然后单击添加。
图 24-16
添加对密钥保管库预览的访问权限
一旦在权限内创建并验证了连接,它们将出现在“管理密钥库连接”部分,如图 24-17 所示。
图 24-17
密钥库现在在预览中可见
然后,在添加新的数据源和连接时,可以在凭据身份验证用户界面中配置密钥库连接。例如,图 24-18 显示了如何使用密钥库提取相应 ADLS Gen2 账户的账户密钥。
图 24-18
为 ADLS Gen2 添加凭据
创建扫描
在 Azure 权限目录中,有创建扫描规则集的功能,使用户能够快速扫描组织内的数据源。扫描规则集是一个容器,用于将一组扫描规则组合在一起,以便轻松地将它们与扫描相关联。要为您的源创建新的扫描,点击图 24-19 所示的扫描图标,然后填充所需的凭证信息。
图 24-19
扫描预览源的步骤
此外,图 24-20 显示了如何定制和更改扫描范围,以选择或取消选择源中的对象。
图 24-20
根据需要选择表格
扫描规则集可以利用默认规则集来包含所有支持的系统分类规则,如图 24-21 所示,或者您可以自定义此规则集的范围。
图 24-21
选择扫描规则集
图 24-22 显示了可用分类系统规则的示例列表。
图 24-22
选择多个规则
或者,图 24-23 显示了如何创建新的自定义扫描规则集,以指定从可用规则列表或可定义的自定义规则中应用的规则。
图 24-23
选择分类规则
创建扫描规则集的最后一步是设置手动(一次性)或重复(由计划定义)触发器。请注意,还有一个设置重复结束日期的选项。图 24-24 展示了这个扫描触发器的样子。请注意您在选择扫描触发器的日期范围、时间范围和重复时所具有的灵活性。
图 24-24
触发可以是手动的,也可以根据计划重复进行
配置好扫描规则集后,检查它,保存并运行它,如图 24-25 所示。
图 24-25
检查扫描并保存/运行
类似于 Azure SQL 数据库源,如图 24-26 所示,可以为这个新的源创建一个新的范围,也可以为 ADLS Gen2 帐户添加。
图 24-26
扫描范围为 ADLS 第二代
您还需要为这个新的 ADLS Gen2 源创建一个新的扫描规则集,如图 24-27 所示。选择系统默认扫描规则集,然后单击继续。
图 24-27
为 ADLS 第二代制定规则
扫描完成后,“概述”部分将提供与执行的扫描次数以及扫描的资产相关的更多详细信息。图 24-28 显示了成功完成的 SQL 数据库扫描的概况。
图 24-28
成功完成的 SQL 扫描概述
此外,图 24-29 显示了对您的 ADLS Gen2 帐户成功完成扫描的概述。
图 24-29
成功完成的 ADLS Gen2 扫描概述
探索词汇表
权限的业务术语表 (
https://docs.microsoft.com/en-us/azure/purview/concept-business-glossary
)
允许用户轻松定义和管理术语表术语。图 24-30 说明了创建术语表术语所需的步骤。(1)通过单击图标导航到术语表,(2)创建新术语,(3)为新术语模板命名,(4)添加新属性,以及(5)单击创建。
图 24-30
添加新的词汇表术语
一旦创建了术语表术语,就可以添加额外的数据、联系人和相关项目,并链接到术语以丰富它们。此外,这些术语表术语可以链接到资产,以进一步丰富资产的元数据,如图 24-31 所示。
图 24-31
词汇表的显示
从图 24-32 的图示中,注意您可以使用 UI 添加新的术语表术语。
图 24-32
词汇表的附加显示
浏览资产
最后,一旦在权限内注册了资产,就可以通过在图 24-33 所示的搜索框中进行搜索,从主页访问这些资产。单击搜索框,键入您有兴趣搜索的资产名称。
图 24-33
在预览主屏幕页面中搜索资产的步骤
或者,可以从图 24-34 所示主页上的“浏览资产”图标访问资产。
图 24-34
在预览中浏览资源的步骤
登记的资产列表也将在粒度级别可用,如图 24-35 所示。
图 24-35
ADLS 第二代资产在范围内
在这些部分中,可以探索、编辑和丰富细节以及血统。图 24-36 显示了 ADLS Gen2 概览选项卡的详细信息。
图 24-36
ADLS Gen2 中的数据概览
图 24-37 显示了与浏览 SQL 数据库表和模式相关的细节。
图 24-37
在预览中浏览 sql 表的步骤
请注意,分类部分会自动捕获符合已定义的敏感性和隐私规则集的字段,如图 24-38 所示。
图 24-38
可以在预览中浏览的关于 sql 表的详细信息
有趣的是,在图 24-39 所示的模式部分中,有一个选项可以改变表的列名和数据类型,因此应该谨慎使用,并从访问的角度进行良好的管理。
此外,示例 customer 表中的每个字段都可以链接到一个术语表术语,在列级别捕获描述,并根据需要更改列级别的分类,这有助于进一步丰富元数据,并真正提供 Azure 中详细且无与伦比的数据治理体验,这种体验在这个领域已经缺失了很长时间。
图 24-39
从预览编辑 sql 表的步骤
图 24-40 描述了范围内相关资产的更多细节。请注意,分层视图有助于直观地描述和理解资产的相关项目。
图 24-40
权限内的相关资产
通过导航至图 24-41 所示的沿袭选项卡,您还可以查看权限内注册资产的沿袭。当您有兴趣从 ETL 的角度了解端到端的数据流过程,以进一步理解数据如何从源流向接收器时,这一点尤其有价值。
图 24-41
预览中的沿袭
以编程方式使用预览
现在,您已经很好地理解了如何创建一个权限帐户,以及如何在权限工作室中注册资产、创建扫描规则集和预定触发器、浏览术语表术语以及通过权限工作室 UI 查看沿袭。Azure 权限还提供了以编程方式使用您的权限帐户的能力,我们将在本节简要探讨这一点。
Azure 权限支持通过 REST APIs 为权限不直接支持的系统进行集成。一个这样的 API 叫做 Apache Atlas REST API。Atlas 公开了各种 REST 端点来处理类型、实体、血统和数据发现(
https://atlas.apache.org/api/v2/index.html
)
。要使用 Atlas API,您首先需要在 Azure 门户的订阅中的 Azure Active Directory 帐户中创建一个服务主体应用。您还需要在您的权限帐户的访问控制(IAM)部分授予这个新创建的服务主体应用“权限数据管理员”角色。一旦完成,您将需要tenant_id
、client_id
和client_secret
来开始以编程方式使用 Azure 权限。
此时,您可以连接到一个新的 Databricks 笔记本,并使用在线提供的许多示例,或者构建自己的示例来开始使用 Atlas API。这里有一个 GitHub 存储库示例,其中包含许多示例,您可以使用 Atlas API (
https://github.com/wjohnson/pyapacheatlas/tree/master/samples/CRUD
)
对您的权限帐户执行创建、读取、更新和删除操作。通过利用 Azure 函数集成 Databricks 和你的权限帐户,你还可以变得更有创造力。
下面是一个示例代码块,您可以将它添加到您的 Databricks 笔记本中,以便从 GUID 或限定名中读取现有的实体,您可以从您的权限工作室帐户中手动获取 GUID 或限定名。该示例代码旨在说明利用 Apache Atlas API 和相应的pyapacheatlas
类以编程方式处理权限的能力:
import json
import os
# PyApacheAtlas packages
# Connect to Atlas via a Service Principal
from pyapacheatlas.auth import ServicePrincipalAuthentication
from pyapacheatlas.core import PurviewClient, AtlasEntity, AtlasProcess
if __name__ == "__main__":
"""
This sample provides an example of reading an existing entity
through the rest api / pyapacheatlas classes.
You need either the Guid of the entity or the qualified name and type name.
The schema of the response follows the /v2/entity/bulk GET operation
even if you are requesting only one entity by Guid.
https://atlas.apache.org/api/v2/json_AtlasEntitiesWithExtInfo.html
The response of get_entity will be a dict that has an "entities" key
that contains a list of the entities you requested.
"""
# Authenticate against your Atlas server
oauth = ServicePrincipalAuthentication(
tenant_id=os.environ.get("TENANT_ID", "Enter-tenant-id"),
client_id=os.environ.get("CLIENT_ID", "Enter-client-id"),
client_secret=os.environ.get("CLIENT_SECRET", "Enter-Client-secret")
)
client = PurviewClient(
account_name = os.environ.get("PURVIEW_NAME", "Enter-Purview-name"),
authentication=oauth
)
# When you know the GUID that you want to get
response = client.get_entity(guid="Enter-guid")
print(json.dumps(response, indent=2))
# When you need to find multiple Guids and they all are the same type
#entities = client.get_entity(
# qualifiedName=["qualifiedname1", "qualifiedname2", "qualifiedname3"],
# typeName="my_type"
#)
#for entity in entities.get("entities"):
# print(json.dumps(entity, indent=2))
运行上述代码后,您将能够在 Databricks 笔记本中看到返回的关于各自 GUID 的结果,如图 24-42 所示。还要考虑探索和集成 Spline ( https://absaoss.github.io/spline/blog.html
),这是一种以轻量级和易于使用的方式从内部 Spark 执行计划中捕获和存储沿袭信息的编程方法。
图 24-42
apache atlas api 从数据块读取预览帐户
摘要
在这一章中,我探讨了如何开始使用 Azure 权限,从设置一个新的权限帐户到管理凭证和访问。然后,我演示了如何创建和注册数据源,创建和触发扫描,以及浏览资产。最后,我谈到了如何通过使用 Apache Atlas API 以编程方式使用 Azure 权限。
azure without 是微软提供的一款很有前途的现代云数据治理产品,它通过 without Studio 提供了一个低代码、易于使用的接口。这种易用性使各种业务和 IT 专业人员能够轻松地使用权限。随着这种数据治理产品的不断成熟,它所支持的特性和来源只会越来越多。
权限也开始与其他 Azure 产品很好地集成,如 Synapse Analytics workspaces,我们在第二十三章中讨论过。在 Synapse Analytics 工作区中,用户可以创建新的数据工厂管道,连接到权限帐户,并利用权限的力量在数据工厂体验中搜索源、汇和各种其他资产。这提供了轻松搜索和构建 ETL 管道的能力。无论是通过编程还是通过其低代码的 studio 接口,without 还可以与各种其他 Azure 服务(如 Power BI 等)很好地集成。随着 Azure 的不断成熟,它有可能成为一个成熟的数据治理产品,可以与市场上更成熟的基于云的数据治理工具相媲美。