当前位置: 首页 > article >正文

Apache Iceberg 概述

Apache Iceberg概述

在这里插入图片描述

一、what is Apache Iceberg?

为了解决数据存储和计算引擎之间的适配的问题,Netflix开发了Iceberg,2018年11月16日进入Apache孵化器,2020 年5月19日从孵化器毕业,成为Apache的顶级项目。
在这里插入图片描述

Apache Iceberg is an open table format for huge analytic datasets.Apache Iceberg 是一种适用于大型分析数据集的开放表格式。

表格式(Table Format)可以理解为元数据以及数据文件的一种组织方式,处于计算框架(Flink,Spark…)之下,数据文件之上。

在这里插入图片描述

A good way to define a table format is a way to organize a dataset’s files to present them as a single “table”.
在这里插入图片描述

Iceberg 使用高性能表格式将表添加到计算引擎中,包括 Spark、Trino、PrestoDB、Flink、Hive 和 Impala,其工作方式与 SQL 表类似。


二、Apache Iceberg核心特性

2.1 数据存储、计算引擎插件化(解耦)

  • Apache Iceberg 作为一种开放的表格式,允许用户灵活地选择数据存储和计算引擎

在这里插入图片描述

  • 它与具体的存储解决方案(如 HDFS、Amazon S3)和计算引擎(如 Apache Spark、Apache Flink)解耦,使得用户能够根据需求随时调整架构
    在这里插入图片描述

  • 例如,在一个数据分析平台中,用户可以将数据存储在 Amazon S3 中,并使用 Apache Spark 来进行批量分析,同时也能接入 Apache Flink 进行实时流处理,无需更改数据格式。


2.2 实时流批一体

  • Iceberg 支持同时处理流数据和批数据,提供统一的读写接口。
  • 可以在同一个数据管道中混合处理实时流数据(如 IoT 设备产生的数据)和历史批数据(如日志文件)。
  • 例如,一个电商平台可以使用 Iceberg 接收实时的交易数据流,并同时执行对历史订单数据的分析,以生成实时销售报告和库存监控,简化 ETL 过程,减少数据延迟。

2.3 数据表演化(Table Evolution)

  • Apache Iceberg 提供了一种高效的方式来进行表级别的模式演进,使得用户能够灵活地修改表的结构而不需要耗费大量时间和资源

  • 这种模式演进通过简单的 SQL 操作实现,避免了繁琐的数据迁移和重写过程

  1. 低代价的操作:在 Iceberg 中,模式演进几乎不需要重写数据。当用户需要对表的结构进行修改(如添加、删除列或更改列的数据类型)时,只需执行相应的 SQL 命令,Iceberg 会在后台自动处理相关的元数据更新,而不需要将现有数据读取出来再写入
    在这里插入图片描述
  2. 无缝集成:与传统的 Hive 表相比,Iceberg 允许用户在不影响现有查询的情况下进行修改。例如,用户可以在保留原有数据的基础上,逐步演进到新的数据模型

假设一个在线零售平台的订单表最初按天分区

CREATE TABLE orders (
    order_id BIGINT,
    customer_id BIGINT,
    order_date DATE,
    amount DECIMAL(10, 2)
) PARTITIONED BY (order_date);

如果业务需求发生变化,需要将表的分区方式改为按小时分区。在传统的 Hive 中,这通常需要创建新表并将数据插入其中:

  1. 创建新表:
CREATE TABLE orders_hourly (
    order_id BIGINT,
    customer_id BIGINT,
    order_date DATE,
    order_hour INT,
    amount DECIMAL(10, 2)
) PARTITIONED BY (order_date, order_hour);//按小时分区
  1. 将旧表数据迁移到新表:
INSERT INTO orders_hourly
SELECT order_id, customer_id, order_date, HOUR(order_date) as order_hour, amount
FROM orders;
  1. 然后重命名新表以替换旧表,这可能影响其他依赖于旧表的查询。

而在 Iceberg 中,用户只需执行以下 SQL 操作:

ALTER TABLE orders ADD COLUMN order_hour INT;
ALTER TABLE orders SET PARTITIONED BY (order_date, order_hour);

Iceberg 会在不影响现有数据的情况下处理分区的变更,原有的数据仍然可以通过新的查询访问。这样,整个演进过程变得简单、快速且高效,大大降低了操作复杂性和风险。

数据架构的演进变得灵活和高效,企业可以更快速地响应业务需求的变化,保持数据模型的现代化。这种无缝的演进能力是许多企业在进行数据管理和分析时所期望的。


2.4 模式演化(Schema Evolution)

Iceberg 的模式演化设计提供了一种灵活、安全的方式来管理表结构,确保在修改表时不会影响现有数据或引入潜在的错误。

