Delta Lake调研:Delta Lake是什么

在这里插入图片描述

Delta Lake是一个基于云对象存储的表存储工具,它实现了lakehouse的构想。Delta Lake可以解决工业领域数据产生,获取,分析等涵盖企业数据分析场景下,数据生命周期内的所有问题,因而有着广阔的使用前景。

本篇博客将带你阅读Delta Lake: High-Performance ACID Table Storage over Cloud Object Stores,了解Delta Lake是什么工具,进而对Delta Lake有一个主观的认识。

Delta Lake: High-Performance ACID Table Storage over Cloud Object Stores介绍了Delta Lake的产生背景,并介绍了其特性与实现方式。首先在INTODUCTION部分介绍了云对象存储(cloud object stores)正逐渐成为大数据时代最广泛使用的数据存储技术,介绍了云对象存储技术的一些特点,引出其所面临的挑战,最终引出Delta Lake是解决cloud object store面临挑战的解决方案。接着在MOTIVATION: CHARACTERISTICS AND CHALLENGES OF OBJECT STORES中介绍云对象存储的API和性能特征,以解释为什么在这些系统上高效的表存储具有挑战性,并概述管理这些系统上表格数据集的现有方法。然后在DELTA LAKE STORAGE FORMAT AND ACCESS PROTOCOLS中介绍了Delta Lake的存储格式和使用方法,并在HIGHER-LEVEL FEATURES IN DELTA中介绍Delta Lake的重要特性,在DELTA LAKE USE CASES中介绍Delta Lake的使用案例。最后在PERFORMANCE EXPERIMENTS中介绍实验结果,DISCUSSION AND LIMITATIONS中讨论Delta Lake的局限性。

此篇博客将重点介绍这篇论文的以下内容:

INTODUCTION

如Amazon S3[4]和Azure Blob存储[17]的云对象存储,已经成为地球上最大、应用最广泛的存储系统之一,为数百万客户存储了数EB的数据[46]。除了云服务的传统优势,如现收现付计费、规模经济和专家管理[15],云对象存储尤其具有吸引力,因为它们允许用户分别扩展计算和存储资源:例如,用户可以存储数PB的数据,但只能运行一个集群在其上执行几个小时的查询。

云对象存储越来越吸引人,因为它将计算和存储两个重要功能分开,因而适用于大量存储,但少量计算的应用场景,这一属性迎合了大数据时代的需求,因而更具有发展前景。

然而,尽管许多系统支持对云对象存储进行读写,但在这些系统上实现高性能和可变的表存储是一项挑战,这使得在这些系统上实现数据仓库功能变得困难。与分布式文件系统(如HDFS[5])或DBMS中的自定义存储引擎不同,大多数云对象存储只是键值存储,没有交叉键一致性保证。它们的性能特征也与分布式文件系统有很大不同,因而需要特别注意。

在云对象存储中存储关系数据集最常见的方法是使用列式文件格式,如Parquet和ORC,其中每个表存储为一组对象(Parquet或ORC
“文件”),可能由一些字段聚集到“分区”中(例如,每个日期的一组单独的对象)[45]。只要目标文件适度大,这种方法就可以为扫描工作负载提供可接受的性能。但是,对于更复杂的工作负载,它会带来正确性和性能方面的挑战:

  • 首先,因为多对象更新不是原子的,所以查询之间没有隔离:如果一个查询需要更新表中的多个对象(例如,在所有表的拼花文件中删除关于一个用户的记录),读者将看到部分更新,因为查询会单独更新每个对象。回滚写操作也很困难:如果更新查询崩溃,则表处于损坏状态。
  • 其次,对于包含数百万对象的大型表,元数据操作的成本很高。例如,Parquet文件包含具有最小/最大统计信息的页脚,这些页脚可用于在选择性查询中跳过读取它们。在HDFS上读取这样的页脚可能需要几毫秒的时间,但是云对象存储的延迟要高得多,因此这些跳过数据的检查可能需要比实际查询更长的时间。

