Iceberg从入门到精通系列之十九:分区

Iceberg从入门到精通系列之十九:分区

  • 一、认识分区
  • 二、Iceberg的分区
  • 三、Hive 中的分区
  • 四、Hive 分区问题
  • 五、Iceberg的隐藏分区
  • 六、分区变换
  • 七、分区变换

一、认识分区

分区是一种通过在写入时将相似的行分组在一起来加快查询速度的方法。

例如,从日志表中查询日志条目通常会包含一个时间范围,就像针对上午 10 点到 12 点之间的日志的查询一样:

SELECT level, message FROM logs
WHERE event_time BETWEEN '2018-12-01 10:00:00' AND '2018-12-01 12:00:00'

将日志表配置为按 event_time 日期分区会将日志事件分组到具有相同事件日期的文件中。 Iceberg 会跟踪该日期,并使用它来跳过没有有用数据的其他日期的文件。

Iceberg 可以按年、月、日和小时粒度对时间戳进行分区。它还可以使用分类列(如本日志示例中的级别)将行存储在一起并加快查询速度。

二、Iceberg的分区

其他表格式(如 Hive)支持分区,但 Iceberg 支持隐藏分区。

  • Iceberg 处理为表中的行生成分区值这一繁琐且容易出错的任务。
  • Iceberg 避免自动读取不必要的分区。消费者不需要知道表是如何分区的,也不需要在查询中添加额外的过滤器。
  • Iceberg分区布局可以根据需要演变。

三、Hive 中的分区

为了演示差异,请考虑 Hive 如何处理日志表。

在 Hive 中,分区是显式的并显示为一列,因此日志表将有一个名为 event_date 的列。写入时,插入需要为 event_date 列提供数据:

INSERT INTO logs PARTITION (event_date)SELECT level, message, event_time, format_time(event_time, 'YYYY-MM-dd')FROM unstructured_log_source

同样,搜索日志表的查询除了 event_time 过滤器之外还必须具有 event_date 过滤器。

SELECT level, count(1) as count FROM logs
WHERE event_time BETWEEN '2018-12-01 10:00:00' AND '2018-12-01 12:00:00'AND event_date = '2018-12-01'

如果 event_date 过滤器丢失,Hive 将扫描表中的每个文件,因为它不知道 event_time 列与 event_date 列相关。

四、Hive 分区问题

必须为 Hive 指定分区值。在日志示例中,它不知道 event_time 和 event_date 之间的关系。

这会导致几个问题:

  • Hive 无法验证分区值 - 由编写者来生成正确的值
    • 使用错误的格式(2018-12-01 而不是 20181201)会默默产生错误结果,而不是查询失败
    • 使用错误的源列(例如处理时间或时区)也会导致错误的结果,而不是失败
  • 由用户决定是否正确编写查询
    • 使用错误的格式也会导致无提示的错误结果
    • 不了解表的物理布局的用户会获得不必要的缓慢查询 – Hive 无法自动翻译过滤器
  • 工作查询与表的分区方案相关联,因此在不破坏查询的情况下无法更改分区配置

五、Iceberg的隐藏分区

Iceberg 通过获取列值并选择性地对其进行转换来生成分区值。 Iceberg 负责将 event_time 转换为 event_date,并跟踪这种关系。

表分区是使用这些关系配置的。日志表将按日期(事件时间)和级别进行分区。

因为 Iceberg 不需要用户维护分区列,所以它可以隐藏分区。每次都会正确生成分区值,并且在可能的情况下始终用于加快查询速度。生产者和消费者甚至看不到 event_date。

最重要的是,查询不再依赖于表的物理布局。通过物理和逻辑的分离,Iceberg 表可以随着数据量的变化而不断演变分区方案。错误配置的表无需进行昂贵的迁移即可修复。

六、分区变换

数据文件存储在带有分区值元组的清单中,这些分区值在扫描中用于过滤掉不能包含与扫描过滤谓词匹配的记录的文件。对于数据文件中存储的所有记录,数据文件的分区值必须相同。 (清单存储来自任何分区的数据文件,只要数据文件的分区规范相同。)

表配置有分区规范,该规范定义如何从记录生成分区值元组。分区规范有一个字段列表,其中包括:

  • 表架构中的源列 ID
  • 分区字段id,用于标识分区字段,在分区规范中是唯一的。在 v2 表元数据中,它在所有分区规范中都是唯一的。
  • 应用于源列以生成分区值的转换
  • 分区名称

由 id 选择的源列必须是原始类型,并且不能包含在映射或列表中,但可以嵌套在结构中。

分区规范捕获从表数据到分区值的转换。除了转换数据值之外,这还用于将谓词转换为分区谓词。从表数据上的列谓词派生分区谓词用于将逻辑查询与物理存储分开:分区可以更改,并且始终从列谓词派生出正确的分区过滤器。这简化了查询,因为用户不必同时提供逻辑谓词和分区谓词。

分区变换

变换名称描述源类型结果类型
identity源值,未修改Any源类型
bucket[N]哈希值,mod N(见下文)int, long, decimal, date, time, timestamp, timestamptz, string, uuid, fixed, binaryint
truncate[W]值被截断为宽度 W(见下文)int, long, decimal, string源类型
year提取日期或时间戳年份,即从 1970 年开始的年份date, timestamp, timestamptzint
month提取日期或时间戳月份,如 1970-01-01 以来的月份date, timestamp, timestamptzint
day提取日期或时间戳日,如 1970-01-01 以来的天数date, timestamp, timestamptzint
hour提取时间戳小时,即从 1970-01-01 00:00:00 开始的小时数timestamp, timestamptzint
void总是产生 nullAny源类型或 int

