【详谈 Delta Lake 】系列技术专题 之 基础和性能(Fundamentals and Performance)-阿里云开发者社区

开发者社区> Apache Spark中国社区> 正文
登录阅读全文

【详谈 Delta Lake 】系列技术专题 之 基础和性能(Fundamentals and Performance)

简介: 本文翻译自大数据技术公司 Databricks 针对数据湖 Delta Lake 的系列技术文章。众所周知,Databricks 主导着开源大数据社区 Apache Spark、Delta Lake 以及 ML Flow 等众多热门技术,而 Delta Lake 作为数据湖核心存储引擎方案给企业带来诸多的优势。本系列技术文章,将详细展开介绍 Delta Lake。
(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅998元/3年,立即抢购>>>:9i0i.cn/aliyun

福利推荐:阿里云、腾讯云、华为云等大品牌云产品全线2折优惠活动来袭,4核8G云服务器899元/3年,新老用户共享优惠,点击这里立即抢购>>>

前言

本文翻译自大数据技术公司 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 了解详情。

译者:韩宗泽(棕泽),阿里云计算平台事业部技术专家,负责开源大数据生态企业团队的研发工作。


1.jpg


Delta Lake技术系列 - 基础和性能(Fundamentals and Performance)

——使用Delta Lake为机器学习和商业智能提供可靠的数据保障


2.jpg


目录

  • Chapter-01 Delta Lake 基础:为什么可靠性和性能很重要?
  • Chapter-02 深入理解事务日志(Transaction Log)
  • Chapter-03 如何使用 Schema 约束(Schema Enforcement)和演变(Schema Evolution)
  • Chapter-04 Delta Lake DML 语法
  • Chapter-05 在 Delta Lake 中使用 Data Skipping 和 Z-Ordering 来快速处理PB级数据


本文介绍内容

Delta Lake 系列电子书由 Databricks 出版,阿里云计算平台事业部大数据生态企业团队翻译,旨在帮助领导者和实践者了解 Delta Lake 的全部功能以及它所处的场景。在本文中,Delta Lake 系列-基础和性能(Fundamentals and performance),重点介绍 Delta Lake 的基础及性能。


后续

读完本文后,您不仅可以了解 Delta Lake 提供了什么特性,还可以理解这些的特性是如何带来实质性的性能改进的。

3.jpg


什么是 Delta Lake?

Delta Lake 是一个统一的数据管理系统,为云上数据湖带来数据可靠性和快速分析。 Delta Lake 运行在现有数据湖之上,并且与 Apache Spark 的 API 完全兼容。


在 Databricks,我们看到了 Delta Lake 如何为数据湖带来可靠性、性能和生命周期管理。我们的客户已经证明,Delta Lake 解决了以下难题:从复杂的数据格式中提取数据的挑战、删除数据以实现法规遵从性的困难、以及为数据捕获进行修改数据所带来的问题。


使用 Delta Lake,您可以加快高质量数据导入数据湖的速度,团队也可以在云服务上快速使用这些数据,安全且可扩展。


4.jpg


Chapter-01 Delta Lake 基础:为什么可靠性和性能很重要?

5.jpg

提到数据可靠性,性能(程序运行的速度)是其中最重要的指标。由于 Delta Lake 提供的 ACID 事务性保护,您可以获得所需的可靠性和性能。


使用 Delta Lake,您可以同时进行流式和批处理作业(我们称为批流一体)、执行 CRUD(对数据的增删改查)操作,从而节省您的资金——因为您现在使用的 vm 相比之前更少了。通过使用批流一体架构,使得维护您数据工程的 data pilelines 会变得非常轻松。


Delta Lake 是一个存储层,它通过在写操作间进行乐观锁控制和快照隔离技术,来提供 ACID 事务性,从而为基于 HDFS 和云对象存储(如阿里云 OSS、AWS S3)的数据湖带来可靠性,进而在写操作期间可以实现一致性的数据读取。Delta Lake 还提供了内置的数据版本控制,以方便回滚和复现。


在本章中,我们将分享数据湖的一些常见挑战,以及 Delta Lake 是如何解决这些挑战的。


数据湖的挑战

数据湖是现代数据体系结构中的一个常见元素。它们通常充当大量数据的存储中心和接收点,以使公司对数据进行收集并挖掘数据的价值。虽然随着数据湖的演进在领域内有所发展,但数据湖通常会有以下几点问题:


6.jpg


  1. 数据湖中数据的读写是不可靠的(Reading and writing into data lakes is not reliable)。数据工程师经常遇到这样的问题:不安全地写入数据湖,这会导致如果读取数据过程中同时又有数据写入,那么将会产生垃圾数据。那边必须构建其他额外的方法,来保证数据同时读写情况的数据一致性。


  1. 数据湖中的数据质量较低(The data quality in data lakes is low)。将非结构化数据转储到数据湖通常都很容易,但这是以牺牲数据质量为代价的。由于没有任何机制来验证Schema和数据,数据湖中的数据质量通常都会很差。那么这会导致那些试图挖掘这些数据的分析项目也随之失败了(由于数据质量低)。


  1. 持续增长的数据规模导致性能很差(Poor performance with increasing amounts of data)。随着存储到数据湖中的数据持续增加,文件和目录的数量也会随之增加。大数据作业和查询引擎将会花费大量时间来处理元数据——这个问题在流作业或处理许多并发批处理作业的情况下更为明显。


  1. 在数据湖中修改、更新或者删除记录非常困难Modifying, updating or deleting records in data lakes is hard )。工程师需要构建复杂的Pipeline来读取整个分区或表,修改数据并将其写回。这种Pipeline效率很低,而且难以维护。


