本文翻译自大数据技术公司 Databricks 针对数据湖 Delta Lake 系列技术文章。众所周知 Databricks 主导着开源大数据社区 Apache Spark、Delta Lake 以及 ML Flow 等众多热门技术 而 Delta Lake 作为数据湖核心存储引擎方案给企业带来诸多的优势。
此外 阿里云和 Apache Spark 及 Delta Lake 的原厂 Databricks 引擎团队合作 推出了基于阿里云的企业版全托管 Spark 产品——Databricks 数据洞察 该产品原生集成企业版 Delta Engine 引擎 无需额外配置 提供高性能计算能力。有兴趣的同学可以搜索 Databricks 数据洞察 或 阿里云 Databricks 进入官网 或者直接访问 https://www.aliyun.com/product/bigdata/spark 了解详情。
译者 韩宗泽 棕泽 阿里云计算平台事业部技术专家 负责开源大数据生态企业团队的研发工作。
——使用Delta Lake为机器学习和商业智能提供可靠的数据保障
Delta Lake 系列电子书由 Databricks 出版 阿里云计算平台事业部大数据生态企业团队翻译 旨在帮助领导者和实践者了解 Delta Lake 的全部功能以及它所处的场景。在本文中 Delta Lake 系列-基础和性能 Fundamentals and performance 重点介绍 Delta Lake 的基础及性能。
读完本文后 您不仅可以了解 Delta Lake 提供了什么特性 还可以理解这些的特性是如何带来实质性的性能改进的。
Delta Lake 是一个统一的数据管理系统 为云上数据湖带来数据可靠性和快速分析。 Delta Lake 运行在现有数据湖之上 并且与 Apache Spark 的 API 完全兼容。
在 Databricks 我们看到了 Delta Lake 如何为数据湖带来可靠性、性能和生命周期管理。我们的客户已经证明 Delta Lake 解决了以下难题 从复杂的数据格式中提取数据的挑战、删除数据以实现法规遵从性的困难、以及为数据捕获进行修改数据所带来的问题。
使用 Delta Lake 您可以加快高质量数据导入数据湖的速度 团队也可以在云服务上快速使用这些数据 安全且可扩展。
提到数据可靠性 性能 程序运行的速度 是其中最重要的指标。由于 Delta Lake 提供的 ACID 事务性保护 您可以获得所需的可靠性和性能。
使用 Delta Lake 您可以同时进行流式和批处理作业 我们称为批流一体 、执行 CRUD 对数据的增删改查 操作 从而节省您的资金——因为您现在使用的 vm 相比之前更少了。通过使用批流一体架构 使得维护您数据工程的 data pilelines 会变得非常轻松。
Delta Lake 是一个存储层 它通过在写操作间进行乐观锁控制和快照隔离技术 来提供 ACID 事务性 从而为基于 HDFS 和云对象存储 如阿里云 OSS、AWS S3 的数据湖带来可靠性 进而在写操作期间可以实现一致性的数据读取。Delta Lake 还提供了内置的数据版本控制 以方便回滚和复现。
在本章中 我们将分享数据湖的一些常见挑战 以及 Delta Lake 是如何解决这些挑战的。
数据湖是现代数据体系结构中的一个常见元素。它们通常充当大量数据的存储中心和接收点 以使公司对数据进行收集并挖掘数据的价值。虽然随着数据湖的演进在领域内有所发展 但数据湖通常会有以下几点问题
由于数据湖的上述这些挑战 许多大数据项目未能实现其愿景 甚至有时项目会完全失败。我们需要一个解决方案 使得数据从业者能够利用好他们现有的数据湖 同时可以确保数据的质量。
Delta Lake 简化了构建数据湖的方式 并解决了上述问题。Delta Lake提供以下关键功能
事务日志 Transaction Log 是理解 Delta Lake 的关键 因为它是许多最重要功能的基础 包括 ACID 事务、可伸缩的元数据处理、时间旅行等等。Delta Lake 事务日志是自 Delta Lake 表创建以来在其上执行的所有事务的有序记录。
Delta Lake 构建在 Apache Spark 之上 允许用户在特定的表上同时进行并发的读写操作。为了随时向用户显示正确的数据视图 事务日志 Transaction Log 充当了唯一的真实来源 跟踪用户对表所做的所有更改的中央存储。
当用户第一次读取 Delta Lake 表或对自上次读取以来已修改的表运行新查询时 Spark将检查事务日志 Transaction Log 以查看哪些新事务已发布到该表。然后 Spark 用这些新的更改来更新最终用户的表。这可以确保用户版本的表始终与主记录在最近一次查询时保持同步 并且用户不能对表进行有分歧的、有冲突的更改。
在本章中 我们将探讨 Delta Lake 事务日志 Transaction Log 如何为多个并发读写的问题提供一个优雅的解决方案。
原子性是 ACID 事务的四个属性之一 它保证对数据湖执行的操作 如插入或更新数据 要么完全完成 要么根本不完成。如果没有这个属性 硬件故障或软件错误很容易导致数据只部分写入表 从而导致数据混乱或损坏。
事务日志 Transaction Log 是 Delta Lake 提供原子性保证的机制。不管怎么说 事务日志中不存在的记录 它就永远不会发生。Delta Lake 事务日志 Transaction Log 只记录完全执行的事务 并将该记录用作唯一的真实来源 因此用户可以在 PB 级的数据进行推理 并确保基本的数据可信度。
但是Delta Lake如何处理多个并发读写呢 由于 Delta Lake 是由 Apache Spark 提供支持的 因此需要能够支持让多个用户同时修改一个表——这是所期待的的能力。为了处理这些情况 Delta Lake 采用了乐观锁并发控制。
乐观锁并发控制是一种处理并发事务的方法 它假定了不同用户对表所做的更改可以在不发生冲突的情况下完成。它的速度非常快 因为在处理数 PB 级别数据时 用户很可能同时处理着数据的不同部分 从而允许他们同时完成不冲突的事务。
当然 即使使用乐观并发控制 有时用户也会尝试同时修改数据的相同部分。幸运的是 Delta Lake 有一个协议 Delta Lake 通过实施互斥规则来处理这些 case 然后它试图乐观地解决任何冲突。
这个协议允许 Delta Lake 提供 ACID 隔离原则 这确保了在多个并发写操作之后 表的结果状态与这些写操作彼此隔离地连续发生时的状态相同。
由于在 Delta Lake 表上进行的所有事务都直接存储到磁盘上 因此这个过程满足 ACID 的耐用性属性 这意味着即使在系统发生故障的情况下 它也将持续存在。
每个表都是 Delta Lake 事务日志 Transaction Log 中记录的所有提交的总和的结果——不多也不少。事务日志 Transaction Log 提供了一个分步指导 详细说明了如何从表的原始状态到当前状态。
因此 我们可以从原始表开始 在任何时间点重新创建表的状态 并且只处理在该时间点之后进行的提交。这种强大的能力被称为“时间旅行 Time travel ” 或数据版本控制 在很多情况下都可以成为救命稻草。有关更多信息 请参阅文章 「为大规模数据湖引入 Delta 时间旅行」 https://databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html 和 「利用 Delta Lake 和 MLflow 为数据科学做好数据准备」 https://www.youtube.com/watch?v hQaENo78za0 list PLTPXxbhUt-YVPwG3OWNQ-1bJI_s_YRvqP index 21 t 112s 。
Delta Lake 事务日志 Transaction Log 是对表所做的每一次更改的最终记录 它为用户提供了一个可验证的数据谱系 对于治理、审计和法规遵从性非常有用。它还可以用于跟踪管道中的意外更改或错误的根源 以找到导致错误的确切操作。用户可以运行 DESCRIBE HISTORY 命令来查看所做更改的相关元数据信息。
想进一步了解 Delta Lake 的事务日志吗 您可以阅读我们的博客 https://databricks.com/blog/2019/08/21/diving-into-delta-lake-unpacking-the-transaction-log.html 或者观看我们的技术讲座 https://databricks.com/discover/diving-into-delta-lake-talks/unpacking-transaction-log 。
随着业务问题和需求的发展 数据的结构也在不断变化。在 Delta Lake 中 合并新的列或对象是很容易的 用户可以访问简单的语义来控制其表的 Schema。同时 重要的是要强调 Schema 约束的重要性 以防止用户在 Schema 演变过程中意外地用错误或垃圾数据污染他们的表 这使他们能够自动添加新的数据列。
Schema 约束 Schema Enforcement 拒绝任何不兼容表的新增和修改操作。通过设置和维护这些更高的标准 分析师和工程师可以相信他们的数据具有最高级别的完整性 从而可以清晰地进行推理 使他们能够做出更好的业务决策。
另一方面 Schem 演变 Schema Evolution 通过使预期的 Schema 更改易自动发生。毕竟 添加一个列应该不难。
Schema 约束 Schema Enforcement 和 Schema 演变 Schema Evolution 是互补的能力。当这些功能结合使用时 比以往任何时候都更容易得到好的效果。
Apache Spark 中的每个 DataFrame 都包含一个 Schema——Schema 定义了数据的描述 如数据类型和列 和蓝图、以及元数据信息。在 Delta Lake 中 表的 Schema 以 JSON 格式保存在事务日志中。
Schema 约束 Schema enforcement 或 Schema validation 是 Delta Lake 中的一种保护措施 它通过拒绝对与表的 Schema 不匹配的写入操作 来保证数据质量。
就像繁忙餐厅的前台经理只接受预订一样 它检查插入表中的每一列数据是否在其预期列的列表中 换句话说 每一列是否都有“预订” 并拒绝任何不在列表中的列的写入。
Delta Lake 使用写时 Schema 校验 这意味着在写入时检查对表的所有新写入是否与目标表的 Schema 兼容。如果 Schema 不兼容 Delta Lake 将完全取消事务 不写入任何数据 并抛出异常以让用户知道表结构不匹配。
为了确定对表的写入是否兼容 Delta Lake 使用以下规则。要写入的 DataFrame 不能包含
Delta Lake 不是自动添加新的列 而是强制执行 Schema 并停止写入。为了帮助识别导致不匹配的列 Spark 打印出堆栈来跟踪两个 Schema 以进行比较。
因为这是一个非常严格的检查 所以 Schema 约束是一个很好的工具 可以用作一个干净的、完全转换的数据集的网关 该数据集可以用于生产或消费。通常在结果数据的表上强制执行
为了为这最后一个障碍准备数据 许多用户采用了一种简单的多跳架构 该架构可以逐步地向表中添加结构。要了解更多信息 请查看「基于 Delta Lake 的机器学习」 https://databricks.com/blog/2019/08/14/productionizing-machine-learning-with-delta-lake.html 。
Schema 演变是一种允许用户轻松更改表的当前 Schema 以适应随时间变化的数据的功能。最常见的是 在执行追加或覆盖操作时使用它来自动调整 Schema 以包含一个或多个新增列。
继上一节中的示例之后 开发人员可以轻松地使用 Schema 演变来添加以前由于 Schema 不匹配而被拒绝的新列。通过使用 Spark .write 或 . writeStream 命令的 .option mergeSchema true 可以触发 Schema 演变 如下例所示。
#Add the mergeSchema option loans.write.format(“delta”) \ .option(“mergeSchema”, “true”) \ .mode(“append”) \ .save(DELTALAKE_SILVER_PATH)
通过在查询中包含 mergeSchema 选项 DataFrame 中存在但目标表中不存在的任何列都会作为写事务的一部分自动添加到 Schema 的末尾。也可以添加嵌套字段 这些字段也将添加到各自结构列的末尾。
数据工程师和科学家可以使用这个选项向他们现有的 ML 生产表中添加新的列 可能是一个新跟踪的指标 或者本月销售数据的一列 且不会破坏依赖于旧列的现有模型。
在表追加或覆盖期间 以下类型的架构更改符合 Schema 演变的条件
其他不符合 Schema 演变条件的更改要求通过添加 .option “overwriteSchema” “true” 覆盖 Schema 和数据。这些变化包括
最后 随着 Spark 3.0 的发布 完全支持显式 DDL 使用ALTER TABLE 允许用户对表 Schema 执行以下操作
无论何时 只要您打算更改表的 Schema 就可以使用 Schema 演变 而不是意外地将不应该存在的列添加到 DataFrame 中 。这是迁移 Schema 的最简单方法 因为它自动添加正确的列名和数据类型 而不必显式声明。
Schema 约束拒绝与表不兼容的任何新列或其他 Schema 更改 通过设置和维护这些高标准 分析师和工程师可以相信他们的数据具有最高级别的完整性 并且可以清晰地进行推理 从而使他们能够做出更好的业务决策。
另一方面 Schema 演变通过使预期的 Schema 更改轻松自动化。毕竟 添加一个列应该不难。
Schema 约束 Schema Enforcement 和 Schema 演变 Schema Evolution 是互补的能力。当这些功能结合使用时 比以往任何时候都更容易得到好的效果。
Delta Lake 支持数据操作语言 DML 命令 包括更新 UPDATE 、删除 DELETE 和合并 MERGE 。这些命令简化了数据变更 CDC 、审计和治理 以及GDPR/CCPA 等工作流程。
在本章中 我们将演示如何使用这些 DML 命令 来描述 Delta Lake 在幕后所做的工作 并为每一个命令提供一些性能调优技巧。
Delta Lake DML UPDATE可以使用 UPDATE 操作来有选择地更新与过滤条件匹配 也称为谓词 的任何行。下面的代码演示了如何将每种类型的谓词用作来 UPDATE。请注意 Delta Lake 提供了 Python、Scala 和 SQL 的 API 但在本电子书中 我们只包含 SQL 代码。
-- Update events UPDATE events SET eventType ‘click’ WHERE buttonPress 1
Delta Lake 分两步对表执行 UPDATE
一旦 Delta Lake 成功地执行了 UPDATE 操作 它就会在事务日志中添加一个 commit 表示从现在起将使用新的数据文件代替旧的数据文件。不过 旧数据文件并不会被删除。相反 它只是简单的“逻辑删除”——会记录为应用于表的旧版本的数据文件 而不是当前版本的数据文件。Delta Lake 能够使用这个逻辑来提供数据版本控制 Version control 和时间旅行 Time travel 。
保留旧数据文件对于调试 debug 非常有用 因为您可以使用 Delta Lake “时间旅行”随时返回并查询表的早期版本。如果您错误地更新了表 并且想知道发生了什么 您可以很容易地将一个表的两个版本相互比较 以查看发生了什么变化。
SELECT * FROM events VERSION AS OF 11 EXCEPT ALL SELECT * FROM mytable VERSION AS OF 12UPDATE 性能优化 tips
优化 Delta Lake 中 UPDATE 命令性能的主要方法是 添加更多谓词以缩小搜索空间 精确更新数据的范围 。搜索越具体 Delta Lake 需要扫描或修改的文件就越少。
可以使用 DELETE 命令根据谓词 过滤条件 有选择地删除行。
DELETE FROM events WHERE date ‘2017-01-01’
如果要还原意外的删除操作 可以使用时间旅行将表回滚到原来的状态。
删除 DELETE 如更新 UPDATE 原理类似。Delta Lake 对数据进行两次扫描 第一次扫描是识别包含与谓词条件匹配的行的任何数据文件 第二次扫描将匹配的数据文件读入内存 此时 Delta Lake 会在将新的数据写入磁盘之前删除所选行。
Delta Lake 成功完成删除操作后 旧数据文件不会被完全删除——它们仍保留在磁盘上 但在 Delta Lake 事务日志中记录为“tombstoned” 不再是活动表的一部分 。
请记住 Delta Lake 不会立即删除这些旧文件 因为您可能仍然需要它们时间旅行回到表的早期版本。如果要删除超过某个时间段的文件 可以使用 VACUUM 命令。
运行 VACUUM 命令将永久删除以下所有数据文件
Delta Lake 不会自动清空旧文件——您必须自己运行命令清除 如下所示。如果要指定不同于默认七天的保留期 可以将其作为参数提供。
from delta.tables import * deltaTable. # vacuum files older than 30 days(720 hours) deltaTable.vacuum(720)
与 UPDATE 命令一样 优化 Delta Lake 上 DELETE 操作性能的主要方法是 添加更多谓词以缩小搜索空间。Delta Lake 的 Databricks 管理版本 Databricks Runtime 企业版 还具有其他性能增强功能 如改进的 Data Skipping、bloom 过滤器和 Z-Order 优化 多维集群 。
Delta Lake MERGE 命令允许您执行 Upserts 这是更新 UPDATE 和插入 INSERT 的混合操作。要理解 Upserts 假设您有一个当前表 也称为目标表 和一个源表 其中包含新记录和对现有记录的更新。
下面是 upsert 的工作原理
Delta Lake MERGE 命令极大地简化了工作流程 这些工作流程与其他传统数据格式 如Parquet 相比可能非常复杂和繁琐。合并 MERGE 和升级 Upserts 带来便利的常见场景包括更改数据捕获、GDPR/CCPA 遵从性、会话化和记录的重复数据消除。
MERGE 底层原理Delta Lake 分两步完成 MERGE 操作
这与更新或删除不同的主要方式是 Delta Lake 使用连接 Join 来完成合并 这一事实允许我们在性能优化时使用一些独特的策略。
为了提高 MERGE 命令的性能 您需要确定组成合并的两个连接中的哪一个限制了您的速度。如果内部连接是瓶颈 即 查找 Delta Lake 需要重写的文件花费的时间太长 请尝试以下策略
因为 Delta Lake 必须复制整个文件才能重写它 所以将它们转换为太大的文件。
在 Databricks 版本的 Delta Engine 企业版 Databricks Runtime 中 使用 Z-Ordering 优化来利用更新的位置。
另一方面 如果外部连接是瓶颈 即重写实际文件本身花费的时间太长 请尝试以下策略。
Delta Lake 支持 DML 命令 包括 UPDATE、DELETE 和 MERGE-INTO 这大大简化了许多常见大数据操作的工作流。在本章中 我们演示了如何在 Delta Lake 中使用这些命令 分享了关于每个命令的工作原理 并提供了一些性能调优技巧。
Delta Lake 能够在几秒钟内筛选出数 PB 级数据。这种速度主要归功于两个特性 1 Data Skipping和 2 Z-Ordering。
结合这些特性有助于 Databricks 运行时显著减少需要扫描的数据量 以针对大型 Delta表的选择性查询 这通常转化为运行时的显著改进和成本节约。
使用 Delta Lake 内置的 Data Skipping 过和 Z-Ordering 集群功能 通过跳过与查询无关的文件 可以在几秒钟内查询到大型云上数据湖数据。例如 在一个网络安全分析用例中 对于典型的查询 504TB数据集中93.2%的记录被跳过 从而将查询时间减少了两个数量级。换句话说 Delta Lake 可以将您的查询速度提高100倍之多。
Apple 的 Dominique Brezinski 和 Databricks 的 Michael Armbrust 演示了如何在网络安全监控和威胁应对的背景下 将 Delta Lake 作为数据工程和数据科学的统一解决方案。了解他们的主题演讲 「 Threat Detection and Response at Scale」 https://databricks.com/session/keynote-from-apple 。
Data Skipping 和 Z-Ordering 被用来提升对大规模数据集的查询性能。Data Skipping 过是 Delta Lake 的一项自动化功能 每当您的 SQL 查询或数据集操作包含“column op literal”形式的过滤器时 就会自动跳过 其中
AND/OR/NOT 以及“literal op column”谓词也受支持。即使 Data Skipping 过在满足上述条件时起作用 它也未必总是有效的。但是 如果有一些列是您经常筛选的 并且希望确保快速筛选 则可以通过运行以下命令显式优化数据布局 以跳过有效性
OPTIMIZE table [WHERE partition_filter ]
ZORDER BY ( column [, ...])
除了分区裁剪之外 数据仓库世界中使用的另一种常见技术 Spark 目前缺乏这种技术 是基于小型物化聚合的I/O裁剪。简言之 其思想是跟踪与I/O粒度相关的简单统计信息 例如特定粒度下的最小值和最大值。我们希望在查询规划时利用这些统计信息 以避免不必要的I/O。
这是 Delta Lake 的 Data Skipping 功能所涉及的内容。在将新数据插入 Delta Lake 表时 将收集受支持类型的所有列 包括嵌套列 的文件级最小/最大统计信息。然后 当对表进行查找查询时 Delta Lake 首先查询这些统计信息 以便确定哪些文件可以安全地跳过。
想了解更多关于 Data Skipping 和 Z-Ordering 的信息 包括如何在网络安全分析中应用它吗 阅读我们的博客 https://databricks.com/blog/2018/07/31/processing-petabytes-of-data-in-seconds-with-databricks-delta.html
您已经了解了 Delta Lake 及其特性 以及如何进行性能优化 本系列还包括其他内容
Delta Lake 技术系列-特性Delta Lake 技术系列-LakehouseDelta Lake 技术系列-StreamingDelta Lake 技术系列-客户用例 Use Case获取更详细的 Databricks 数据洞察相关信息 可至产品详情页查看
https://www.aliyun.com/product/bigdata/spark
阿里巴巴开源大数据技术团队成立 Apache Spark 中国技术社区 定期推送精彩案例 技术专家直播 只为营造纯粹的 Spark 氛围 欢迎关注公众号
扫描下方二维码入 Databricks 数据洞察产品交流钉钉群一起参与交流讨论
在Python开发过程中,我们难免会遇到多重条件判断的情况的情况,此时除了用很多...
背景 我们知道 如果在Kubernetes中支持GPU设备调度 需要做如下的工作 节点上安装...
本文转载自公众号读芯术(ID:AI_Discovery)。 这一刻你正在应对什么挑战?这位前...
近几年,互联网行业蓬勃发展,在互联网浪潮的冲击下,互联网创业已成为一种比较...
溢价 域名 的续费价格如何?通常来说,因为溢价域名的价值高于普通域名,所以溢...
基本介绍 给定 n 个权值作为 n 个叶子节点,构造一颗二叉树,若该树的带权路径长...
TIOBE 公布了 2021 年 3 月的编程语言排行榜。 本月 TIOBE 指数没有什么有趣的变...
前言 统计科学家使用交互式的统计工具(比如R)来回答数据中的问题,获得全景的认...
想了解更多内容,请访问: 51CTO和华为官方战略合作共建的鸿蒙技术社区 https://...
本文转载自微信公众号「bugstack虫洞栈」,作者小傅哥 。转载本文请联系bugstack...