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

背景

在Apache Hudi初探(一)(与flink的结合)中,我们提到了Pipelines.hoodieStreamWrite 写hudi文件,这个操作真正写hudi是在Pipelines.hoodieStreamWrite方法下的transform(opName("stream_write", conf), TypeInformation.of(Object.class), operatorFactory),具体分析一下写入的过程。

分析

对于transform(opName("stream_write", conf), TypeInformation.of(Object.class), operatorFactory)这个代码片段,我们主要看operatorFactory 这个对象(transform这个操作是Flink框架的操作):

public class StreamWriteOperator<I> extends AbstractWriteOperator<I> {public StreamWriteOperator(Configuration conf) {super(new StreamWriteFunction<>(conf));}public static <I> WriteOperatorFactory<I> getFactory(Configuration conf) {return WriteOperatorFactory.instance(conf, new StreamWriteOperator<>(conf));}
}

最主要的hudi算子为StreamWriteOperator,其中最主要的操作是由StreamWriteFunction来完成的:

// StreamWriteFunction@Overridepublic void initializeState(FunctionInitializationContext context) throws Exception {this.taskID = getRuntimeContext().getIndexOfThisSubtask();this.metaClient = StreamerUtil.createMetaClient(this.config);this.writeClient = FlinkWriteClients.createWriteClient(this.config, getRuntimeContext());this.writeStatuses = new ArrayList<>();this.writeMetadataState = context.getOperatorStateStore().getListState(new ListStateDescriptor<>("write-metadata-state",TypeInformation.of(WriteMetadataEvent.class)));this.ckpMetadata = CkpMetadata.getInstance(this.metaClient.getFs(), this.metaClient.getBasePath());this.currentInstant = lastPendingInstant();if (context.isRestored()) {restoreWriteMetadata();} else {sendBootstrapEvent();}// blocks flushing until the coordinator starts a new instantthis.confirming = true;}@Overridepublic void open(Configuration parameters) throws IOException {this.tracer = new TotalSizeTracer(this.config);initBuffer();initWriteFunction();}@Overridepublic void snapshotState(FunctionSnapshotContext functionSnapshotContext) throws Exception {if (inputEnded) {return;}snapshotState();// Reload the snapshot state as the current state.reloadWriteMetaState();}@Overridepublic void snapshotState() {// Based on the fact that the coordinator starts the checkpoint first,// it would check the validity.// wait for the buffer data flush out and request a new instantflushRemaining(false);}@Overridepublic void processElement(I value, ProcessFunction<I, Object>.Context ctx, Collector<Object> out) throws Exception {bufferRecord((HoodieRecord<?>) value);}
  • initializeState操作,主要是做一些初始化的操作

    • this.taskID = getRuntimeContext().getIndexOfThisSubtask();
      获取当前的task的索引下标,用来向operator coordinator发送event给operator coordinator,之后 StreamWriteOperatorCoordinator(operator coordinator) 进行处理,后续会说到StreamWriteOperatorCoordinator

    • metaClient = StreamerUtil.createMetaClient(this.config)
      writeClient = FlinkWriteClients.createWriteClient
      初始化hudi的元数据客户端(这里是HoodieTableMetaClient)和写入客户端(这里是HoodieFlinkWriteClient)

    • writeStatuses = new ArrayList<>()
      记录后续的写入hudi文件的信息

    • writeMetadataState = context.getOperatorStateStore().getListState
      记录写入hudi的元数据事件,会在后续的操作中,会包装成event发送给operator coordinator(StreamWriteOperatorCoordinator)

    • ckpMetadata = CkpMetadata.getInstance
      Flink的checkpoint的元数据信息路径,默认的路径是/${hoodie.basePath}/.hoodie/.aux/ckp_meta

    • currentInstant = lastPendingInstant()
      获取上次还没有完成的commit

    • restoreWriteMetadata或者sendBootstrapEvent,根据是否是从checkpoint恢复过来的进行不同消息的发送,
      这里的operator coordinator(StreamWriteOperatorCoordinator)会进行统一的处理,并初始化一个commit

  • open操作
    写入hudi前的前置操作,比如说 初始化TotalSizeTracer记录maxBufferSize便于flush操作
    根据write.operation的值(默认是upsert)选择后续的操作是insert或upsert或overwrite,这里是upsert

  • processElement操作
    这里对传入的HoodieRecord进行缓存,主要是bufferRecord做的事情,

    • 首先会获取bucketID,之后再往对应的bucket中插入数据
    • 如果超出write.batch.size(默认是128MB),则会进行flushBucket操作,该操作主要是写入hudi操作 //TODO: 具体的写入hudi操作
      • 首先会获取新的需要提交的commit
      • 再进行写入的实际操作
      • 写入的文件元数据信息回传到operator coordinator进行统一处理
  • snapshotState 操作

    • 调用flushRemaining 写入剩下的数据到hudi存储中
    • 重新加载当前写入的hudi文件元数据信息到当前flink的state中