而根据与云客户的合作经验,这些一致性和性能问题给企业数据团队带来了重大挑战。大多数企业数据集是不断更新的,因此它们需要一个原子写入解决方案;大多数关于用户的数据集需要表范围的更新来实现隐私策略,比如GDPR合规性[27];甚至纯粹的内部数据集也可能需要更新以修复不正确的数据、合并延迟的记录等。有趣的是,在Databricks云服务的最初几年(2014-2016),我们收到的支持升级中,大约一半是由于云存储策略导致的数据损坏、一致性或性能问题(例如:撤消崩溃的更新作业的效果,或提高读取数万个对象的查询的性能)。

Delta Lake正是为了解决上述问题而产生的。Delta Lake是一个云对象存储上的ACID表存储层。作者于2017年开始向客户提供Delta Lake服务,并于2019年开放源代码[26]。

Delta-Lake的核心思想很简单:作者用ACID方式在云对象中存储日志,以纪录哪些对象是Delta表的一部分。数据对象本身被编码在Parquet中,这使得从已经可以处理Parquet的引擎中编写连接器变得很容易。这种设计允许客户一次以一种可串行化的方式更新多个对象,用另一个对象替换对象的子集等等,同时仍然从对象本身(类似于原始Parquet)获得高并行读写性能。日志还包含元数据,例如每个数据文件的最小/最大统计信息,使元数据搜索比“对象存储中的文件”方法快一个数量级。此外Delta Lake,将所有元数据都存在底层对象存储中,并且使用针对对象存储的乐观并发协议实现事务(一些细节因云提供商而异)。这意味着不需要运行服务器来维护Delta表的状态;用户只需要在运行查询时启动服务器,就可以享受单独扩展计算和存储的好处。

Delta Lake有许多特性:

  • Time travel
  • UPSERT, DELETE and MERGE operations
  • Efficient streamingI/O
  • Caching
  • Data layout optimization
  • Schema evolution
  • Audit logging

这些特性共同提高了在云对象存储中处理数据的可管理性和性能,并实现了一个结合了数据仓库和数据湖关键特性的“Lakehouse”范例:可直接用于低成本对象存储的标准DBMS管理功能。事实上,许多Databricks客户可以使用Delta Lake简化他们的整体数据体系结构,方法是使用Delta表替换以前单独的数据湖、数据仓库和流式存储系统,为所有这些用例提供适当的功能。

在这里插入图片描述
图1显示了一个极端的示例,其中包含对象存储、消息队列和两个用于不同商业智能团队的数据仓库(每个团队运行自己的计算资源)的数据管道被对象存储上的Delta表所取代,使用Delta的流式I/O和性能特性来运行ETL和BI。新的管道只使用低成本的对象存储,创建的数据副本更少,从而降低了存储成本和维护开销。

这张图中,数据流的终点同为Steaming Analytics, BI Users, Data Scientis,数据的起点也相同,是Change Log和Sensor Data,(a)和(b)图的区别在于数据流动的方式。

在图(a)中需要转成Parquet格式的数据作为“中转”,形成Parquet格式的数据最终流入Data warehouse,以供BI users使用。

图(a)中数据从ETL job1到ETL job2中间需要一个Message Queue进行中转,ETL job1到ETL job3则需要Parquet格式。在图(b)中从ETL job1到ETL job2 , ETL job3只需要一个Delta Lake table 即可。

由此可知使用Delta lake table可以简化数据流动过程,减少了数据格式转换的次数,因而有利于数据分析。

MOTIVATION: CHARACTERISTICS AND CHALLENGES OF OBJECT STORES

相较于现有技术,Delta Lake有以下3个优势:

  • Delta Lake提供了更简单的元数据API
  • 一致性属性
  • 实验性能(吞吐,延迟等)

更简单的元数据API

云对象存储,如Amazon S3[4]和Azure Blob存储[17]、Google云存储[30]和OpenStack Swift[38],提供了元数据API,比如S3的列表操作[41],通常可以在给定开始键的情况下,按键的字典顺序列出bucket中可用的对象。不幸的是,这些元数据API通常时间开销很大:例如,S3的列表每次调用最多只返回1000个键,每次调用需要数千万到数百毫秒,因此使用顺序实现列出包含数百万个对象的数据集可能需要几分钟。