在这里插入图片描述

  1. ADD:通过增加新列,用户可以轻松扩展表的结构,例如添加新特性而不干扰现有数据。

  2. DROP:移除不再需要的列,确保数据模型的整洁,且不影响其他列的内容。

  3. RENAME:重命名列有助于提升可读性或反映业务变化,Iceberg 保证其他列的数据不会受到影响。

  4. UPDATE:对复杂结构的基本类型进行扩展,如从 tinyint 更新为 int,支持更大的数据范围,而无需重写数据。

  5. REORDER:改变列的排列顺序,使数据结构更符合用户需求,同时保持数据完整性。

在这里插入图片描述
Iceberg 使用唯一ID来定位列,从而避免因名称重复或位置依赖引发的问题,这一设计增强了模式演化的灵活性和可靠性。

在这里插入图片描述
使用名称或者位置信息来定位列的, 都会存在一些问题, 比如使用名称的话,名称可能会重复, 使用位置的话, 不能修改顺序并且废弃的字段也不能删除。


2.5 分区演化(Partition Evolution)

  • Iceberg可以在一个已存在的表上直接修改,因为Iceberg的查询流程并不和分区信息直接关联。
  • 当我们改变一个表的分区策略时,对应修改分区之前的数据不会改变, 依然会采用老的分区策略,新的数据会采用新的分区策略。
  • 也就是说同一个表会有两种分区策略,旧数据采用旧分区策略,新数据采用新新分区策略, 在元数据里两个分区策略相互独立,不重合。

在这里插入图片描述

  • booking_table表2008年按月分区,进入2009年后改为按天分区,这两中分区策略共存于该表中。
  • 借助Iceberg的隐藏分区(Hidden Partition),在写SQL 查询的时候,不需要在SQL中特别指定分区过滤条件,Iceberg会自动分区,过滤掉不需要的数据。
  • Iceberg分区演化操作同样是一个元数据操作, 不会重写数据文件。

sales,初始的分区策略是按年份(year)进行分区:

  • id
  • amount
  • date (包含年份信息)

初始分区策略

  • year 分区
    • 数据分区示例:
      • 2021
      • 2022
      • 2023
  1. 初始数据加载

    • 数据按 year 分区存储在表中。
    • 例如,2022年的销售数据存储在 year=2022 的目录下。
  2. 修改分区策略

    • 假设将分区策略改为按月(year/month)进行分区。

    • 新的分区策略会将数据细分为每个月。

    • 现在表结构将会有两个分区策略。

    • 2021年、2022年、2023年的旧数据仍然采用老的分区策略,即按 year 分区。

    • 这些数据会保留在原有的分区结构中,例如:

      • year=2021
      • year=2022
      • year=2023
    • 新加载的数据将会使用新的分区策略,即按 year/month 进行分区。

    • 例如,2023年4月的新数据将存储在:

      • year=2023/month=04 的目录下。

Iceberg 确保查询可以有效处理这两种不同的分区策略:

  • 查询旧数据:查询在 year 分区下的数据时,Iceberg 会直接访问原来的分区。
  • 查询新数据:查询在 year/month 分区下的新数据时,Iceberg 会访问新的分区目录。

2.6 列顺序演化(Sort Order Evolution)

  • Iceberg可以在一个已经存在的表上修改排序策略。修改了排序策略之后, 旧数据依旧采用老排序策略不变。

  • 往Iceberg里写数据的计算引擎总是会选择最新的排序策略, 但是当排序的代价极其高昂的时候, 就不进行排序了。

  • 类似于:
    在这里插入图片描述
    orders 表,初始的排序策略是按 customer_id 排序:

  • order_id

  • customer_id

  • order_date

初始排序策略:按 customer_id 排序。

修改排序策略

  • 假设将排序策略更改为按 order_date 排序。

  • 新的排序策略生效后,任何新写入的数据将采用 order_date 排序。

  • 已存在的数据仍然保持按 customer_id 排序,不会受到影响。

  • 计算引擎在写入新数据时会优先选择 order_date 排序策略。

  • 在某些情况下,如果排序代价过高,可能会选择不进行排序。

在查询时,Iceberg 能够智能处理不同的排序策略:

  • 查询旧数据:针对旧数据的查询依然能保持按 customer_id 的排序。
  • 查询新数据:新数据会根据 order_date 进行排序。

2.7 隐藏分区(Hidden Partition)