由于数据湖的上述这些挑战,许多大数据项目未能实现其愿景,甚至有时项目会完全失败。我们需要一个解决方案,使得数据从业者能够利用好他们现有的数据湖,同时可以确保数据的质量。


Delta Lake的核心能力

Delta Lake 简化了构建数据湖的方式,并解决了上述问题。Delta Lake提供以下关键功能:

7.jpg


  • ACID 事务性:Delta Lake 在多个写操作之间提供 ACID 事务性。每一次写操作都是一个事务操作,事务日志(Transaction Log)中记录的写操作都有一个顺序序列。事务日志(Transaction Log)跟踪了文件级别的写操作,并使用了乐观锁进行并发控制,这非常适用于数据湖,因为尝试修改相同文件的多次写操作的情况并不经常发生。当发生冲突时,Delta Lake 会抛出一个并发修改异常,抛给供用户处理并重试其作业。Delta Lake 还提供了最高级别的隔离(可序列化隔离),允许工程师不断地向目录或表写入数据,而使用者不断地从同一目录或表读取数据,读取数据时会看到数据的最新快照。


  • Schema 管理(Schema management):Delta Lake 会自动验证正在写入的 DataFrame 的 Schema 是否与表的 Schema 兼容。若表中存在但 DataFrame 中不存在的列则会被设置为 null。如果 DataFrame 中有额外的列不在表中,那么该操作将会抛出异常。Delta Lake 具有 DDL(数据定义语言)显式添加新列的功能,并且能够自动更新 Schema。


  • 可伸缩的元数据(Metadata)处理:Delta Lake 将表或目录的元数据信息存储在事务日志(Transaction Log)中,而不是元数据 Metastore 中。这使得 Delta Lake 够在固定时间内列出大目录中的文件,并且在读取数据时效率很高。


  • 数据版本控制和时间旅行(Time Travel):Delta Lake 允许用户读取表或目录的历史版本快照。当文件在写入过程中被修改时,Delta Lake 会创建文件的新的版本并保留旧版本。当用户想要读取表或目录的较旧版本时,他们可以向 Apach Spark 的 read API 提供时间戳或版本号,Delta Lake 根据事务日志(Transaction Log)中的信息来构建该时间戳或版本的完整快照。这非常方便用户来复现实验和报告,如果需要,还可以将表还原为旧版本。


  • 统一批流一体:除了批处理写入之外,Delta Lake 还可以作为 Apache Spark 的结构化流的高效流接收器(Streaming Sink)。与 ACID 事务和可伸缩元数据处理相结合,高效的流接收器(Streaming Sink)支持大量近实时的分析用例,而无需维护复杂的流和批处理管道。


  • 记录更新和删除:Delta Lake 将支持合并、更新和删除的DML(数据管理语言)命令。这使得工程师可以轻松地在数据湖中插入和删除记录,并简化他们的变更数据捕获和 GDPR(一般数据保护条例)用例。由于 Delta Lake 在文件级粒度上进行跟踪和修改数据,因此它比读取和覆盖整个分区或表要高效得多。


  • 数据期望(Data expectations,即将推出):Delta Lake 还将支持一个新的 API 来设置表或目录的数据期望。工程师将能够指定一个布尔条件并调整参数以处理数据的期望。当 Apache Spark 作业写入表或目录时,Delta Lake 将自动验证记录,当发生冲突时,它将根据提供的严重性处理记录。


