关于数据库:Delta-Lake基础介绍商业版

47次阅读

共计 3919 个字符,预计需要花费 10 分钟才能阅读完成。

简介:介绍 Lakehouse 搜索引擎的设计思维,探讨其如何应用缓存,辅助数据结构,存储格局,动静文件剪枝,以及 vectorized execution 达到优越的解决性能。

作者:李洁杏,Databrick 资深软件工程师

一、Lakehouse 搜索引擎设计背景

1. 数据仓库和 Lakehouse

数据管理系统从晚期的数据仓库(Data Warehouse),曾经倒退到明天的 Lakehouse。Lakehouse 能够同时存储结构化、半结构化和非结构化数据,并且反对流剖析、BI、数据迷信和机器剖析的场景。

2. Lakehouse 在查问性能上的挑战

数据仓库架构能够齐全控制数据的存储和查问,因而能够同时设计查问零碎,以及适应查问零碎的数据存储构造,以达到优越的查问性能;

而在 Lakehouse 架构下,数据是用凋谢存储构造存储的,如 Parquet 格局,以便更多零碎能够便捷的拜访数据,然而凋谢的存储格局并不一定适宜查问操作,查问零碎也没有足够的统计数据来实现高效查问。

那么,Lakehouse 如何以凋谢的存储格局达到高效的查问性能?

3. 解决方案

为解决以上的问题,Databricks Lakehouse 设计了新的搜索引擎,其 SQL 性能在 Data Lake 存储系统和文件格式方面都有杰出的体现。

其 SQL 性能优化是通过以下技术实现的:

a. 高速缓存:将热数据放入高速缓存中;

b. 建设辅助数据结构:如收集统计数据、建设索引;

c. 数据布局优化:以实现最小化 I /O;

d. 动静文件剪枝:以实现最小化 I /O。

二、Lakehouse 中的 SQL 性能优化技术

1. 高速缓存

大部分的工作负载,个别都会集中拜访某些“热”数据上,Data Warehouse 常常应用 SSD 和内存作为缓存来减速热数据的查问。

Lakehouse 能够应用与数据仓库雷同的优化数据结构对其进行缓存,进步查问性能。

如图所示,在 Databricks 中用 SSD 作为缓存,能够将数据读取速度进步 3 倍以上;采纳 Delta 引擎作为缓存,则能够将数据读取速度进步 7 倍以上。

2. 建设辅助数据结构

即便数据是用 Parquet 格局存储的,也能够建设很多额定的数据结构来放慢查问,同时对这些额定的数据进行事务性的保护。

示例一:Parquet 文件中的 Data Skipping

在 Parquet 文件中,保护表中每个数据文件的最小 / 最大值统计信息,有助于在查问产生时能够跳过一些无关的数据。

如下图,如果查问条件是 year=2020 和 uid=24000,利用最小 / 最大统计信息,可知这个查问的信息只会存在于 file3,因而能够跳过 file1 和 file2 的读取。

示例二:在 Parquet 文件上建设索引

如下图,如果查问条件是 type=“DELETE_ACCOUT”,能够利用在 type 上建设的索引间接跳到对应的数据上,从而防止读取无关数据。

示例三:Parquet 文件上建设 Bloom Filter

能够为每一个文件建设 Bloom Filter,Bloom Filter 能够疾速判断表文件中是否蕴含须要查问的数据,如果不蕴含则疾速跳过该文件,从而缩小扫描数据量,晋升查问性能。

Bloom Filter 原理:

Bloom Filter 对每个文件中的数据记录应用 1 个或多个哈希表计算其哈希值,其起始值都为 0,当有哈希值映射在对应的地位时则为 1,这样在查问的时候,能够跳过值为 0 的地位;也有可能的状况是,对应的位全副都为 1,这时候数据也有可能不在这个文件中(假阳性),能够通过管制应用哈希函数的个数以及 Bloom Filter 的大小,来管制假阳性率。

3. 数据布局

a. 小文件问题

在 Delta Lake 中频繁执行 MERGE,UPDATE,INSERT 操作,可能会产生大量的小文件。大量的小文件,一方面会升高零碎读取性能,同时也会进步元数据操作的开销。

Lakehouse 中应用了不同的技术来缩小小文件的产生:

  • 优化 Delta 表写入

如下图所示,在开源版 Spark 中,每个 executor 向 partition 中写入数据时,都会创立一个表文件进行写入,最终会导致一个 partition 中产生很多的小文件。

Databricks 对 Delta 表的写入过程进行了优化,对每个 partition 应用一个专门的 executor 来合并其它 executor 对该 partition 的写入,从而防止了小文件的产生。

  • 主动合并小文件

在每次向 Delta 表中写入数据之后,会查看 Delta 表中的表文件数量,如果 Delta 表中的小文件(size < 128MB 则视为小文件)数量达到阈值,则会执行一次小文件合并,将 Delta 表中的小文件合并为一个新的大文件。

  • 手动合并小文件

