随着过去几年数据量呈指数级增长,最大的挑战之一是找到存储各种数据类型的最佳方式。与过去不同,当关系数据库被认为是唯一的出路时,组织现在希望对原始数据进行分析——想想社交媒体情绪分析、音频/视频文件等等——这通常不能以传统(关系)方式存储,或者以传统方式存储它们需要大量的精力和时间,这会增加整体分析时间。
另一个挑战是以某种方式坚持使用传统方法以结构化方式存储数据,但无需设计复杂且耗时的 ETL 工作负载来将这些数据移动到企业数据仓库中。此外,如果组织中一半的数据专业人员精通 Python(数据科学家、数据工程师),而另一半(数据工程师、数据分析师)精通 SQL,那会怎样?你会坚持让“Pythonists”学习 SQL 吗?或相反亦然?
顺便说一下,如果你想了解如何使用 Azure Synapse Analytics 从 Parquet 文件中查询数据[1],我会为你提供帮助。
Parquet 文件格式简而言之!
在我展示 Parquet 文件格式的来龙去脉之前,有(至少)五个主要原因可以说明为什么 Parquet 现在被认为是存储数据的实际标准:
-
• 数据压缩——通过应用各种编码和压缩算法,Parquet 文件减少了内存消耗
-
• 列式存储——这在分析工作负载中至关重要,其中快速数据读取操作是关键要求。
-
• 与语言无关——如前所述,开发人员可能使用不同的编程语言来操作 Parquet 文件中的数据
-
• 开源格式——意思是不会被特定的供应商锁定
-
• 支持复杂数据类型
行存储 vs. 列存储
我们已经提到 Parquet 是一种基于列的存储格式。然而要了解使用 Parquet 文件格式的好处,我们首先需要在基于行和基于列的数据存储方式之间划清界线。
在传统的基于行的存储中,数据存储为一系列行。是这样的:
现在当我们谈论 OLAP[2] 场景时,用户可能会问的一些常见问题是:
-
• 我们卖了多少球?
-
• 有多少美国用户购买了 T 恤?
-
• 客户 Maria Adams 的总花费是多少?
-
• 1 月 2 日我们有多少销售额?
为了能够回答这些问题中的任何一个,引擎必须从头到尾扫描每一行。因此,要回答这个问题:有多少美国用户购买了 T 恤,引擎必须执行如下操作:
本质上我们只需要来自两列的信息:产品(T 恤)和国家/地区(美国),但引擎将扫描所有五列。这不是最有效的解决方案。
列存储
现在让我们检查列存储的工作原理。正如你可能假设的那样,方法是 180 度不同的:
在这种情况下,每一列都是一个单独的实体——也就是说每一列在物理上与其他列分开。回到我们之前的业务问题:引擎现在可以只扫描查询所需的那些列(产品和国家/地区),同时跳过扫描不必要的列。而且在大多数情况下,这应该会提高分析查询的性能。
Parquet 是一种列式格式,将数据存储在行组中
让我们回到之前的示例,描述 Parquet 将如何存储相同的数据块:
让我们停下来解释一下上面的插图,因为这正是 Parquet 文件的结构(有意省略了一些额外的东西,但我们很快也会解释)。列仍然作为单独的单元存储,但 Parquet 引入了额外的结构,称为行组。
为什么这个额外的结构非常重要?
在OLAP场景中,我们主要关注两个概念:projection和predicate(s)。投影是指 SQL 语言中的 SELECT 语句——查询需要哪些列。回到我们之前的示例,我们只需要 Product 和 Country 列,因此引擎可以跳过扫描其余列。
谓词指的是 SQL 语言中的 WHERE 子句——哪些行满足查询中定义的条件。在我们的例子中,我们只对 T 恤感兴趣,因此引擎可以完全跳过扫描行组 2,其中产品列中的所有值都等于袜子。
让我们在这里快速停下来,了解引擎需要执行的工作方面各种类型的存储之间的区别:
-
• 行存储——引擎需要扫描所有 5 列和所有 6 行
-
• 列存储——引擎需要扫描 2 列和所有 6 行
-
• 带行组的列存储——引擎需要扫描 2 列和 4 行
显然这是一个过于简化的示例,只有 6 行和 5 列,因此看不到这三种存储选项之间的性能差异。然而在现实生活中,当处理大量数据时,差异会变得更加明显。
现在问题是:Parquet 如何“知道”要跳过/扫描哪个行组?
Parquet 文件包含元数据
这意味着,每个 Parquet 文件都包含“关于数据的数据”——例如特定行组中特定列的最小值和最大值等信息。此外,每个 Parquet 文件都包含一个页脚,其中保存了有关格式版本、模式信息、列元数据等的信息。可以在此处[3]找到有关 Parquet 元数据类型的更多详细信息。
重要提示:为了优化性能并消除不必要的数据结构(行组和列),引擎首先需要“熟悉”数据,因此它首先读取元数据。这不是一个缓慢的操作,但它仍然需要一定的时间。因此如果从多个小的 Parquet 文件中查询数据,查询性能可能会降低,因为引擎必须从每个文件中读取元数据。因此最好将多个较小的文件合并为一个较大的文件(但仍然不要太大)
什么是“小”,什么是“大”?不幸的是,这里没有单一的“黄金”数字,但是例如,Microsoft Azure Synapse Analytics 建议单个 Parquet 文件的大小至少应为几百 MB[4]。
还有什么?
这是 Parquet 文件格式的简化、高级说明:
数据压缩
我们已经解释了跳过不必要的数据结构(行组和列)的扫描如何使查询受益并提高整体性能。但是不仅如此——还记得我在一开始就告诉过你 Parquet 格式的主要优势之一是减少文件的内存占用吗?这是通过应用各种压缩算法来实现的。
我已经在此处[5]撰写了有关 Power BI(以及一般的表格模型)中的各种数据压缩类型的文章。
有两种主要的编码类型使 Parquet 能够压缩数据并实现惊人的空间节省:
-
• 字典编码——Parquet 创建列中不同值的字典,然后用字典中的索引值替换“真实”值。回到我们的例子,这个过程看起来像这样。当产品名称很短时,为什么会有这种开销?假设存储了产品的详细描述,例如:“脖子上有应用的长臂 T 恤”。而且,现在想象一下,产品已售出百万次。Parquet 将仅存储索引值(整数而不是文本),而不是具有百万次重复值“Long arm …bla bla”。
-
• Run-Length-Encoding with Bit-Packing——当数据包含许多重复值时,Run-Length-Encoding (RLE) 算法可能会带来额外的内存节省。
Delta Lake文件格式
简单来说:Delta Lake 主要是 Parquet 文件的版本控制。它还存储事务日志,以便跟踪应用于 Parquet 文件的所有更改。这也称为符合 ACID 的事务。
由于它不仅支持 ACID 事务,还支持时间旅行(回滚、审计跟踪等)和 DML(数据操作语言)语句,如 INSERT、UPDATE 和 DELETE,所以如果你想到 Delta Lake 作为“数据湖上的数据仓库”(Lakehouse)
结论
我们在进化,数据也在进化。因此新类型的数据需要新的存储方式。Parquet 文件格式是当前数据领域中最有效的存储选项之一,因为它提供了多种好处——在内存消耗方面,通过利用各种压缩算法,以及通过使引擎跳过扫描不必要的数据来快速查询处理。
引用链接
[1]
如何使用 Azure Synapse Analytics 从 Parquet 文件中查询数据: [https://data-mozart.com/mastering-dp-500-synapse-serverless-sql-and-file-types-the-ultimate-guide/](https://data-mozart.com/mastering-dp-500-synapse-serverless-sql-and-file-types-the-ultimate-guide/)[2]
OLAP: [https://www.ibm.com/cloud/blog/olap-vs-oltp](https://www.ibm.com/cloud/blog/olap-vs-oltp)[3]
此处: [https://parquet.apache.org/docs/file-format/metadata/](https://parquet.apache.org/docs/file-format/metadata/)[4]
Microsoft Azure Synapse Analytics 建议单个 Parquet 文件的大小至少应为几百 MB: [https://www.youtube.com/watch?v=RxjMibOx__A](https://www.youtube.com/watch?v=RxjMibOx__A)[5]
此处: [https://data-mozart.com/inside-vertipaq-compress-for-success/](https://data-mozart.com/inside-vertipaq-compress-for-success/)
原文始发于微信公众号(漫谈大数据):Parquet 文件格式:你需要知道的一切
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/159614.html