hudi StreamWriteOperatorCoordinator作用

总的来说,StreamWriteOperatorCoordinator扮演的角色和在Spark中driver的角色一样,都是来最后来提交 元数据信息到huid中。
具体的作用还是得从具体的方法来看:

  @Overridepublic void handleEventFromOperator(int i, OperatorEvent operatorEvent) {ValidationUtils.checkState(operatorEvent instanceof WriteMetadataEvent,"The coordinator can only handle WriteMetaEvent");WriteMetadataEvent event = (WriteMetadataEvent) operatorEvent;if (event.isEndInput()) {// handle end input event synchronously// wrap handleEndInputEvent in executeSync to preserve the order of eventsexecutor.executeSync(() -> handleEndInputEvent(event), "handle end input event for instant %s", this.instant);} else {executor.execute(() -> {if (event.isBootstrap()) {handleBootstrapEvent(event);} else {handleWriteMetaEvent(event);}}, "handle write metadata event for instant %s", this.instant);}}...@Overridepublic void notifyCheckpointComplete(long checkpointId) {executor.execute(() -> {// The executor thread inherits the classloader of the #notifyCheckpointComplete// caller, which is a AppClassLoader.Thread.currentThread().setContextClassLoader(getClass().getClassLoader());// for streaming mode, commits the ever received events anyway,// the stream write task snapshot and flush the data buffer synchronously in sequence,// so a successful checkpoint subsumes the old one(follows the checkpoint subsuming contract)final boolean committed = commitInstant(this.instant, checkpointId);if (tableState.scheduleCompaction) {// if async compaction is on, schedule the compactionCompactionUtil.scheduleCompaction(metaClient, writeClient, tableState.isDeltaTimeCompaction, committed);}if (tableState.scheduleClustering) {// if async clustering is on, schedule the clusteringClusteringUtil.scheduleClustering(conf, writeClient, committed);}if (committed) {// start new instant.startInstant();// sync Hive if is enabledsyncHiveAsync();}}, "commits the instant %s", this.instant);}
  • handleEventFromOperator方法用来接受task发送的消息

    • 对于BootStrap类型的WriteMetadataEvent(在StreamWriteFunction方法initializeState中),相当于函数初始化也就会触发
      该类型的消息由handleBootstrapEvent来处理(我们这里假设每个任务operator都完成了初始化的操作),对应的数据流如下:

      initInstant||\/
      reset => startInstant
      

      startInstant 这里就会初始化一个hudi写操作的commit信息

    • 对于一般的write的信息的event,(比如说在processElement的flushBucket函数中),由handleWriteMetaEvent来处理:

       if (this.eventBuffer[event.getTaskID()] != null) {this.eventBuffer[event.getTaskID()].mergeWith(event);} else {this.eventBuffer[event.getTaskID()] = event;}
      

      这里只是加到变量名为eventBuffer 的WriteMetadataEvent类型的数组中,后续中会进行处理

    • 对于isEndInputtrue的event,这种一般source是基于文件的这种,这里先不讨论

  • notifyCheckpointComplete 当对应的checkpointId完成以后,该方法会被调用

    • commitInstant 提交hudi元数据,如果如果有发生异常,则回滚当前hudi对应的commit
    • scheduleCompaction && scheduleClustering 进行hui的CompcationClustering
    • 如果成功的提交了,则会开启一个新的commit,如果开了hive同步(hive_sync.enabled默认为false),则会同步元数据信息到hive

总结

用一张图总结一下交互方式,如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/105417.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NVIDIA vGPU License许可服务器高可用全套部署秘籍

第1章 前言 近期遇到比较多的场景使用vGPU&#xff0c;比如Citrix 3D场景、Horizon 3D场景&#xff0c;还有AI等&#xff0c;都需要使用显卡设计研发等&#xff0c;此时许可服务器尤为重要&#xff0c;许可断掉会出现掉帧等情况&#xff0c;我们此次教大家部署HA许可服务器。 …

爬虫异常处理:异常捕获与容错机制设计

作为一名专业的爬虫程序员&#xff0c;每天使用爬虫IP面对各种异常情况是我们每天都会遇到的事情。 在爬取数据的过程中&#xff0c;我们经常会遇到网络错误、页面结构变化、被反爬虫机制拦截等问题。在这篇文章中&#xff0c;我将和大家分享一些关于如何处理爬虫异常情况的经…

怎么制作sip网络寻呼话筒,sip任意呼叫主机,

怎么制作sip网络寻呼话筒&#xff0c;sip任意呼叫主机&#xff0c; 所需材料一&#xff1a;SV-2103VP sip网络音频模块 功能如下&#xff1a; SV-2101VP/ SV-2103VP使用了AT32F437VGT7处理器构架加专业的双向音频Codec编解码器&#xff0c; 处理器负责数据的传输&#xff0c…

【李群李代数】李群控制器(lie-group-controllers)介绍——控制 SO(3) 空间中的系统的比例控制器Demo...

李群控制器SO(3)测试 测试代码是一个用于控制 SO(3) 空间中的系统的比例控制器。它通过计算控制策略来使当前状态逼近期望状态。该控制器使用比例增益 kp 进行参数化&#xff0c;然后进行一系列迭代以更新系统状态&#xff0c;最终检查状态误差是否小于给定的阈值。这个控制器用…

Checkstyle安装、使用

Checkstyle简介 Checkstyle是SourceForge下的一个项目&#xff0c;官网&#xff1a; https://checkstyle.sourceforge.io/ 在官网有详细的说明。 Checkstyle是一个开发工具&#xff0c;可以帮助开发者自动检查java代码是否遵循编程规范&#xff0c;将开发者从枯燥繁琐的手工…

ArcGIS Serve Windows下用户密码变更导致Server服务无法启动问题

问题&#xff1a; 因未知原因Windows下的Server安装账户密码变更&#xff0c;但是又忘记了密码&#xff0c;导致&#xff0c;Server服务启动失败&#xff0c;错误1069&#xff1a; 解决方法&#xff1a; 在账户管理界面&#xff0c;重置对应的arcgis账户的密码&#xff0c;…

VUE之jspreadsheet电子excel表格动态高度设置

问题&#xff1a;excel电子表格在不同屏幕大小下横向滚动条会被遮挡 排查原因&#xff1a;由于excel高度固定导致 解决方法&#xff1a;设计页面较多&#xff0c;所以封装公共方法 步骤&#xff1a; 1.使用混入封装动态设置excel高度方法&#xff1a; const mixinJexcel …

“分布式”与“集群”初学者的技术总结

一、“分布式”与“集群”的解释&#xff1a; 分布式&#xff1a;把一个囊肿的系统分成无数个单独可运行的功能模块 集群&#xff1a; 把相同的项目复制进行多次部署&#xff08;可以是一台服务器多次部署&#xff0c;例如使用8080部署一个&#xff0c;8081部署一个&#xff0c…

Unity 物体的运动之跟随鼠标

你想让鼠标点击哪里&#xff0c;你的运动的对象就运动到哪里吗&#xff1f; Please follow me ! 首先&#xff0c;你要先添加一个Plane ,以及你的围墙&#xff0c;你的移动的物体 想要实现跟随鼠标移动&#xff0c;我们先创建一个脚本 using System.Collections; using Syst…

html学习第2篇---标签(1)

html学习第2篇---标签 1、标题标签h1---h62、段落标签p3、换行标签br4、文本格式化标签5、div标签和span标签6、图像标签img6.1、图像属性6.2、相对路径、绝对路径 7、超链接标签a7.1、属性7.2、分类 8、注释标签和特殊字符8.1、注释8.2、特殊字符 1、标题标签h1—h6 为了使网…

SpringBoot案例-文件上传

目录 简介 文件上传前端页面三要素 服务端接收文件 小结 本地储存 实现 代码优化 小结 阿里云OSS 阿里云 阿里云OSS 使用第三方服务--通用思路 准备工作 参照官方SDK代码&#xff0c;编写入门程序 集成使用 阿里云OSS-使用步骤 阿里云OSS使用步骤 参照SDK编写入…

【C++11】future和async等

C11的future和async等关键字 1.async和future的概念 std::async 和 std::future 是 C11 引入的标准库功能&#xff0c;用于实现异步编程&#xff0c;使得在多线程环境中更容易处理并行任务。它们可以帮助你在不同线程中执行函数&#xff0c;并且能够方便地获取函数的结果。 在…

两个步骤让图片动起来!

在当今数字时代&#xff0c;动态图片已经成为了网页设计和移动应用设计的标配之一。动态图片能够吸引用户的注意力&#xff0c;提高用户体验和页面交互性。那么&#xff0c;图片怎么动起来&#xff1f;有什么好用的方法呢&#xff1f;下面我们来一起探讨一下。 通常我们认知的动…

java八股文面试[JVM]——JVM内存结构2

知识来源&#xff1a; 【2023年面试】JVM内存模型如何分配的_哔哩哔哩_bilibili

2023中国算力大会 | 中科驭数加入DPU推进计划,探讨DPU如何激活算网融合新基建

8月18日&#xff0c;由工业和信息化部、宁夏回族自治区人民政府共同主办的2023中国算力大会在宁夏银川隆重召开。作为DPU算力基础设施领军企业&#xff0c;中科驭数产品运营部副总经理曹辉受邀在中国信通院承办的算网融合分论坛发表主题演讲《释放极致算力 DPU激活算网融合新基…

Vue使用Element的表格Table显示树形数据,多选框全选无法选中全部节点

使用Element的组件Table表格&#xff0c;当使用树形数据再配合上多选框&#xff0c;如下&#xff1a; 会出现一种问题&#xff0c;点击左上方全选&#xff0c;只能够选中一级树节点&#xff0c;子节点无法被选中&#xff0c;如图所示&#xff1a; 想要实现点击全选就选中所有的…

嵌入式学习之linux

今天&#xff0c;主要对linux文件操作原理进行了学习&#xff0c;主要学习的内容就是对linux文件操作原理进行理解。写的代码如下&#xff1a;

CSS3盒模型+flex

1.盒模型 标准盒模型: wwidthpaddingborderhheightpaddingborder 怪异盒模型(ie盒模型) wwidth包含了(paddingborder)hheight包含了(paddingborder) 2.CSS3弹性盒(重点新版弹性盒) 弹性盒: 设置为弹性盒后,父元素为容器,子元素为项目弹性盒中存在两根轴,默认水平为主轴,垂…

成集云 | 畅捷通T+cloud连接器自动同步财务费用单至畅捷通 | 解决方案

源系统成集云目标系统 方案介绍 财务管理作为企业管理中重要的组成部分&#xff0c;在企业的发展和成长中扮演着重要角色&#xff0c;成集云以钉钉费用单OA审批与畅捷通TCloud系统为例&#xff0c;与钉钉连接器深度融合&#xff0c;通过数据处理和字段匹配实现了费用…

6.oracle中listagg函数使用

1. 作用 可以实现行转列&#xff0c;将多列数据聚合为一列&#xff0c;实现数据的压缩 2. 语法 listagg(measure_expr&#xff0c;delimiter) within group ( order by order_by_clause); 解释&#xff1a; measure_expr可以是基于任何列的表达式 delimiter分隔符&#xff0c…