Apache Hudi初探(一)(与flink的结合)

Flink源码剖析:自定义TableSink与TableFactory定位过程剖析 文章目录1. 背景2. user-defined redis sink2.1 RedisTableSinkFactory2.2 RedisTableSink2.3 RedisSink3. TableFactory定位 1. 背景 现有自定义redis sink的需求,我们借此学习一下如何自定义flink sink connector,以及flink是如何通过ddl建表语句中的properties来定位具体的TableFactory,进而创建StreamTableSink的。 该文介绍的写法是Flink1.1 阅读详情

背景

和Spark的使用方式不同,flink结合hudi的方式,是以SPI的方式,所以不需要像使用Spark的方式一样,Spark的方式如下:

spark.sql.extensions=org.apache.spark.sql.hudi.HoodieSparkSessionExtension
spark.sql.catalog.spark_catalog=org.apache.spark.sql.hudi.catalog.HoodieCatalog

(这里不包括org.apache.spark.sql.sources.DataSourceRegister)
Flink结合Hudi的方式,只需要引入了对应的jar包即可,以SPI的方式:

META-INF/services/org.apache.flink.table.factories.Factory
org.apache.hudi.table.HoodieTableFactory
org.apache.hudi.table.catalog.HoodieCatalogFactory

其中 HoodieTableFactory 是读写Hudi数据的地方,
HoodieCatalogFactory是操作Hudi用到的Catalog

先说杂谈

直接先解释一下Hudi的写数据:

HoodieTableFactory

  @Override
  public DynamicTableSink createDynamicTableSink(Context context) {
    Configuration conf = FlinkOptions.fromMap(context.getCatalogTable().getOptions());
    checkArgument(!StringUtils.isNullOrEmpty(conf.getString(FlinkOptions.PATH)),
        "Option [path] should not be empty.");
    ResolvedSchema schema = context.getCatalogTable().getResolvedSchema();
    sanityCheck(conf, schema);
    setupConfOptions(conf, context.getObjectIdentifier(), context.getCatalogTable(), schema);
    return new HoodieTableSink(conf, schema);
  }

创建的HoodieTableSink是真正Hudi写入数据的类:

public class HoodieTableSink implements DynamicTableSink, SupportsPartitioning, SupportsOverwrite {
  ...
  @Override
  public SinkRuntimeProvider getSinkRuntimeProvider(Context context) {
    return (DataStreamSinkProviderAdapter) dataStream -> {

      // setup configuration
      long ckpTimeout = dataStream.getExecutionEnvironment()
          .getCheckpointConfig().getCheckpointTimeout();
      conf.setLong(FlinkOptions.WRITE_COMMIT_ACK_TIMEOUT, ckpTimeout);
      // set up default parallelism
      OptionsInference.setupSinkTasks(conf, dataStream.getExecutionConfig().getParallelism());

      RowType rowType = (RowType) schema.toSinkRowDataType().notNull().getLogicalType();

      // bulk_insert mode
      final String writeOperation = this.conf.get(FlinkOptions.OPERATION);
      if (WriteOperationType.fromValue(writeOperation) == WriteOperationType.BULK_INSERT) {
        return Pipelines.bulkInsert(conf, rowType, dataStream);
      }

      // Append mode
      if (OptionsResolver.isAppendMode(conf)) {
        DataStream<Object> pipeline = Pipelines.append(conf, rowType, dataStream, context.isBounded());
        if (OptionsResolver.needsAsyncClustering(conf)) {
          return Pipelines.cluster(conf, rowType, pipeline);
        } else {
          return Pipelines.dummySink(pipeline);
        }
      }

      DataStream<Object> pipeline;
      // bootstrap
      final DataStream<HoodieRecord> hoodieRecordDataStream =
          Pipelines.bootstrap(conf, rowType, dataStream, context.isBounded(), overwrite);
      // write pipeline
      pipeline = Pipelines.hoodieStreamWrite(conf, hoodieRecordDataStream);
      // compaction
      if (OptionsResolver.needsAsyncCompaction(conf)) {
        // use synchronous compaction for bounded source.
        if (context.isBounded()) {
          conf.setBoolean(FlinkOptions.COMPACTION_ASYNC_ENABLED, false);
        }
        return Pipelines.compact(conf, pipeline);
      } else {
        return Pipelines.clean(conf, pipeline);
      }
    };
  }
  ...
}
  • long ckpTimeout = * 获取到flink的checkpoint的超时时间,并设置为write.commit.ack.timeout的值
    和
    spark*的批处理的不同,flink会有checkpoint的存在(便于flink内部状态的保存和恢复)。
  • OptionsInference.setupSinkTasks
    设置write.tasks/write.bucket_assign.tasks/compaction.tasks/clustering.tasks 的值
  • 根据设置的write.operation值(默认是upsert),选择不同的代码路径
  • Pipelines.bootstrap bootstrap操作会加载存在的索引,并传递到下游的operator算子中
    • 如果index.global.enabled为true(默认为true),则首先构建RowDataToHoodieFunction 算子,把记录转换为HoodieAvroRecord
      其中,payload.class默认为EventTimeAvroPayload
      write.precombine 为 false,这是为了更好的写性能,这一点和Spark的默认行为一样
    • 如果index.bootstrap.enabled为true默认是false,还会构建BootstrapOperator算子,从已有的hoodie表中加载索引,并把索引记录传播到下游(注意每个task只会触发一次)
  • pipeline = Pipelines.hoodieStreamWrite 写hudi文件
    • 正如代码中的注释一样,先按照record key做shuffle,再按照fileId做shuffle,最后才是写操作:
       | input1 | ===\     /=== | bucket assigner | ===\     /=== | task1 |
                      shuffle(by PK)                    shuffle(by bucket ID)
       | input2 | ===/     \=== | bucket assigner | ===/     \=== | task2 |
      
      
    • 如果index.type不是BUCKET(默认是FLINK_STATE,使用flink state backend作为存储),我们这里主要说明一下非bucket索引:
       WriteOperatorFactory<HoodieRecord> operatorFactory = StreamWriteOperator.getFactory(conf);
        return dataStream
            // Key-by record key, to avoid multiple subtasks write to a bucket at the same time
            .keyBy(HoodieRecord::getRecordKey)
            .transform(
                "bucket_assigner",
                TypeInformation.of(HoodieRecord.class),
                new KeyedProcessOperator<>(new BucketAssignFunction<>(conf)))
            .uid(opUID("bucket_assigner", conf))
            .setParallelism(conf.getInteger(FlinkOptions.BUCKET_ASSIGN_TASKS))
            // shuffle by fileId(bucket id)
            .keyBy(record -> record.getCurrentLocation().getFileId())
            .transform(opName("stream_write", conf), TypeInformation.of(Object.class), operatorFactory)
            .uid(opUID("stream_write", conf))
            .setParallelism(conf.getInteger(FlinkOptions.WRITE_TASKS));
      
      • 按照record key进行分组后,主要的操作就是在BucketAssignFunction 这个函数中,
        该函数的主要作用就是:
        • 先根据上一个operator下发的索引记录,更新内存中保存的索引,如果索引存在则更新,否则新增(这里插入对应的I或者U标识)
      • 再按照FileId进行分组后,主要的操作 在StreamWriteFunction这个函数中,这里涉及的知识点比较多,后续详细剖析
        主要涉及了StreamWriteOperatorCoordinator以及hudi exactly once的实现等
  • 如果compaction.async.enabled为True(默认是True)则进行异步Compaction,否则进行Clean操作
Hudi集成Spark与hudi表的创建 阅读详情

相关推荐

基于Apache Hudi + Flink的亿级数据入湖实践

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 本次分享分为5个部分介绍Apache Hudi的应用与实践 实时数据落地需求演进 基于Spark+Hudi的实时数据落地应用实践 基于Flink自定义实时数据落地实践 基于Flink+Hudi的应用实践 后续应用规划及展望 1. 实时数据落地需求演进 实时平台上线后,主要

虚幻私塾 962

