Apache Flink源码解析之stream-source

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 今天我们来解读一下Flink stream里的source模块。它是整个stream的入口,也是我们了解其流处理体系的入口。 SourceFunction SourceFunction是所有stream source的根接口。

今天我们来解读一下Flink stream里的source模块。它是整个stream的入口,也是我们了解其流处理体系的入口。

SourceFunction

SourceFunction是所有stream source的根接口。

它继承自一个标记接口(空接口)Function

SourceFunction定义了两个接口方法:

  • run : 启动一个source,即对接一个外部数据源然后emit元素形成stream(大部分情况下会通过在该方法里运行一个while循环的形式来产生stream)。
  • cancel : 取消一个source,也即将run中的循环emit元素的行为终止。

正常情况下,一个SourceFunction实现这两个接口方法就可以了。其实这两个接口方法也固化了一种实现模板

比如,实现一个XXXSourceFunction,那么大致的模板是这样的:

private volatile boolean isRunning = true;

    @Override
    public void run(SourceContext<T> ctx) throws Exception {
        while (isRunning && otherCondition == true) {
            ctx.collect(getElement());
        }
    }

    @Override
    public void cancel() {
        isRunning = false;
    }

SourceContext

Flink将Source的运行机制跟其如何emit元素进行了分离。具体如何emit元素,取决于另外一个独立的接口SourceContextSourceFunction以内部接口的方式定义了该上下文接口对象,将具体的实现抛给具体的sourceFunction。该接口中定义了emit元素的接口方法:

  • collect : 从source emit一个元素,该元素的时间戳被自动设置为本地时钟(System#currentTimeMillis()),这种由当前source自动追加的时间戳,在Flink里称之为Ingress Time(即摄入时间)。
  • collectWithTimestamp : 根据用户提供的自定义的时间戳emit一个元素,这种被称之为Event Time(即用户自行设置的事件时间)。
  • emitWatermark : 手动发射一个Watermark

这里有几个时间概念可参考我之前的文章:http://vinoyang.com/2016/05/02/flink-concepts/#时间

Watermark:Flink用Watermark来对上面的Event Time类型的事件进行窗口处理。所谓的Watermark是一个时间基准。WaterMark包含一个时间戳,Flink使用WaterMark标记所有小于该时间戳的消息都已流入,Flink的数据源在确认所有小于某个时间戳的消息都已输出到Flink流处理系统后,会生成一个包含该时间戳的WaterMark,插入到消息流中输出到Flink流处理系统中,Flink操作符按照时间窗口缓存所有流入的消息,当operator处理到WaterMark时,它对所有小于该WaterMark时间戳的时间窗口数据进行处理并发送到下一个operator节点,然后也将WaterMark发送到下一个operator节点。

内置的SourceFunction

source相关的完整类图如下:

flink-stream-source_class-diagram

RichSourceFunction

一个抽象类,继承自AbstractRichFunction。为实现一个Rich SourceFunction提供基础能力(其实所谓的Rich,主要是提供某种范式或者模板帮助你完成一部分基础实现)。该类的子类有两个,不过他们仍然是抽象类,只是在此基础上提供了更具体的实现:

  • MessageAcknowledgingSourceBase :它针对的是数据源是消息队列的场景并且提供了基于ID的应答机制。
  • MultipleIdsMessageAcknowledgingSourceBase : 在MessageAcknowledgingSourceBase的基础上针对ID应答机制进行了更为细分的处理,支持两种ID应答模型:session idunique message id

ParallelSourceFunction

该接口只是个标记接口,用于标识继承该接口的Source都是并行执行的。其直接实现类是RichParallelSourceFunction,它是一个抽象类并继承自AbstractRichFunction(从名称可以看出,它应该兼具richparallel两个特性,这里的rich体现在它定义了openclose这两个方法)。

继承RichParallelSourceFunction的那些SourceFunction意味着它们都是并行执行的并且可能有一些资源需要open/close,Flink提供了这么几个实现:

  • FileSourceFunction : 以文件为数据源的Source,它根据给定的InputFormat作为数据源记录的生产器(它可以接收一个file path来基于文件生产记录),根据给定的TypeInformation来产生序列化器,再结合内部创建的splitIterator实现了一个基于文件的sourceFunction。
  • ConnectorSource : 抽象类,没有具体的实现。通过其构造器注入了一个属性DeserializationSchema,该属性是一个协议接口,用于定义如何将二进制数据反序列化为Java/Scala对象。
  • StatefulSequenceSource :有状态的序列Source。它接收startend作为一个发射序列的区间,然后根据一定的算法算得需要发射的时间间隔,并保证区间内的元素送达具有exactly once的强一致性,具体的计算方式需要结合当前task的subtask的数量以及当前subtask在集合中的索引计算得出。
  • FromSplittableIteratorFunction :根据给定的SplittableIterator(它是一个全局的iterator)结合当前task运行时subtask的数量,以及该subtask在所有subtask中的序号计算出分区(partition)从而产生一个细分的Iterator。通过Iterator迭代来发射元素。

FileMonitoringFunction

该Source是以监控给定path位置的文件为手段,根据给定的interval作为时间间隔,emit的内容依赖监控文件的变。Flink为这种形式的Source提供了三种watchtype :

    public enum WatchType {
        ONLY_NEW_FILES,                 //仅关注新文件产生
        REPROCESS_WITH_APPENDED,    //当有文件产生变更,该文件的所有内容都需要被重新处理
        PROCESS_ONLY_APPENDED       //当有文件产生变更,只有变更的内容需要被处理
    }

该类型的Source始终发射的是一个三元组(Tuple3),它包含三个元素:

  • filePath : 标识文件路径
  • offset : 偏移量
  • fileSize : 文件大小

watchtype的不同主要影响发射元素的内容。当WatchType的类型为ONLY_NEW_FILESREPROCESS_WITH_APPENDED类型时,offset会被设置为0,fileSize被设置为-1。而WatchType类型为PROCESS_ONLY_APPENDED,则三个值都为其对应的真实值。

SocketTextStreamFunction

根据给定的hostnameport,以socket的方式进行通信并获取数据,以delimiter参数给定的字符作为终止标识符。

FromIteratorFunction

该Source接收一个迭代器,然后在发射循环体中,依次迭代发射数据。

FromElementsFunction

该Source接收一个元素迭代器(一组元素的集合),以Flink的类型序列化机制将其序列化为二进制数据,然后在发射元素的循环体中,进行反序列化为初始类型,再发射数据。

这里先序列化为二进制,再从二进制反序列化为最初的对象类型。不是特别容易理解,乍一看多此一举,让人匪夷所思。其实,这么做是有原因的,是因为Flink的序列化机制是其自定义的,并且跟其自主管理内存紧密联系在一起(想了解其自主内存管理的可参看我之前的系列文章)。而自主内存管理又涉及到二进制数据的存储。FromElementsFunction支持从某个check point部分恢复,所以必须先还原其原先的存储位置(通过序列化),然后跳过不需要emit的元素,然后再发射需要发射的元素(将这些元素反序列化)。

常见连接器中的Source

Flink自身提供了一些针对第三方主流开源系统的连接器支持,它们有:

  • elasticsearch
  • flume
  • kafka(0.8/0.9版本)
  • nifi
  • rabbitmq
  • twitter

这些连接器有些可以同时作为sourcesink。因为我们今天的主题是source,所以我们先来看看以上这些被支持的连接器它们的source都是继承自刚刚我们谈到的哪些接口或者类。

  • kafka : RichParallelSourceFunction
  • nifi : RichParallelSourceFunction
  • rabbitmq : MultipleIdsMessageAcknowledgingSourceBase(因为rabbitmq具备非常成熟的ack机制,所以继承这个类是顺其自然的)

小结

这篇文章我们主要谈及了Flink的stream source相关的设计、实现。当然这个主题还没有完全谈完,还会有后续篇幅继续解读。




原文发布时间为:2016-05-05


本文作者:vinoYang


本文来自云栖社区合作伙伴CSDN博客,了解相关信息可以关注CSDN博客。

相关实践学习
基于Hologres轻松玩转一站式实时仓库
本场景介绍如何利用阿里云MaxCompute、实时计算Flink和交互式分析服务Hologres开发离线、实时数据融合分析的数据大屏应用。
Linux入门到精通
本套课程是从入门开始的Linux学习课程,适合初学者阅读。由浅入深案例丰富,通俗易懂。主要涉及基础的系统操作以及工作中常用的各种服务软件的应用、部署和优化。即使是零基础的学员,只要能够坚持把所有章节都学完,也一定会受益匪浅。
目录
相关文章
|
1月前
|
存储 人工智能 大数据
The Past, Present and Future of Apache Flink
本文整理自阿里云开源大数据负责人王峰(莫问)在 Flink Forward Asia 2024 上海站主论坛开场的分享,今年正值 Flink 开源项目诞生的第 10 周年,借此时机,王峰回顾了 Flink 在过去 10 年的发展历程以及 Flink社区当前最新的技术成果,最后展望下一个十年 Flink 路向何方。
363 33
The Past, Present and Future of Apache Flink
|
1月前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
1月前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
1月前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
28天前
|
存储 物联网 大数据
探索阿里云 Flink 物化表:原理、优势与应用场景全解析
阿里云Flink的物化表是流批一体化平台中的关键特性,支持低延迟实时更新、灵活查询性能、无缝流批处理和高容错性。它广泛应用于电商、物联网和金融等领域,助力企业高效处理实时数据,提升业务决策能力。实践案例表明,物化表显著提高了交易欺诈损失率的控制和信贷审批效率,推动企业在数字化转型中取得竞争优势。
102 16
|
11天前
|
自然语言处理 数据处理 索引
mindspeed-llm源码解析(一)preprocess_data
mindspeed-llm是昇腾模型套件代码仓,原来叫"modelLink"。这篇文章带大家阅读一下数据处理脚本preprocess_data.py(基于1.0.0分支),数据处理是模型训练的第一步,经常会用到。
29 0
|
2月前
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
68 12
|
1月前
|
PyTorch Shell API
Ascend Extension for PyTorch的源码解析
本文介绍了Ascend对PyTorch代码的适配过程,包括源码下载、编译步骤及常见问题,详细解析了torch-npu编译后的文件结构和三种实现昇腾NPU算子调用的方式:通过torch的register方式、定义算子方式和API重定向映射方式。这对于开发者理解和使用Ascend平台上的PyTorch具有重要指导意义。
|
1月前
|
安全 搜索推荐 数据挖掘
陪玩系统源码开发流程解析,成品陪玩系统源码的优点
我们自主开发的多客陪玩系统源码,整合了市面上主流陪玩APP功能,支持二次开发。该系统适用于线上游戏陪玩、语音视频聊天、心理咨询等场景,提供用户注册管理、陪玩者资料库、预约匹配、实时通讯、支付结算、安全隐私保护、客户服务及数据分析等功能,打造综合性社交平台。随着互联网技术发展,陪玩系统正成为游戏爱好者的新宠,改变游戏体验并带来新的商业模式。
|
4月前
|
运维 数据处理 数据安全/隐私保护
阿里云实时计算Flink版测评报告
该测评报告详细介绍了阿里云实时计算Flink版在用户行为分析与标签画像中的应用实践,展示了其毫秒级的数据处理能力和高效的开发流程。报告还全面评测了该服务在稳定性、性能、开发运维及安全性方面的卓越表现,并对比自建Flink集群的优势。最后,报告评估了其成本效益,强调了其灵活扩展性和高投资回报率,适合各类实时数据处理需求。

推荐镜像

更多
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等