在读取对象时,云对象存储通常支持字节范围请求,因此只读取大对象中的一个范围(例如,字节10000到20000)是有效的。这使得利用通常访问值的集群存储格式成为可能。

更新对象通常需要一次重写整个对象。这些更新可以是原子的,这样读者就可以看到新的对象版本或旧的对象版本。有些系统还支持附加到对象上[48]。

一些云供应商还通过blob存储实现了分布式文件系统接口,比如Azure的ADLS Gen2[18],它的语义与Hadoop的HDFS类似(例如,目录和原子重命名)。尽管如此,许多待解决的问题,例如小文件[36]和跨多个目录的原子更新,仍然存在,作者因此提出Delta Lake。

一致性保证

云对象存储为每个键提供了最终的一致性,并且没有跨键的一致性保证,这给管理由多个对象组成的数据集带来了挑战。尤其是,在客户机上载新对象之后,其他客户机不一定能立即在列表或读取操作中看到该对象。同样,对现有对象的更新可能不会立即对其他客户端可见。此外,根据对象存储的不同,即使是执行写操作的客户机也可能无法立即看到新对象。

确切的一致性模型因云提供商而异,可能相当复杂。作为一个具体的例子,amazons3为编写新对象的客户机提供了读写一致性,这意味着读操作(如S3的GET)将在PUT之后返回对象内容。但是,有一个例外:如果编写对象的客户机在其PUT之前向(不存在的)键发出GET,那么随后的GET可能会在一段时间内不读取对象,很可能是因为S3采用了负缓存。而且,S3的列表操作最终总是一致的,这意味着
PUT后的LIST可能不会返回新对象[40]。其他云对象存储提供了更强的保证[31],但仍然缺乏跨多个键的原子操作。

实验性能

使用对象存储实现高吞吐量需要仔细平衡大型顺序I/O)和并行性。对于读取,可用的最细粒度操作是读取顺序字节范围。每个读取操作通常会产生至少5–10毫秒的基本延迟,然后可以以大约50–100 MB/s的速度读取数据,因此一个操作需要读取至少几百KB的数据,以实现至少一半的连续读取峰值吞吐量,并需要多MB的数据以接近峰值吞吐量。

此外,在典型的VM配置上,应用程序需要并行运行多个读取以最大化吞吐量。例如,在AWS上最常用于分析的VM类型至少有10gbps的网络带宽,因此它们需要运行8-10并行读取以充分利用此带宽。

列表操作还需要显著的并行性才能快速地进行列表操作大型对象集。例如,S3的列表操作每个请求最多只能返回1000个对象,并且需要几十到几百毫秒,因此客户端需要并行地发出数百个列表来列出大的bucket或“目录”。在我们为云计算中的apachespark优化的运行时中,除了驱动程序节点中的线程之外,我们有时还对Spark集群中的工作节点上的列表操作进行并行化,以使它们运行得更快。

在Delta-Lake中,关于可用对象的元数据(包括它们的名称和数据统计信息)存储在Delta日志中,但是我们还通过集群并行地读取这个日志。写操作通常必须替换整个对象(或附加到它)。这意味着,如果希望表接收点更新,那么表中的对象应该保持较小,这与支持较大的读取不一致。或者,可以使用日志结构的存储格式。

表存储意味着:对象存储的性能特征导致分析工作负载需要考虑三个方面:

  1. 将频繁访问的数据按顺序放在附近,这通常会导致选择列格式。
  2. 对象(object)变大,但不要太大。大对象增加了更新数据的成本(例如,删除关于一个用户的所有数据),因为它们必须完全重写。
  3. 避免列表操作,并尽可能使这些操作请求字典键范围。

表格存储的现有方法

基于对象存储的特点,目前主要有三种方法来管理对象存储上的表格数据集,分别是:

  • 文件目录
  • 自定义存储引擎
  • 对象存储中的元数据
文件目录(Directories of Files)

开源大数据栈和许多云服务支持的最常见的方法是将表存储为对象的集合,通常是列存储格式(如Parquet)存储。作为改进,可以基于一个或多个属性将记录“分区”到目录中。

