• Iceberg学习笔记(1)—— 基础知识


    Iceberg是一个面向海量数据分析场景的开放表格式(Table Format),其设计的目的是解决数据存储和计算引擎之间的适配的问题

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

    概述

    iceberg的特性

    • 数据存储、计算引擎插件化:Iceberg提供一个开放通用的表格式(Table Format)实现方案,不和特定的数据存储、计算引擎绑定
    • 实时流批一体:Iceberg上游组件将数据写入完成后,下游组件及时可读,可查询。可以满足实时场景。并且Iceberg同时提供了流/批读接口、流/批写接口。可以在同一个流程里, 同时处理流数据和批数据,大大简化了ETL链路
    • 数据表演化(Table Evolution):Iceberg可以通过SQL的方式进行表级别模式演进;不存在读出数据重新写入或者迁移数据这种费时费力的操作(比如在常用的Hive中,如果我们需要把一个按天分区的表,改成按小时分区。此时,不能再原表之上直接修改,只能新建一个按小时分区的表,然后再把数据Insert到新的小时分区表。而且,即使我们通过Rename的命令把新表的名字改为原表,使用原表的上次层应用, 也可能由于分区字段修改,导致需要修改 SQL,这样花费的经历是非常繁琐的)
    • 模式演化(Schema Evolution):
    1. ADD:向表或者嵌套结构增加新列
    2. Drop:从表中或者嵌套结构中移除一列
    3. Rename:重命名表中或者嵌套结构中的一列
    4. Update:将复杂结构(struct, map, list)中的基本类型扩展类型长度, 比如tinyint修改成int.
    5. Reorder:改变列或者嵌套结构中字段的排列顺序

    重点:一个元数据操作, 不会涉及到重写数据文件的过程

    具体表现为:

    ①增加列时候,不会从另外一个列中读取已存在的的数据

    ②删除列或者嵌套结构中字段的时候,不会改变任何其他列的值

    ③更新列或者嵌套结构中字段的时候,不会改变任何其他列的值

    ④改变列列或者嵌套结构中字段顺序的时候,不会改变相关联的值

    实现方式:在表中Iceberg 使用唯一ID来定位每一列的信息;新增一个列的时候,会新分配给它一个唯一ID, 并且绝对不会使用已经被使用的ID

    使用唯一ID定位,避免了使用名称定位会重复、使用位置定位无法修改顺序的缺点

    • 分区演化:Iceberg table partitioning can be updated in an existing table because queries do not reference partition values directly(可以直接在表上修改分区策略,因为查询不和分区数据直接关联)

    当我们改变一个表的分区策略时,对应修改分区之前的数据不会改变, 依然会采用老的分区策略,新的数据会采用新的分区策略,也就是说同一个表会有两种分区策略,旧数据采用旧分区策略,新数据采用新新分区策略, 在元数据里两个分区策略相互独立,不重合

    借助Iceberg的隐藏分区(Hidden Partition),在写SQL 查询的时候,不需要在SQL中特别指定分区过滤条件,Iceberg会自动分区,过滤掉不需要的数据;Iceberg分区演化操作同样是一个元数据操作, 不会重写数据文件

    • 列顺序演化(Sort Order Evolution):Iceberg可以在一个已经存在的表上修改排序策略。修改了排序策略之后, 旧数据依旧采用老排序策略不变。往Iceberg里写数据的计算引擎总是会选择最新的排序策略, 但是当排序的代价极其高昂的时候, 就不进行排序了
    • 隐藏分区(Hidden Partition): Iceberg的分区字段/策略(通过某一个字段计算出来),可以不是表的字段和表数据存储目录;在建表或者修改分区策略之后,新的数据会自动计算所属于的分区。在查询的时候同样不用关心表的分区是什么字段/策略,只需要关注业务逻辑,Iceberg会自动过滤不需要的分区数据

    Iceberg的分区信息和表数据存储目录是独立的,因此Iceberg的表分区可以被修改,而且不涉及到数据迁移

    • 镜像数据查询(Time Travel):Iceberg提供了查询表历史某一时间点数据镜像(snapshot)的能力。通过该特性可以将最新的SQL逻辑,应用到历史数据上
    • 支持事务(ACID):Iceberg通过提供事务(ACID)的机制,使其具备了upsert的能力并且使得边写边读成为可能,从而数据可以更快的被下游组件消费。通过事务保证了下游组件只能消费已commit的数据,而不会读到部分甚至未提交的数据
    • 基于乐观锁的并发支持:Iceberg基于乐观锁提供了多个程序并发写入的能力并且保证数据线性一致
    • 文件级数据剪裁:Iceberg的元数据里面提供了每个数据文件的一些统计信息,比如最大值,最小值,Count计数等等。因此,查询SQL的过滤条件除了常规的分区,列过滤,甚至可以下推到文件级别,大大加快了查询效率

    不同数据湖框架的对比

    iceberg不支持索引

    存储结构

    • 数据文件 data files:数据文件是Apache Iceberg表真实存储数据的文件,一般是在表的数据存储目录的data目录下,如果我们的文件格式选择的是parquet,那么文件是以“.parquet”结尾
    • 表快照 Snapshot:快照代表一张表在某个时刻的状态;每个快照里面会列出表在某个时刻的所有 data files 列表。data files是存储在不同的manifest files里面,manifest files是存储在一个Manifest list文件里面,而一个Manifest list文件代表一个快照
    • 清单列表 Manifest list:manifest list是一个元数据文件它列出构建表快照(Snapshot)的清单(Manifest file)。这个元数据文件中存储的是Manifest file列表,每个Manifest file占据一行。每行中存储了Manifest file的路径、其存储的数据文件(data files)的分区范围,增加了几个数文件、删除了几个数据文件等信息,这些信息可以用来在查询时提供过滤,加快速度

    例如:snap-6746266566064388720-1-52f2f477-2585-4e69-be42-bbad9a46ed17.avro就是一个Manifest List文件

    • 清单文件 Manifest file:Manifest file也是一个元数据文件,它列出组成快照(snapshot)的数据文件(data files)的列表信息

    每行都是每个数据文件的详细描述,包括数据文件的状态、文件路径、分区信息、列级别的统计信息(比如每列的最大最小值、空值数等)、文件的大小以及文件里面数据行数等信息。其中列级别的统计信息可以在扫描表数据时过滤掉不必要的文件

    Manifest file是以avro格式进行存储的,以“.avro”后缀结尾,例如:52f2f477-2585-4e69-be42bbad9a46ed17-m0.avro

    查看具体的存储结构

    打开HDFS的Web UI,进入/user/hive/warehouse/iceberg_test1路径下(使用默认的catalog创建了表iceberg_test1)

    • data:数据文件

    可以看到是以parquet格式存储的

    • metadata:元数据文件

    Manifest file记录了数据文件的位置信息; Manifest list记录了 Manifest file的位置信息

  • 相关阅读:
    多线程与高并发(7)——从ReentrantLock到AQS源码(两万字大章,一篇理解AQS)
    java计算机毕业设计新生报到管理系统源程序+mysql+系统+lw文档+远程调试
    AI-数学-高中-31-统计-总体方差与样本方差(新教材内容)
    2.1 发布与订阅C++
    数组与list的转化分析
    ImageEn FMX内置图像效果对话框
    java框架常见的面试题
    基于深度学习的鸟类检测识别系统(含UI界面,Python代码)
    python执行pip指令时,提示“You should consider upgrading……”的解决方法
    文献阅读4
  • 原文地址:https://blog.csdn.net/qq_51235856/article/details/134520064