对于 null 输入值,所有转换都必须返回 null。

void 变换可用于替换现有分区字段中的变换,以便该字段在 v1 表中有效删除。

七、分区变换

Iceberg 表分区可以在现有表中更新,因为查询不直接引用分区值。

当您改进分区规范时,使用早期规范写入的旧数据保持不变。新数据是在新布局中使用新规范写入的。每个分区版本的元数据单独保存。因此,当您开始编写查询时,您会得到分割计划。这是每个分区布局使用为该特定分区布局派生的过滤器单独规划文件的地方。这是一个人为示例的直观表示:

在这里插入图片描述
2008 年的数据按月划分。从 2009 年开始,该表进行了更新,数据改为按天分区。两种分区布局都可以在同一个表中共存。

Iceberg 使用隐藏分区,因此您无需为特定分区布局编写查询即可快速运行。相反,您可以编写查询来选择所需的数据,Iceberg 会自动删除不包含匹配数据的文件。

分区演化是元数据操作,不会急切地重写文件。

Iceberg 的 Java 表 API 提供了 updateSpec API 来更新分区规范。例如,以下代码可用于更新分区规范,以添加一个新的分区字段,将 id 列值放入 8 个存储桶中,并删除现有的分区字段类别:

Table sampleTable = ...;
sampleTable.updateSpec().addField(bucket("id", 8)).removeField("category").commit();

Spark 支持通过其 ALTER TABLE SQL 语句更新分区规范。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/327086.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络知识-以太网技术的发展及网络设备

目 录 一、背景介绍 (一)网络技术的时代 (二)以太网技术脱颖而出 二、以太网的工作原理 (一)、载波侦听多路访问(CSMA/CD) 1、数据发送流程 2、发送过程解析 3、…

Allegro如何进行四层板板层设计

Allegro如何进行四层板板层设计 板层设计说明 在进行多层板设计时我们画好PCB板框后,都要进行板层的设计。这里就以最简单的4层板为例为大家举例说明。 板层设置 点击“Setup”->“Cross Section Editor”如下图所示: 也可以直接点击工具栏进入…

手写视频裁剪框

<!-- 截取框 --><divv-show"isShow"class"crop-box":style"{width: cropWidth px,height: cropHeight px,left: cropX px,top: cropY px,}"ref"cropBox"mousedown"startInteraction"><!-- 内容在这里 --…

数据库选择题 (期末复习)

数据库第一章 概论简答题 数据库第二章 关系数据库简答题 数据库第三章 SQL简答题 数据库第四第五章 安全性和完整性简答题 数据库第七章 数据库设计简答题 数据库第九章 查询处理和优化简答题 数据库第十第十一章 恢复和并发简答题 2015期末 1、在数据库中&#xff0c;下列说…

分布式(6)

目录 26.雪花算法如何实现的&#xff1f; 27.雪花算法有什么问题&#xff1f;有哪些解决思路&#xff1f; 28.有哪些方案实现分布式锁&#xff1f; 29.基于数据库如何实现分布式锁&#xff1f;有什么缺陷&#xff1f; 30.基于Redis如何实现分布式锁&#xff1f;有什么缺陷&…

Unix操作系统的前世今生

Unix是一种多用户、多任务操作系统&#xff0c;最初由AT&T贝尔实验室的肯汤普逊&#xff08;Ken Thompson&#xff09;和丹尼斯里奇&#xff08;Dennis Ritchie&#xff09;等人开发于上世纪70年代初。它被设计成一种通用的操作系统&#xff0c;支持跨多种硬件平台&#xf…

吉时利2601A数字源表Keithley 2601A

吉时利2601A源测量单元&#xff08;SMU&#xff09;&#xff0c;也被称为源表&#xff0c;是一种高性能的仪器&#xff0c;能够提供100毫伏至40伏的电压范围&#xff0c;以及100纳至10安的电流范围。这种仪器能够提供的功率高达40.4瓦&#xff0c;使其在台式I-V表征工具或多通道…

C语言学习NO.11-字符函数strlen,strlen函数的使用,与三种strlen函数的模拟实现

&#xff08;一&#xff09;strlen函数的使用 strlen函数的演示 #include <stdio.h> #include <string.h>int main() {char arr1[] "abcdef";char arr2[] "good";printf("arr1 %d,arr2 %d",strlen(arr1),strlen(arr2));return …

Linux第11步_解决“挂载后的U盘出现中文乱码”

学习完“通过终端挂载和卸载U盘”&#xff0c;我们发现U盘下的中文文件名会出现乱码&#xff0c;现在讲解怎么解决这个问题。其实就是复习一下“通过终端挂载和卸载U盘”&#xff0c;单独讲解&#xff0c;是为了解决问题&#xff0c;一次性搞好&#xff0c;我们会不长记性。 在…

手势识别+人脸识别+姿态估计(关键点检测+教程+代码)

手势识别和手势关键点检测是计算机视觉领域中的一个重要研究方向,涉及到从图像或视频中检测人手的位置和姿态信息,并推断出手势的意义。以下是一些可能用到的方法和技术: 手势识别 基于深度学习的手势识别 基于深度学习的手势识别是目前最流行的方法之一。它通常使用卷积神…

Zookeeper注册中心实战

Java学习手册面试指南&#xff1a;https://javaxiaobear.cn Spring Cloud Zookeeper通过自动配置和绑定到 Spring 环境和其他 Spring 编程模型习惯用法&#xff0c;为 Spring Boot 应用程序提供Apache Zookeeper集成。通过一些简单的注释&#xff0c;您可以快速启用和配置应用…