例如,对于带有日期字段的表,我们可以为每个日期创建一个单独的对象目录,例如,将1月1日的数据存在mytable/date=2020-01-01/obj1,将1月2日的数据存在mytable/date=2020-01-01/obj2等等,并基于此字段将传入的数据拆分为多个对象。这样的分区减少了列表操作的开销,并减少了只访问几个分区的查询的读取。

这种方法很有吸引力,因为表“只是一堆对象”,可以从许多工具访问,而无需运行任何额外的数据存储或系统。它起源于HDFS上的apachehive[45],与Parquet、Hive和其他文件系统上的大数据软件配合使用。

这种方法的挑战在于“只是一堆文件”的方法在云对象存储上同时存在性能和一致性问题。客户遇到的最常见挑战是:

  • 跨多个对象没有原子性:任何需要写入或更新多个对象的事务都有可能对其他客户端可见部分写入。此外,如果这样的事务失败,数据将处于损坏状态。
  • 最终一致性:即使事务成功,客户端也可能看到一些更新的对象,但看不到其他对象。
  • 性能差:列出对象以查找与查询相关的对象开销很大,即使它们是按键划分到目录中的。此外,访问存储在Parquet或ORC文件中的每个对象的统计信息是昂贵的,因为它需要对每个特性进行额外的高延迟读取。
  • 无管理功能:对象存储未实现标准实用程序,如数据仓库中熟悉的表版本控制或审核日志。
自定义存储引擎(Custom Storage Engines)

为云构建的“封闭(closed-world)”存储引擎(如Snowflake data warehouse[23])可以绕过云对象存储的许多一致性挑战,其实现方法是在一个单独的、高度一致的服务中管理元数据本身,该服务拥有关于对象组成表的“真实数据来源”。在这些引擎中,云对象存储可以被视为哑块设备(dump block device),并且可以使用标准技术在云对象上实现高效的元数据存储、搜索、更新等。

然而,这种方法需要运行一个高可用性的服务来管理元数据,这可能很开销很大,在使用外部计算引擎查询数据时会增加开销,并且可以将用户锁定到一个提供者中。

这种方法的挑战在于尽管全新的“封闭”设计带来了诸多好处,但我们在使用这种方法时遇到的一些具体挑战是:

  • 表的所有I/O操作都需要联系元数据服务,这会增加其资源成本,降低性能和可用性:例如,当访问Spark中的Snowflake数据集时,从Snowflake的Spark connector读取的数据流通过Snowflake的服务传输,与直接从云对象存储读取数据相比,性能降低。
  • 现有计算引擎的连接器需要更多的工程工作来实现,而不是重用现有开放格式(如Parquet)的方法:数据团队希望在他们的数据上使用各种各样的计算引擎(例如Spark、TensorFlow、PyTorch等),因此使连接器易于实现非常重要。
  • 专有元数据服务将用户与特定的服务提供商联系起来,而基于云存储中直接访问对象的方法使用户能够始终使用不同的技术访问其数据。
    ApacheHiveAcid[32]通过使用HiveMetaStore(一种事务存储库)在HDFS或对象存储上实现了类似的方法
    RDBMS(如MySQL)来跟踪多个文件,这些文件保存以ORC格式存储的表的更新。但是,这种方法受到元存储(metastore)性能的限制,在我们的经验中,元存储可能成为具有数百万对象的表的瓶颈。
对象存储中的元数据(Metadata in Object Stores)

DeltaLake的方法是将事务日志和元数据直接存储在云对象存储中,并在对象存储操作上使用一组协议来实现序列化。然后,表格中的数据以Parquet格式存储,这样就可以方便地从任何已经支持Parquet的软件访问,只要有一个最小的连接器来发现要读取的对象集。尽管我们相信Delta Lake是第一个使用这种设计的系统(从2016年开始),另外两个软件包现在也支持它——ApacheHudi[8]和ApacheIceberg[10]。Delta-Lake提供了许多这些系统不支持的独特功能,例如Z顺序集群、缓存和后台优化。在论文的第8节会更详细地讨论这些系统之间的异同。

Delat Lake调研总篇

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值