Apache Iecberg 从入门到放弃(1) —— Flink X Iceberg On Zeppelin

背景介绍

上一章我们聊过了Data Lake House&Iceberg的相关知识,也算是初步入门了。今天再来看看如何将Flink 和 Iceberg结合。
Iceberg的官方案例是通过Flink Sql Client来实现的,这个东西的局限性比较大,而且不太好看(这是主要原因),所以我打算用Zeppelin来代替Sql Client。
光说不练假把式,开整

环境准备

开始之前重申一下,我的环境准备是建立在Flink 已经能够正常在Zeppelin上提交到Yarn集群,并且与Hive打通,如果还没有实现这些,请看我以前的博客传送门

  • 将jar包放到指定位置
    # 如果用的Flink 1.11.0可以参考这部分步骤
    # 下载iceberg-flink-runtime-xxx.jar到Zeppelin服务器上任意目录
    # 这里用的是0.11.1版本的iceberg-flink-runtime,如果需要别的版本,请去https://repo.maven.apache.org/maven2/org/apache/iceberg/iceberg-flink-runtime/
    wget https://repo.maven.apache.org/maven2/org/apache/iceberg/iceberg-flink-runtime/0.11.1/iceberg-flink-runtime-0.11.1.jar
    # 如果用的Flink 1.11.X版本可以参考这部分步骤,至于其他版本,没有尝试过
    git clone https://github.com/apache/iceberg.git
    cd iceberg
    git checkout -B 0.11.x origin/0.11.x
    # 将根目录下的文件versions.props中的 org.apache.flink:* = 1.11.0 替换为 org.apache.flink:* = 1.11.2
    # 1.11.2 可以 替换成任意的Flink 1.11.x版本
    ./gradlew clean build -x test
    # 编译完成之后,将 flink-runtime/build/libs/iceberg-flink-runtime-0.11.1.jar上传至服务器指定目录
    
    # 接下来的步骤都是在Zeppelin上执行
    
  • 指定依赖的包
    %flink.conf
    flink.execution.packages org.apache.flink:flink-connector-kafka_2.11:1.11.2
    flink.execution.jars /home/dijie/iceberg/iceberg-flink-runtime-0.11.1.jar
    
  • 到这里,环境准备就结束了,接下来我们系统的来学习一下

Flink x Iceberg

catalog

  • 建一个新的catalog,并指定为Iceberg Catalog
    %flink.ssql
    CREATE CATALOG iceberg_catalog WITH (
    'type'='iceberg',
    'catalog-type'='hive',
    'uri'='thrift://localhost:9083',
    'clients'='5',
    'property-version'='1',
    'warehouse'='hdfs://hacluster/user/hive/warehouse'
    );
    
  • 看看有没有效果Apache Iecberg 从入门到放弃(1) —— Flink X Iceberg On Zeppelin_第1张图片

可以看到,除了默认的default_catalog,以及Zeppelin自动帮我们创建的hive catalog以外,我们自己建的iceberg_catalog也已经出现

Catalog的中文叫目录,那我们的database就像目录里面的每一个大章节,而table是每一个小章节,每个小章节里面的内容就是我们表里面的数据

在Iceberg中,有三种类型的Catalog

  • Hive Catalog
    我们上面用Flink Sql建的iceberg_catalog就是Hive Catalog,通过我们指定的uri地址去连接Hive Metastore,然后将我们建的库&表的信息 持久化到Hive的元数据系统中

  • Hadoop Catalog
    不依赖于Hive MetaStore ,而是通过HDFS&LOCAL 文件系统来存储元数据,对于表的更改通过对象/文件级别的原子性操作的提交来更新新元数据文件的路径[2]

    demo代码

    CREATE CATALOG hadoop_catalog WITH (
    'type'='iceberg',
    'catalog-type'='hadoop',
    'warehouse'='hdfs://nn:8020/warehouse/path',
    'property-version'='1'
    );
    
  • Custom Catalog
    最后一种是自定义类型的catalog,由用户自己实现的Catalog进行表的管理

    demo代码

    CREATE CATALOG my_catalog WITH (
    'type'='iceberg',
    'catalog-impl'='com.my.custom.CatalogImpl',
    'my-additional-catalog-config'='my-value'
    );
    

别的对catalog的操作我就不演示了可以参考官网的案例[1]

DDL