8.jpg


Chapter-02 深入理解事务日志(Transaction Log)

9.jpg


事务日志(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)如何为多个并发读写的问题提供一个优雅的解决方案。

10.jpg


实现原子性以保证操作的完全性

原子性是 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 的耐用性属性,这意味着即使在系统发生故障的情况下,它也将持续存在。


11.jpg


时间旅行(Time travel)、数据沿袭(Data Lineage)和调试(Debugging)

每个表都是 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)。


12.jpg


Chapter-03 如何使用Schema约束(Schema Enforcement)和演变(Evolution)

13.jpg


随着业务问题和需求的发展,数据的结构也在不断变化。在 Delta Lake 中,合并新的列或对象是很容易的,用户可以访问简单的语义来控制其表的 Schema。同时,重要的是要强调 Schema 约束的重要性,以防止用户在 Schema 演变过程中意外地用错误或垃圾数据污染他们的表,这使他们能够自动添加新的数据列。


Schema 约束(Schema Enforcement)拒绝任何不兼容表的新增和修改操作。通过设置和维护这些更高的标准,分析师和工程师可以相信他们的数据具有最高级别的完整性,从而可以清晰地进行推理,使他们能够做出更好的业务决策。


另一方面,Schem 演变(Schema Evolution)通过使预期的 Schema 更改易自动发生。毕竟,添加一个列应该不难。


Schema 约束(Schema Enforcement)和 Schema 演变(Schema Evolution)是互补的能力。当这些功能结合使用时,比以往任何时候都更容易得到好的效果。


理解表的 Schema

Apache Spark 中的每个 DataFrame 都包含一个 Schema——Schema 定义了数据的描述(如数据类型和列)和蓝图、以及元数据信息。在 Delta Lake 中,表的 Schema 以 JSON 格式保存在事务日志中。


14.jpg


什么是 Schema 约束(Schema Enforcement)?

Schema 约束(Schema enforcement,或 Schema validation)是 Delta Lake 中的一种保护措施,它通过拒绝对与表的 Schema 不匹配的写入操作,来保证数据质量。


就像繁忙餐厅的前台经理只接受预订一样,它检查插入表中的每一列数据是否在其预期列的列表中(换句话说,每一列是否都有“预订”),并拒绝任何不在列表中的列的写入。


Schema 约束(Schema Enforcement)是如何工作的?

Delta Lake 使用写时 Schema 校验,这意味着在写入时检查对表的所有新写入是否与目标表的 Schema 兼容。如果 Schema 不兼容,Delta Lake 将完全取消事务,不写入任何数据,并抛出异常以让用户知道表结构不匹配。

为了确定对表的写入是否兼容,Delta Lake 使用以下规则。要写入的 DataFrame 不能包含:


  • 目标表结构中不存在的任何其他列。相反,如果传入的数据不包含表中的列,则没有问题——这些列将被简单地分配 null 值。


  • 与目标表中的列数据类型不同的列数据类型。如果目标表的列包含 StringType 数据,但 DataFrame 中的相应列包含 IntegerType 数据,则架构强制将引发异常并阻止执行写操作。


  • 只有大小写不同的列名。这意味着不能在同一个表中定义名为“Foo”和“foo”的列。虽然 Spark 可以在区分大小写或不区分大小写(默认)Schema 下使用,但是 Delta Lake 保留大小写,但在存储 Schema 时不区分大小写。在存储和返回列信息时,Parquet 区分大小写。为了避免潜在的错误、数据损坏或丢失问题(这是我们在 Databricks 亲身经历的),我们决定添加这个限制。