除了主动合并,Databricks 还提供 Opitmize 命令,使用户能够手动合并小文件,优化表构造,使得表文件的构造更加紧凑。

b. 查问工夫问题

查问运行工夫次要取决于拜访的数据量,即便应用 Parquet 格局,也能够通过优化表内的数据布局以缩小运行工夫。

  • 表文件数据排序

将表文件存储数据排序,在每个表文件中存储一定量的数据,如下图中 file1 存储 uid=0…1000,file2 存储 uid=1001…2000,这样在查问时就能够依据须要跳过无关的表文件,缩小文件扫描数量。

  • Z-Ordering 优化

在理论查问中,有些查问须要看 colomn1 在某个范畴内的数据,有些查问须要看 colomn2 在某个范畴内的数据,或者更多,这时候仅仅对 colomn1 进行排序显然是不够的。

Z-Ordering 能够在多个维度上(如下图的 col 1-4)将关联的信息存储到同一组文件中,来缩小不必要的文件读取。

4. 动静文件剪枝(Dynamic File Pruning,DFP)

动静文件剪枝简称 DFP,咱们以上面一个简略的查问为例:

SELECT sum(ss_quantity) 
FROM store_sales 
JOIN item ON ss_item_sk = i_item_sk 
WHERE i_item_id =‘AAAAAAAAICAAAAAA'

查问阐明:将 store_sales 与 item 两个表连起来,条件是当 item_sk 值相等且 item_id 等于一个固定值。


未启用 DFP

如果不开启 DFP,从上图能够看出,查问会先对 store_sales 进行全表扫描,而后再和过滤后的 item 表的行进行 join,尽管后果仅有 4.6 万多条数据,但却扫描了表 store_sales 中的 86 多亿条数据。


启用 DFP

在启用 DFP 之后,会先扫描 item 表,查问出表 item 中 i_item_id =‘AAAAAAAAICAAAAAA’ 数据行,而后将这些数据行的 i_item_sk 值作为表 store_sales 的 ss_item_sk 的查问条件,在表 store_sales 的 SCAN 阶段进行过滤,跳过大量无关数据。这样仅扫描了 660 多万条 store_sales 中的数据,比未启用 DFP 时缩小了近 99%。

从后果上看,启动 DFP 后,该条查问实现了 10 倍的性能晋升。

针对该个性在 TPC-DS 上进行测试(见下图),测试发现启用 DFP 后,TPC-DS 的查问速度达到 4.5 倍到 8 倍的晋升。

5. 优化组合

综合应用以上优化技术协同工作,让 Lakehouse 中的数据读取都在高速缓存中进行,并且通过数据布局优化,建设辅助数据结构缩小对非缓存数据读取的 I /O,实现了 Lakehouse 引擎能够提供与数据仓库相似的查问性能。

如下图所示,Delta Engine 的查问性能与 DW1 相似,并且超过了 DW2 和 DW3。

三、Delta Clones

Delta Clones 是 Lakehouse 的一项十分重要的技术,能够对大型数据集进行高效拷贝,反对测试、分享和机器学习的不同需要。

1. 什么是克隆?

克隆也叫拷贝,是原始数据在给定工夫点的正本;

它具备与源表雷同的元数据:雷同表构造,束缚,列形容,统计信息和分区;

两种克隆形式:shallow(浅克隆),deep(深克隆)。

2. 深克隆

深克隆会残缺复制源表的元数据和数据文件,并生成一个全新的独立的表。

a. 深克隆语句

在 SQL 中运行 CREATE TABLE 语句;在 Python 和 Scala 语句中运行 DeltaTable 语句。

# SQL 
CREATE TABLE delta.`path/to/copy` CLONE customers
# Python and Scala
DeltaTable
.forName("park", "customers")
.clone("path/to/copy")

b. 深克隆的个性

与源表相比,克隆表有独立的历史记录;
在克隆过程中、或之后产生的对源表的任何更改,都不会反映在克隆表中;

3. 浅克隆

浅克隆仅复制须要克隆的表的元数据,表自身的数据文件不会被复制。

a. 浅克隆语句

与深克隆语句相似,只是在 SQL 中退出 SHALLOW CLONE 语句;在 Python 和 Scala 中退出 isShallow=true。

# SQL 
CREATE TABLE delta.`path/to/copy` SHALLOW CLONE customers
# Python and Scala 
DeltaTable 
.forName("spark", "customers") 
.clone("path/to/copy", isShallow=true)

b. 浅克隆的个性

浅克隆不是自蕴含的,即本身不是数据源,如果源文件数据被删除,则浅克隆数据可能会不可用;
浅克隆不复制流事务或 COPY INTO 相干的元数据;

4. 克隆的实用场景

克隆的实用场景有很多,比方:数据存储、短期试验、数据分享和劫难复原,其中除了短期试验应用浅克隆,其它场景都须要应用深克隆。

原文链接
本文为阿里云原创内容,未经容许不得转载。

正文完
 0