这部分我也会挑一些重点的来说,就不全部演示了

  • CREATE TABLE

    CREATE TABLE iceberg_catalog.default.sample (
    id BIGINT COMMENT 'unique id',
    data STRING
    ) PARTITIONED BY (data);
    
    • PARTITION BY (column1, column2, …)配置分区字段,可选配置,目前Flink Sql暂未支持Iceberg的隐藏分区功能
    • WITH (‘key’=‘value’, …) 可以配置这里面的Table Configuration
    • 目前也不支持定义计算列、主键、水印
  • ALTER TABLE

    ALTER TABLE iceberg_catalog.default.sample SET ('write.format.default'='avro')
    

    通过alter语句修改建表时指定的WITH中的参数

  • Writing With SQL
    有两种类型的insert,分别是INSERT INTO & INSERT OVERWRITE

    • INSERT INTO
      INSERT INTO hive_catalog.default.sample VALUES (1, 'a');
      INSERT INTO hive_catalog.default.sample SELECT id, data from other_kafka_table;
      
      以流式的方式一直append数据
    • INSERT OVERWRITE
      INSERT OVERWRITE只支持batch模式的Flink Job
      INSERT OVERWRITE sample VALUES (1, 'a');
      INSERT OVERWRITE hive_catalog.default.sample PARTITION(data='a') SELECT 6;
      

    对于分区表,如果所有分区列都被设置到PARTITION()中,则会插入静态分区;如果有部分被设置,则会通过动态分区插入,这里的表现和Hive类似
    对于非分区表,数据将会被完全覆盖

  • Querying with SQL
    Flink中的查询分为Batch和Streaming,在读取Iceberg表时,可以通过Sql Hint来自由切换

    SELECT * FROM sample /*+ OPTIONS('streaming'='true', 'monitor-interval'='1s', 'start-snapshot-id'='3821550127947089987')*/ ;
    
    • streaming:表示以流方式读取
    • monitor-interval:监视新提交的数据文件的间隔,默认为1s
    • start-snapshot-id:从指定的快照号开始读取数据
  • 尚未支持的功能

    • 创建隐藏分区表
    • 计算列、水印、主键
    • 对列进行操作
    • 自动合并小文件(目前提供了启动批作业合并小文件的方式,不够自动化)

更多的内容请参考官网iceberg-flink

完整案例

  • 指定Flink配置
    %flink.conf
    flink.execution.packages org.apache.flink:flink-connector-kafka_2.11:1.11.2
    flink.execution.jars /home/dijie/iceberg/iceberg-flink-runtime-0.11.1.jar
    execution.checkpointing.interval 60000
    execution.checkpointing.externalized-checkpoint-retention RETAIN_ON_CANCELLATION
    state.backend filesystem
    state.checkpoints.dir hdfs:///flink/checkpoints
    
    如果没有指定checkpoint,那么数据会一直无法写入HDFS,并且不会报错,因为提交Iceberg的元数据是在checkpoint完成的时候做的,具体可以参考这个iceberg项目中的这个类org.apache.iceberg.flink.sink.IcebergFilesCommitter
  • 建一张kafka Source 表
    %flink.ssql
    use catalog hive;
    drop table if exists dijie_kafkaTable;
    CREATE TABLE dijie_kafkaTable (
    exec_id int,
    flow_id String
    ) WITH (
    'connector' = 'kafka',
    'topic' = 'a_laoxiang_test',
    'properties.bootstrap.servers' = 'localhost:9092',
    'properties.group.id' = 'testGroup',
    'format' = 'json',
    'scan.startup.mode' = 'earliest-offset'
    )
    
    注意下,这里不要用Iceberg的catalog来建表,否则会存在问题,在执行查询的时候,会把表当成Iceberg表来处理
  • 建一张Iceberg Sink 表
    %flink.ssql
    use catalog iceberg_catalog;
    drop table if exists iceberg_catalog.iceberg_db.iceberg_kafka_test;
    create table iceberg_catalog.iceberg_db.iceberg_kafka_test(
    exec_id int ,
    flow_id string
    )
    
  • 简单的逻辑处理后插入Iceberg Sink表,并且再通过Streaming Read去读取Iceberg表
    Apache Iecberg 从入门到放弃(1) —— Flink X Iceberg On Zeppelin_第2张图片

好了,案例演示全部结束

写在最后

  • 这一次主要是演示Flink和Iceberg的结合,具体的核心原理没有过多的分析
  • 下一章会和大家讲一下Iceberg写在HDFS上的元数据信息,这部分我还没看过,先让我自己学习一波
  • 记得点赞

引用

[1] iceberg-flink
[2] A Short Introduction to Apache Iceberg
[3] Table Configuration

你可能感兴趣的:(Apache,Iceberg,大数据,数据湖,仓湖一体,数据仓库,Apache,Iceberg)