Hudi集成Flink-写入方式

参考: https://chbxw.blog.csdn.net/article/details/119841434。CDC(change data capture) 保证了完整数据变更,目前主要有两种方式。1、kafak 作为 源表,flinksql 消费kafka。1、使用 mysql-cdc 监听 binlog。3、将 kafka 中数据 写入 hudi。2、kafka 作为 sink表。接下来我们主要介绍 第二种方式。2、创建hudi目标表。3、写入sink 表。

chbxw 2724

hudi实战-- hudi on flink 参数配置大全

1.设置单个主键2.设置联合主键。

阿华田的博客 1344

Flink 自定义数据源Connector

flink自定义数据源

tianhouquan的专栏 5608

hudi和flink结合使用方案

Apache Hudi(简称Hudi)是Uber创建的一个数据湖框架。2019年1月,Hudi加入Apache孵化器进行孵化,并于2020年5月晋升为Apache顶级项目。它是最流行的数据湖框架之一。 1. hudi与spark解耦 自诞生以来,Hudi一直使用Spark作为其数据处理引擎。如果用户想要使用Hudi作为他们的数据湖框架,他们必须将Spark引入到他们的平台技术栈中。几年前,使用Spark作为大数据处理引擎可以说是非常普遍甚至是自然的。因为Spark既可以执行批处理,也可以使用微批处理来模拟流

u011624157的专栏 2688

分享一些基于微信小程序开发的小游戏源码

小游戏小程序是运行在微信生态系统(或其他支持小程序的平台)中的轻量级应用程序,专为休闲游戏体验而设计的小程序子类别,小游戏小程序通常体积较小,加载速度快,用户无需等待长时间即可开始游戏。用户无需下载或安装单独的游戏应用程序,即可通过小程序入口直接进入游戏,同时小游戏小程序通常包含排行榜、分享功能等社交元素,可以增强游戏体验并促进用户参与。game.js:游戏页面的逻辑文件,包含页面数据、生命周期函数、事件处理函数等。game.wxml:游戏页面的结构文件,定义了页面的布局和组件。

xinshangdian的博客 6222

【Hudi】Flink + Hudi 实践

前言 好久没有更新 “好” 文章了,内心很过意不去,怎么变的这么懒了,哈哈哈哈哈 正好,最近数据湖的概念火的一塌糊涂,特别是 Hudi , 与 Flink 的结合越来越好,可以说 Flink + Hudi 就是未来的趋势,这不,我就来简单讲讲,给 “小白”当个引路人,让知识传播给大家,毕竟我也是从小白看着别人的文章过来的 Hudi 概述 Apache Hudi (简称:Hudi) 使得您能在hadoop兼容的存储之上存储大量数据,同时它还提供两种原语,使得除了经典的批处理之外,还可以在数据湖上进行流处理

Together 7107

DSP28335做FFT傅里叶变换

1. 看了一下例程,居然没有FFT的例程,难道这个DSP28335不能做FFT吗?对了C2000系列是有C2000 ware这个库的。方便很多,不过目前不确定在C5000上运行的FFT能直接迁移到DSP28335上行不?测试了一下,是可以的,因为都是用的math.h,下面的一些正弦函数基本一样的 2. 硬件简介,其中DSP28335和TLV320AIC23B之间使用I2C接口进行寄存器配置,...

weixin_30390075的博客 3331

Apache Hudi初探(二)(与flink的结合)--flink写hudi的操作(JobManager端的提交操作)

在Apache Hudi初探(一)(与flink的结合)中,我们提到了,这个操作真正写hudi是在方法下的,具体分析一下写入的过程。对于这个代码片段,我们主要看 这个对象(这个操作是Flink框架的操作): 最主要的算子为,其中最主要的操作是由来完成的: 操作,主要是做一些初始化的操作 获取当前的task的索引下标,用来向发送event给,之后 StreamWriteOperatorCoordinator() 进行处理,后续会说到StreamWriteOperatorCoordinator 初始化hu

monkeyboy_tech的博客 2440

9 HAL库驱动框架简述(STM32HAL库)