Delta Lake 不是自动添加新的列,而是强制执行 Schema,并停止写入。为了帮助识别导致不匹配的列,Spark 打印出堆栈来跟踪两个 Schema 以进行比较。


Schema 约束起到什么作用呢?

因为这是一个非常严格的检查,所以 Schema 约束是一个很好的工具,可以用作一个干净的、完全转换的数据集的网关,该数据集可以用于生产或消费。通常在结果数据的表上强制执行:


  • 机器学习算法
  • BI 仪表盘
  • 数据分析和可视化工具
  • 任何需要高度结构化、强类型、语义 Schema 的生产系统


为了为这最后一个障碍准备数据,许多用户采用了一种简单的多跳架构,该架构可以逐步地向表中添加结构。要了解更多信息,请查看「基于 Delta Lake 的机器学习」(https://databricks.com/blog/2019/08/14/productionizing-machine-learning-with-delta-lake.html)。


15.jpg

什么是 Schema 演变?

Schema 演变是一种允许用户轻松更改表的当前 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 演变的条件:


  • 添加新列(这是最常见的场景)
  • 从 NullType->any other type 更改数据类型,或从 ByteType->ShortType->IntegerType 升级数据类型


其他不符合 Schema 演变条件的更改要求通过添加 .option(“overwriteSchema”,“true”) 覆盖 Schema 和数据。这些变化包括:


  • 删除列
  • 更改现有列的数据类型(就地)
  • 重命名仅区分大小写的列名(例如,“Foo”和“foo”)


最后,随着 Spark 3.0 的发布,完全支持显式 DDL(使用ALTER TABLE),允许用户对表 Schema 执行以下操作:


  • 添加列
  • 更改列注释
  • 设置定义表行为的表属性,例如设置事务日志的保留期限


16.jpg


Schema 演变起到什么作用呢?

无论何时,只要您打算更改表的 Schema,就可以使用 Schema 演变(而不是意外地将不应该存在的列添加到 DataFrame 中)。这是迁移 Schema 的最简单方法,因为它自动添加正确的列名和数据类型,而不必显式声明。


总结

Schema 约束拒绝与表不兼容的任何新列或其他 Schema 更改,通过设置和维护这些高标准,分析师和工程师可以相信他们的数据具有最高级别的完整性,并且可以清晰地进行推理,从而使他们能够做出更好的业务决策。


另一方面,Schema 演变通过使预期的 Schema 更改轻松自动化。毕竟,添加一个列应该不难。


Schema 约束(Schema Enforcement)和 Schema 演变(Schema Evolution)是互补的能力。当这些功能结合使用时,比以往任何时候都更容易得到好的效果。



17.jpg


Chapter-04 Delta Lake DML(数据操作语言)

18.jpg


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


19.jpg


更新(UPDATE):底层原理

Delta Lake 分两步对表执行 UPDATE:


  1. 查找并选择包含与谓词匹配的数据的文件,这些文件是需要更新的。Delta Lake 尽可能使用 Data Skipping 来加速这个过程。
  2. 将每个匹配文件读入内存,更新相关行,并将结果写入新的数据文件。


一旦 Delta Lake 成功地执行了 UPDATE 操作,它就会在事务日志中添加一个 commit,表示从现在起将使用新的数据文件代替旧的数据文件。不过,旧数据文件并不会被删除。相反,它只是简单的“逻辑删除”——会记录为应用于表的旧版本的数据文件,而不是当前版本的数据文件。Delta Lake 能够使用这个逻辑来提供数据版本控制(Version control)和时间旅行(Time travel)。


UPDATE + Delta Lake Time Travel = 易于Debugging

保留旧数据文件对于调试 debug 非常有用,因为您可以使用 Delta Lake “时间旅行”随时返回并查询表的早期版本。如果您错误地更新了表,并且想知道发生了什么,您可以很容易地将一个表的两个版本相互比较,以查看发生了什么变化。

SELECT * FROM events VERSION AS OF 11 EXCEPT ALL SELECT
* FROM mytable VERSION AS OF 12

UPDATE:性能优化 tips

优化 Delta Lake 中 UPDATE 命令性能的主要方法是,添加更多谓词以缩小搜索空间(精确更新数据的范围)。搜索越具体,Delta Lake 需要扫描或修改的文件就越少。


Delta Lake DML:DELETE

可以使用 DELETE 命令根据谓词(过滤条件)有选择地删除行。

DELETE FROM events WHERE date < ‘2017-01-01’

如果要还原意外的删除操作,可以使用时间旅行将表回滚到原来的状态。


20.jpg


删除(DELETE):底层原理

删除(DELETE)如更新(UPDATE)原理类似。Delta Lake 对数据进行两次扫描:第一次扫描是识别包含与谓词条件匹配的行的任何数据文件,第二次扫描将匹配的数据文件读入内存,此时 Delta Lake 会在将新的数据写入磁盘之前删除所选行。


Delta Lake 成功完成删除操作后,旧数据文件不会被完全删除——它们仍保留在磁盘上,但在 Delta Lake 事务日志中记录为“tombstoned”(不再是活动表的一部分)。


请记住,Delta Lake 不会立即删除这些旧文件,因为您可能仍然需要它们时间旅行回到表的早期版本。如果要删除超过某个时间段的文件,可以使用 VACUUM 命令。


删除(DELETE)+ VACUUM:清理旧的数据文件

运行 VACUUM 命令将永久删除以下所有数据文件:


  1. 已不再是当前表的部分数据,并且:
  2. 早于保留阈值,默认为7天


Delta Lake 不会自动清空旧文件——您必须自己运行命令清除,如下所示。如果要指定不同于默认七天的保留期,可以将其作为参数提供。

from delta.tables import * deltaTable.
# vacuum files older than 30 days(720 hours)
deltaTable.vacuum(720)

21.jpg


删除(DELETE):性能优化tips

与 UPDATE 命令一样,优化 Delta Lake 上 DELETE 操作性能的主要方法是,添加更多谓词以缩小搜索空间。Delta Lake 的 Databricks 管理版本(Databricks Runtime 企业版)还具有其他性能增强功能,如改进的 Data Skipping、bloom 过滤器和 Z-Order 优化(多维集群)。


Delta Lake DML: MERGE

Delta Lake MERGE 命令允许您执行 Upserts,这是更新(UPDATE)和插入(INSERT)的混合操作。要理解 Upserts,假设您有一个当前表(也称为目标表)和一个源表,其中包含新记录和对现有记录的更新。


下面是 upsert 的工作原理:


  • 当源表中的记录与目标表中预先存在的记录匹配时,Delta Lake 会更新该记录。
  • 如果没有这样的匹配,Delta Lake 将插入新记录。


Delta Lake MERGE 命令极大地简化了工作流程,这些工作流程与其他传统数据格式(如Parquet)相比可能非常复杂和繁琐。合并(MERGE)和升级(Upserts)带来便利的常见场景包括更改数据捕获、GDPR/CCPA 遵从性、会话化和记录的重复数据消除。

22.jpg

MERGE:底层原理

Delta Lake 分两步完成 MERGE 操作:


  1. 在目标表和源表之间执行内部联接,以选择所有匹配的文件。
  2. 在目标表和源表中的选定文件之间执行外部联接,并写出更新(UPDATE)/删除(DELETE)/插入(INSERT)的数据。


这与更新或删除不同的主要方式是,Delta Lake 使用连接(Join)来完成合并,这一事实允许我们在性能优化时使用一些独特的策略。


MERGE:性能优化 tips

为了提高 MERGE 命令的性能,您需要确定组成合并的两个连接中的哪一个限制了您的速度。如果内部连接是瓶颈(即,查找 Delta Lake 需要重写的文件花费的时间太长),请尝试以下策略:

  • 添加更多谓词以缩小搜索空间。
  • 调整随机分区。
  • 调整广播连接阈值。
  • 压缩表中的小文件(如果有很多),但不要压缩


因为 Delta Lake 必须复制整个文件才能重写它,所以将它们转换为太大的文件。


在 Databricks 版本的 Delta Engine(企业版 Databricks Runtime)中,使用 Z-Ordering 优化来利用更新的位置。


另一方面,如果外部连接是瓶颈(即重写实际文件本身花费的时间太长),请尝试以下策略。


  • 调整随机分区。
  • 通过在写入前启用自动重新分区来减少文件(在 Databricks Delta Lake 中优化写入)。
  • 调整广播阈值。如果正在执行完全外部联接,Spark 无法执行广播联接,但是如果正在执行正确的外部联接,Spark 可以执行一个,并且可以根据需要调整广播阈值。
  • 缓存源表 / DataFrame。
  • 缓存源表可以加快第二次扫描,但请确保不要缓存目标表,因为这可能导致缓存一致性问题。


Delta Lake 支持 DML 命令,包括 UPDATE、DELETE 和 MERGE-INTO,这大大简化了许多常见大数据操作的工作流。在本章中,我们演示了如何在 Delta Lake 中使用这些命令,分享了关于每个命令的工作原理,并提供了一些性能调优技巧。


23.jpg

Chapter-05 Delta Lake如何使用Data Skipping和Z-Ording快速处理PB级别数据

24.jpg


Delta Lake 能够在几秒钟内筛选出数 PB 级数据。这种速度主要归功于两个特性:(1)Data Skipping和(2)Z-Ordering。


结合这些特性有助于 Databricks 运行时显著减少需要扫描的数据量,以针对大型 Delta表的选择性查询,这通常转化为运行时的显著改进和成本节约。


使用 Delta Lake 内置的 Data Skipping 过和 Z-Ordering 集群功能,通过跳过与查询无关的文件,可以在几秒钟内查询到大型云上数据湖数据。例如,在一个网络安全分析用例中,对于典型的查询,504TB数据集中93.2%的记录被跳过,从而将查询时间减少了两个数量级。换句话说,Delta Lake 可以将您的查询速度提高100倍之多。


想了解 Data Skipping 和 Z-Ordering 的实际应用吗?

Apple 的 Dominique Brezinski 和 Databricks 的 Michael Armbrust 演示了如何在网络安全监控和威胁应对的背景下,将 Delta Lake 作为数据工程和数据科学的统一解决方案。了解他们的主题演讲:「 Threat Detection and Response at Scale」(https://databricks.com/session/keynote-from-apple)。

25.jpg


使用 Data Skipping 和 Z-Ordering

Data Skipping 和 Z-Ordering 被用来提升对大规模数据集的查询性能。Data Skipping 过是 Delta Lake 的一项自动化功能,每当您的 SQL 查询或数据集操作包含“column op literal”形式的过滤器时,就会自动跳过,其中:


  • column 是一些 Delta Lake 表的一个属性,无论是顶级的还是嵌套的,其数据类型 为string/numeric/date/timestamp
  • op 是一个二进制比较运算符,StartsWith/LIKE pattern%',或 IN
  • literal 是与列具有相同数据类型的显式(列表)值


AND/OR/NOT 以及“literal op column”谓词也受支持。即使 Data Skipping 过在满足上述条件时起作用,它也未必总是有效的。但是,如果有一些列是您经常筛选的,并且希望确保快速筛选,则可以通过运行以下命令显式优化数据布局,以跳过有效性:


OPTIMIZE [WHERE ]

ZORDER BY ( [, ...])


探索细节

除了分区裁剪之外,数据仓库世界中使用的另一种常见技术( 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


26.jpg



后续

您已经了解了 Delta Lake 及其特性,以及如何进行性能优化,本系列还包括其他内容:

  • Delta Lake 技术系列-特性
  • Delta Lake 技术系列-Lakehouse
  • Delta Lake 技术系列-Streaming
  • Delta Lake 技术系列-客户用例(Use Case)





获取更详细的 Databricks 数据洞察相关信息,可至产品详情页查看:

https://www.aliyun.com/product/bigdata/spark


阿里巴巴开源大数据技术团队成立 Apache Spark 中国技术社区,定期推送精彩案例,技术专家直播,只为营造纯粹的 Spark 氛围,欢迎关注公众号!


扫描下方二维码入 Databricks 数据洞察产品交流钉钉群一起参与交流讨论!


image.png


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:


http://www.vxiaotou.com