什么是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 可以按照年、月、日和小时粒度划分时间戳。
它还可以使用分类列(如本日志示例中的 level)将行存储在一起并加快查询速度。
Iceberg 有什么不同之处?
其他表格式(如 Hive)支持分区,但是 Iceberg 支持隐藏分区。
- Iceberg 处理为表中的行生成分区值的繁琐且容易出错的任务。
- Iceberg 自动避免读取不必要的分区。 消费者不需要知道表是如何分区的,也不需要在查询中添加额外的过滤条件。
- Iceberg分区布局可以根据需要进行调整。
Hive中分区
为了演示这种差异,请考虑 Hive 将如何处理日志表。
在 Hive 中,分区是显式的,并且以列的形式出现,因此日志表有一个称为事件日期的列。写入时,插入操作需要为事件日期列提供数据:
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不能验证分区值-这取决于writer生成正确的值
- 使用错误的格式,2018-12-01而不是20181201,会产生错误结果,而不是查询失败
- 使用错误的源列(如处理时间或时区)也会导致不正确的结果,而不是失败
取决于用户是否正确地编写查询
- 使用错误的格式也会导致错误结果
- 不理解表的物理布局的用户会得到不必要的慢查询—— Hive 不能自动转换过滤器
正在执行的查询与表的分区方案绑定在一起,因此不能在不中断查询的情况下更改分区配置
Iceberg的隐藏分区
Iceberg 通过获取列值并可选地转换列值来生成分区值。Iceberg 负责将事件时间转换为事件日期,并跟踪关系。
使用这些关系配置表分区。日志表将按date(event_time)和level进行分区。
因为 Iceberg 不需要用户维护的分区列,所以它可以隐藏分区。每次都能正确生成分区值,并且总是用于加速查询(如果可能的话)。
生产者和消费者甚至看不到event_date。
最重要的是,查询不再依赖于表的物理布局。
通过物理和逻辑之间的分离,随着数据量的变化,Iceberg 表可以随时间演变分区方案。
可以修复配置错误的表,而无需进行昂贵的迁移。
上一篇: wpf无边框窗体移动和大小调整
下一篇: iceberg flink 读操作