Iceberg 提供了一种灵活的隐藏分区机制,使得用户无需手动管理分区信息。
在这里插入图片描述

  1. 自动分区管理:
  • 隐蔽性:与传统的 Hive 分区策略不同,Iceberg 的分区字段和策略不需要暴露给用户。用户在创建表时或修改分区策略时,Iceberg 会自动计算新数据应归属的分区。
  1. 分区字段与表数据的独立性:
  • 非表字段分区字段可以是通过某种逻辑计算得出的,而不是直接表中的字段。分区策略可以更加灵活和动态。
  • 目录无关性:Iceberg 的分区信息与表的数据存储目录是独立的,用户不需要关心物理存储的结构。
  1. 数据插入与查询:
  • 自动计算:在插入新数据时,Iceberg 会根据定义的分区策略自动计算并归入相应的分区。
  • 查询优化:在查询过程中,用户只需专注于业务逻辑,Iceberg 会自动过滤不需要的分区,从而提高查询性能。
  1. 修改分区策略:
  • 灵活性:用户可以随时修改分区策略,而不需要进行数据迁移。Iceberg 处理了分区的重新计算和数据组织,确保数据的完整性和可用性。

2.8 时间旅行(Time Travel)

Iceberg提供了查询表历史某一时间点数据镜像(snapshot)的能力。

用户可以通过简单的查询语法,指定时间戳或快照 ID 来访问这些历史数据。
在这里插入图片描述

通过该特性可以将最新的SQL逻辑,应用到历史数据上。

  1. 审计与合规:查看过去某一时刻的数据状态,便于数据审计和合规检查。
  2. 数据恢复:在数据错误或丢失时,可以恢复到之前的版本。
  3. 比较变更:分析数据的历史变化,便于理解数据演变过程。

2.9 支持事务(ACID)

Iceberg 的 ACID 事务支持使得数据管理更加可靠。

通过允许并发读写,Iceberg 能够实现高效的 upsert 操作(允许用户同时执行插入和更新),确保下游组件只接收到已提交的数据。


2.10 基于乐观锁的并发支持

乐观锁机制

  • Iceberg 使用乐观并发控制来处理多个程序的并发写入。在每次事务开始时,Iceberg 不会立即锁定数据,而是允许所有操作并在提交时检查数据的完整性。

  • 当一个事务准备提交时,它会检查是否有其他事务已更改了相同的数据。如果没有冲突,事务就会成功提交;如果有冲突,则会被拒绝,用户需要重新尝试。

  • 减少锁竞争:由于不在读操作时加锁,乐观锁机制降低了在高并发环境中出现的竞争条件。

  • 线性一致性:尽管是乐观的控制方式,Iceberg 仍能保证数据的一致性,使得多个并发写入不会导致脏读或不可重复读。


2.11 文件级数据剪裁

  • Iceberg 在每个数据文件的元数据中维护统计信息,例如最小值、最大值、计数等。这些信息使得查询优化器能够更智能地选择需要读取的文件。

  • 在执行查询时,查询引擎可以根据 SQL 语句中的过滤条件,评估每个文件的统计信息,从而决定是否需要读取该文件。

  • 加快查询速度:通过剪裁不相关的数据文件,Iceberg 可以显著减少需要扫描的数据量,从而加快查询速度。

  • 资源优化:减少 I/O 操作,节省计算资源,提升整体性能。


贴一个 亚马逊官方整理的 iceberg文档,对于列位快速上手iceberg有所帮助

在这里插入图片描述


http://www.kler.cn/a/321341.html

相关文章:

  • 网络管理 详细讲解
  • Python入门:4.Python中的运算符
  • sh cmake-linux.sh -- --skip-license --prefix = $MY_INSTALL_DIR
  • Android Https和WebView
  • Java/JDK下载、安装及环境配置超详细教程【Windows10、macOS和Linux图文详解】
  • WPSJS:让 WPS 办公与 JavaScript 完美联动
  • ansible playbook多个play多个task
  • ChatGPT高级语音助手正式上线!OpenAI:50多种语言、9种声线可选
  • 磨具生产制造9人共用一台工作站
  • elasticsearch的Ingest Attachment插件的使用总结
  • 数据结构之链表(1),单链表
  • 微服务MongoDB解析部署使用全流程
  • C嘎嘎入门篇:类和对象(1)
  • excel单元格增加可选下拉列表
  • 玩转指针(3)
  • JVM 垃圾回收算法细节
  • 第13讲 实践:设计SLAM系统
  • 工作安排 - 华为OD统一考试(E卷)
  • 深度学习—神经网络基本概念
  • md编辑器语法
  • C语言究竟是一门怎样的语言?
  • E. Alternating String
  • AWS上迁移WordPress遭遇若干问题记处理办法
  • 皮肤病检测-目标检测数据集(包括VOC格式、YOLO格式)
  • 使用离火插件yoloV8数据标注,模型训练
  • @SuppressWarnings注解