HAL库外设的使用步骤总结如下:1、定义并填充xxx外设句柄结构体。2、如果遵循HAL库规范,通过HAL_xxx_MspInit()函数,实现外设底层资源的初始化,包括但不限于GPIO、时钟、DMA、中断等资源的初始化。3、调用HAL库的对应外设初始化函数,形如:HAL_xxx_Init()。4、初始化完成,开始使用外设。5、使用方法具体查看对应外设的HAL库驱动包中的说明:补充:HAL库使用主线外设初始化外设使用。

qq_25218501的博客 1979

千兆以太网 PCB 设计实战:4层板 100Ω 差分对布线,EMI 降低 6dB 实测

本文详细解析了千兆以太网 PCB 设计中的关键技术与实战经验,重点介绍了4层板上100Ω差分对的优化布线方法,通过实测数据展示了EMI降低6dB的有效方案。内容涵盖层叠设计、阻抗计算、布线技巧及EMI抑制措施,为硬件工程师提供了一套完整的高速电路设计解决方案。

weixin_29175469的博客 424

Apache Hudi初探(三)(与flink的结合)--flink写hudi的操作(真正的写数据)

在之前的文章中Apache Hudi初探(二)(与flink的结合)–flink写hudi的操作(JobManager端的提交操作) 有说到写hudi数据会涉及到写hudi真实数据以及写hudi元数据,这篇文章来说一下具体的实现这里的操作就是在HoodieFlinkWriteClient.upsert方法: initTable 初始化HoodieFlinkTable preWrite 在这里几乎没什么操作 getOrCreateWriteHandle 创建一个写文件的handle(假如这里创建的是Flin

monkeyboy_tech的博客 1061

别再折腾老教程了!树莓派4B/5最新系统(Raspberry Pi OS Bookworm)红外遥控配置,用gpio-ir驱动一次成功

本文详细介绍了树莓派4B/5在最新Raspberry Pi OS Bookworm系统下配置红外遥控的完整指南,摒弃过时的lirc-rpi驱动,采用现代gpio-ir驱动方案。从硬件连接到软件配置,提供10分钟快速上手指南,涵盖驱动加载、信号测试、按键映射及高级应用场景,帮助用户高效完成红外遥控配置。

weixin_42520909的博客 442

实时数据湖 Flink Hudi 实践探索

本文介绍的介绍的主题是 Flink 和 Hudi 在数据湖 Streaming 方向的一些探索和实践,将会围绕以下四点展开: • Apache Hudi 背景介绍 • Flink Hudi 设计 • Hudi 应用场景 • Hudi RoadMap

科技很有意思 3980

基于Keil软件实现对射式红外传感器计次 (江协科技HAL库)

用HAL库复现江协科技,让嵌入式学习之路更顺畅。

2401_82728381的博客 798

HyperLynx中层叠设计实例

这两种方式有点区别,前一种方式只是增加层,需要自行修改层的类型,后一种方式可以选定为某一种类型,如果是增加信号层,软件会默认同时增加一层介质层。层叠已经有8层,按照示例的层叠有4个信号层、3个地平面层和1个电源平面层,对照进行层名称(LayerName)、介质类型(Type)及用途(Usage)设置。在这列中,有的是白色,有的是淡蓝色。白色的说明可以修改,如第一行是介质,通常在最外层的介质有两个用途,阻焊层和介质,单击该行会出现一个下拉菜单,选择SolderMask,即为阻焊层。...

小幽余生不加糖 5874

hudi与flink的集成(一)

Apache Hudi 是目前最流行的数据湖解决方案之一,AWS 在 EMR 服务中 预安装[2] 了 Apache Hudi,为用户提供高效的 record-level updates/deletes 和高效的数据查询管理。 Apache Flink 作为目前最流行的流计算框架,在流式计算场景有天然的优势,当前,Flink 社区也在积极拥抱 Hudi 社区,发挥自身 streaming 写/读的优势,同时也对 batch 的读写做了支持。

qq_40822132的博客 2167

深度学习技巧应用26-CNN中多种注意力机制的嵌入方法,终于搞懂注意力机制了

大家好,我是微学AI,今天给大家介绍一下深度学习技巧应用26-CNN中多种注意力机制的嵌入方法,终于搞懂注意力机制了。CNN是一种能够有效处理图像和其他二维数据的深度学习模型。在传统的CNN中,每个卷积核都会对输入的所有位置进行相同的操作,这可能导致网络无法针对特定区域或特征进行更加关注和重点处理。 注意力机制被引入卷积神经网络中,旨在使网络能够自动地学习和聚焦于输入中的重要区域或特征。通过引入注意力机制,可以增强网络对不同区域或特征的关注度,提取更有意义和相关的特征,从而提高模型的性能和表达能力。

微学AI的博客 3312

Apache Hudi初探(五)(与flink的结合)--Flink 中hudi clean操作

首先是反序列化CleanPlan,然后在进行清理,主要是删除1. 如果没有满足的分区,直接删除该分区,2. 否则删除该分区下的满足条件的文件,最后返回。HoodieFlinkMergeOnReadTable*类型的hudi表,用来做clean等操作。,也就是在写数据失败的时候,会立即进行这次写失败的数据的清理,在这种情况下,创建一个只有一个线程的线程池,改线程池的主要作用来异步执行hudi写操作。本文主要是具体说说Flink中的clean操作的实现。真正执行clean的部分,主要是调用。

monkeyboy_tech的博客 1496

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Zeppelin结合Flink查询hudi数据

关于Zeppelin Zeppelin是基于 Web 的notebook,是支持使用 SQL、Scala、Python、R 等进行数据驱动的交互式数据分析和协作的Notebook。 Zeppelin支持多种语言后端,Apache Zeppelin 解释器允许将任何语言/数据处理后端插入 Zeppelin。 目前 Apache Zeppelin 支持 Apache Spark、Apache Flink、Python、R、JDBC、Markdown 和 Shell 等多种解释器。 简单来说就是,让你通过Web

从大数据到人工智能的博客 791

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

使用 Flink Hudi 构建流式数据湖平台

▼ 关注「ApacheFlink」,看更多大咖▼摘要:本文整理自阿里巴巴技术专家陈玉兆 (玉兆)、阿里巴巴开发工程师刘大龙 (风离) 在 Flink Forward Asia 2021 ...

Ververica的博客 1442

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

使用 Flink Hudi 构建流式数据湖

简介:本文介绍了 Flink Hudi 通过流计算对原有基于 mini-batch 的增量计算模型的不断优化演进。 本文介绍了 Flink Hudi 通过流计算对原有基于 mini-batch 的增量计算模型不断优化演进。用户可以通过 Flink SQL 将 CDC 数据实时写入 Hudi 存储,且在即将发布的 0.9 版本 Hudi 原生支持 CDC format。主要内容为: 背景 增量 ETL 演示 一、背景 近实时 从 2016 年开始,Apache Hudi 社区就开始通过 H.

阿里云云栖号 1324

[Hudi]hudi的编译及hudi&spark和hudi&flink的简单使用

hudi的编译

MyNameIsWangYi的博客 1709

Hudi系列9:Flink SQL操作hudi表

Flink SQL操作Hudi表 Flink Hudi集成

只是甲的博客 1624

Flink CDC Hudi同步:增量更新与快照管理

传统批处理ETL面临三大挑战:数据延迟(T+1级)、存储冗余(全量快照)、资源浪费(重复计算)。以电商订单系统为例,每日全量同步10TB订单表需消耗4小时,而99%数据未变更。Flink CDC(Change Data Capture,变更数据捕获)技术通过捕获数据库事务日志实现实时增量同步,结合Apache Hudi(Hadoop Upserts Deletes and Incrementals...

gitblog_01079的博客 1129
上一篇: Apache Hudi初探(九)(与spark的结合)--非bulk_insert模式
下一篇: Spark中python和jvm的通信杂谈--ArrowConverter
鸿乃江边鸟
博客等级 码龄6年 3746粉丝 235原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值