flink内容总结

一、flink简介

flink介绍

flink是一个分布式处理引擎,用于对无界和有界数据流进行有状态的计算。
* 流处理:数据大小未知,简单操作,及时响应,再次提取数据代价大,数据到达次序独立
* 批处理:数据大小固定,复杂操作,需要一段时间,数据量大,方便查询计算结果

无界流和有界流

无界流有一个开始但没有定义的结束。它们不会在生成时终止并提供数据。必须持续处理无界流,即必须在摄取事件后立即处理事件。无法等待所有输入数据到达,因为输入是无界的,并且在任何时间点都不会完成。处理无界数据通常要求以特定顺序(例如事件发生的顺序)摄取事件,以便能够推断结果完整性。

有界流具有定义的开始和结束。可以在执行任何计算之前通过摄取所有数据来处理有界流。处理有界流不需要有序摄取,因为可以始终对有界数据集进行排序。有界流的处理也称为批处理。

二、实时计算面临的挑战

1、数据处理唯一性(如何保证数据只处理一次(需要保证),至少一次(可能会丢数据),最多一次(可能会丢数据)?)

2、数据处理的及时性(采集的实时数据量过大的话,可能会导致短时间内处理不过来,如何保证数据能够及时的处理,不出现数据堆积)

3、数据处理层和存储层的可扩展性(如何根据采集的数据量大小动态扩缩容)

4、数据处理层和存储层的容错性(如何保证数据处理层和存储层高可用,出现故障时数据处理层和存储层服务依旧可用)

三、flink API

Process Function:它允许用户在应用程序中自由地处理来自单流或多流的事件(数据),并提供具有全局一致性和容错保障的状态。主要依靠events、state和time来实现复杂计算。

DataStream API(应用于有界/无界数据流场景)和 DataSet API(应用于有界数据集场景):Core APIs 提供的流式 API为数据处理提供了通用的模块组件,例如各种形式的用户自定义转换(transformations)、联接(joins)、聚合(aggregations)、窗口(windows)和状态(state)操作等。

Table API:是以表(Table)为中心的声明式编程(DSL)API,例如在流式数据场景下,它可以表示一张正在动态改变的表。 Table API 也提供了类似于关系模型中的操作,比如 select、project、join、group-by 和aggregate 等。Table API 程序是以声明的方式定义应执行的逻辑操作,而不是确切地指定程序应该执行的代码。尽管 Table API 使用起来很简洁并且可以由各种类型的用户自定义函数扩展功能,但还是比 Core API 的表达能力差。此外,Table API 程序在执行之前还会使用优化器中的优化规则对用户编写的表达式进行优化。

SQL:这层抽象在语义和程序表达式上都类似于 Table API,但是其程序实现都是 SQL 查询表达式。SQL 抽象与 Table API 抽象之间的关联是非常紧密的,并且 SQL 查询语句可以在 Table API 中定义的表上执行。

四、数据流编程模型

Source ----> Transformation ----> Sink

Source:

Flink 在流处理和批处理上的 source 大概有 4 类:

1、基于本地集合的 source。

2、基于文件的 source。

3、基于网络套接字的 source。

4、自定义的 source。自定义的 source 常见的有 Apache kafka、Amazon Kinesis Streams、RabbitMQ、Twitter Streaming API、Apache NiFi 等,当然你也可以定义自己的 source,实现SourceFunction。

Transformation:

数据转换的各种操作,有Map/FlatMap/Filter/KeyBy/Reduce/Aggregations/max/maxBy/min/minBy/window等。

Sink:

Flink 将转换计算后的数据发送的地点 。

Flink 常见的 Sink 大概有如下几类:

1、写入文件。

2、打印出来。

3、写入 socket。

4、自定义的sink。自定义的 sink 常见的有 Apache kafka、RabbitMQ、MySQL、ElasticSearch、Apache Cassandra、Hadoop FileSystem 等,同理你也可以定义自己的 sink,实现SinkFuncation。

五、flink架构

Client:Flink 作业在哪台机器上面提交,那么当前机器称之为Client。它会构建出DataFlow graph(数据流图),然后通过Client提交给JobManager。Client 不是运行时和程序执行的一部分,而是用于准备数据流并将其发送给 JobManager。之后,客户端可以断开连接(分离模式),或保持连接来接收进程报告(附加模式)。

JobManager:是主(master)节点,相当于Spark的Driver,相当于YARN里面的ResourceManager,生产环境中需要做高可用。JobManager会将任务进行拆分,发送到TaskManager上面执行。它决定何时调度下一个 task(或一组 task)、对完成的 task 或执行失败做出反应、协调 checkpoint、并且协调从失败中恢复等等。

TaskManager:是从节点(slave),相当于Spark的Executor,执行作业流的 task,并且缓存和交换数据流。

jobManager--Driver

Actor System -- 分布式通信工具(RPC分布式远程通信)

Scheduler -- 调度,相当于DAGScheduler

checkpoint -- 发起checkpoint

taskManager--Executor

TaskSlot--运行task

Memory & I/O Manager ---管理内存和磁盘数据

Network Manager-- 管理网络连接

Actor System -- 分布式通信工具(RPC分布式远程通信)

当Flink系统启动时,首先启动JobManager和一至多个TaskManager。JobManager负责协调Flink系统,

TaskManager则是执行并行程序的worker。JobManager将Job拆分成task,提交给TaskManager(worker)。当系统以本地形式启动时,一个JobManager和一个TaskManager会启动在同一个JVM中。

当一个程序被提交后,系统会创建一个Client来进行预处理,将程序转变成一个并行数据流(dataStream)的形式,交给JobManager和TaskManager执行。

六、Task Slot和资源

 

每个 TaskManager 有一个 slot,这意味着每个 task 组都在单独的 JVM 中运行(例如,可以在单独的容器中启动)。具有多个 slot 意味着更多 subtask 共享同一JVM。同一JVM 中的 task 共享 TCP 连接(通过多路复用)和心跳信息。它们还可以共享数据集和数据结构,从而减少了每个 task 的开销。

Flink 集群所需的 task slot 和作业中使用的最大并行度恰好一样。无需计算程序总共包含多少个 task(具有不同并行度)。

七、flink时间机制

三种时间机制:

1.EventTime 事件时间:事件发生的时间,在进行Flink流处理程序之前,这个时间就已经能包含在了事件中,并且可以从每个记录中提取事件时间戳。数据在传输过程中会出现乱序,通过水位线解决数据乱序问题。

2.ProcessingTime 处理时间:事件被处理时当前系统的时间。

3.IngestionTime 摄入时间:事件(日志,数据,消息)进入Flink的时间。

八、WaterMark

Flink WaterMark原理与实现 - 追风dylan - 博客园

在使用 EventTime 处理 Stream 数据的时候会遇到数据乱序的问题。

如何计算WaterMark的值?
Watermark = 进入Flink的最大的事件时间(mxtEventTime) — 指定的延迟时间(t)

有Watermark 的 Window 是怎么触发窗口函数?

如果有窗口的停止时间等于或者小于maxEventTime – t(当时的warkmark),那么这个窗口被触发执行

九、状态

flink程序中间计算结果会以状态的形式保存。

无状态流处理和有状态流处理的主要区别:无状态流处理分别接收每条输入数据,根据最新输入的数据生成输出数据;有状态流处理会维护状态,根据每条输入记录进行更新,并基于最新输入的记录和当前的状态值生成输出记录,即综合考虑多个事件之后的结果。

十、窗口

十一、flink常用算子

Map:在算子中得到一个元素并生成一个新元素data.map { x => x.toInt }

FlatMap:在算子中获取一个元素, 并生成任意个数的元素data.flatMap { str => str.split(" ") }

MapPartition:类似Map, 但是一次Map一整个并行分区data.mapPartition { in => in map { (_, 1) } }

Filter:如果算子返回true则包含进数据集, 如果不是则被过滤掉data.filter { _ > 100 }

Reduce:通过将两个元素合并为一个元素, 从而将一组元素合并为一个元素data.reduce { _ + _ }

ReduceGroup:将一组元素合并为一个或者多个元素data.reduceGroup { elements => elements.sum }

Aggregate:讲一组值聚合为一个值, 聚合函数可以看作是内置的Reduce函数data.aggregate(SUM, 0).aggregate(MIN, 2)data.sum(0).min(2)

Distinct:去重

Join:按照相同的Key合并两个数据集input1.join(input2).where(0).equalTo(1)同时也可以选择进行合并的时候的策略, 是分区还是广播, 是基于排序的算法还是基于哈希的算法input1.join(input2,JoinHint.BROADCAST_HASH_FIRST).where(0).equalTo(1)

OuterJoin:外连接, 包括左外, 右外, 完全外连接等left.leftOuterJoin(right).where(0).equalTo(1) { (left, right) => ... }

CoGroup:二维变量的Reduce运算, 对每个输入数据集中的字段进行分组, 然后join这些组

input1.coGroup(input2).where(0).equalTo(1)

Cross:笛卡尔积input1.cross(input2)

Union:并集input1.union(input2)

sortPartition:指定字段对分区中的数据进行排序

min、max、minBy、maxBy:求最大/最小值。

区别:minBy/maxBy会更新符合条件的整体数据,而min/max只会更新符合条件的那个字段。

十二、flink广播变量

广播变量可以理解为是一个公共的共享变量,我们可以把一个 dataset 数据集广播出去, 然后不同的 task 在节点上都能够获取到,这个数据在每个节点上只会存在一份。 如果不使用 broadcast,则在每个节点中的每个 task 中都需要拷贝一份 dataset 数据集, 比较浪费内存(也就是一个节点中可能会存在多份 dataset 数据)。

注意:因为广播变量是要把 dataset 广播到内存中,所以广播的数据量不能太大。

用法:

  • 在需要使用广播的操作后,使用withBroadcastSet 创建广播
  • 在操作中,使用 getRuntimeContext.getBroadcastVariable [广播数据类型] ( 广播名 ) 获取广播变量

十三、checkpoint

在 Flink 任务运行过程中,为了保障故障容错,会定期进行 Checkpoint 将状态信息保存到外部存储介质中,当 Flink 任务由于各种原因出现故障时,Flink 任务会自动从 Checkpoint 处恢复,这就是 Checkpoint 的作用。

1、checkpoint目录清除策略

  • DELETE_ON_CANCELLATION:仅当作业失败时,作业的 Checkpoint 才会被保留用于任务恢复。当作业取消时,Checkpoint 状态信息会被删除,因此取消任务后,不能从 Checkpoint 位置进行恢复任务。
  • RETAIN_ON_CANCELLATION:当作业手动取消时,将会保留作业的 Checkpoint 状态信息。注意,这种情况下,需要手动清除该作业保留的 Checkpoint 状态信息,否则这些状态信息将永远保留在外部的持久化存储中。

如果 Checkpoint 目录的清除策略配置为 DELETE_ON_CANCELLATION,那么在取消任务时 Checkpoint 的状态信息会被清理掉,我们就无法通过 Checkpoint 来恢复任务了。为了从 Checkpoint 中轻量级地进行任务恢复,我们需要将该参数配置为 RETAIN_ON_CANCELLATION。

2、Savepoint 与 Checkpoint 的区别

Flink 中还有一个 Savepoint 的概念,Savepoint 与 Checkpoint 类似,同样需要把状态信息存储到外部介质,当作业失败时,可以从外部存储中恢复。

checkpoint更轻量级,使用过程中优先使用checkpoint来恢复任务。

十四、Exactly-once

flink 中的一个大的特性就是exactly-once的特性,我们在一般的流处理程序中,会有三种处理语义

  • at most once : 至多一次,表示一条消息不管后续处理成功与否只会被消费处理一次,那么就存在数据丢失可能。
  • exactly once : 精确一次,表示一条消息从其消费到后续的处理成功,只会发生一次。
  • at least once :至少一次,表示一条消息从消费到后续的处理成功,可能会发生多次。

通常要求程序满足exactly-once,就是确保数据的准确性,不丢失,不重复。通过flink的checkpoint特性和两阶段提交,来实现exactly once。

十五、flink的两阶段提交

flink中两阶段提交是为了保证端到端的Exactly Once,主要依托checkpoint机制来实现。

1、 jobMaster 会周期性的发送执行checkpoint命令(start checkpoint);

2、当source端收到执行指令后会产生一条barrier消息插入到input消息队列中,当处理到barrier时会执行本地checkpoint, 并且会将barrier发送到下一个节点,当checkpoint完成之后会发送一条ack信息给jobMaster;

3、当DAG图中所有节点都完成checkpoint之后,jobMaster会收到来自所有节点的ack信息,那么就表示一次完整的checkpoint的完成;

4、JobMaster会给所有节点发送一条callback信息,表示通知checkpoint完成消息,这个过程是异步的,并非必须的,方便做一些其他的事情,例如kafka offset提交到kafka。

十六、flink特点

1、支持高吞吐、低延迟、高性能的流处理

2、支持带有事件时间的窗口(window)操作

3、支持有状态计算的Exactly-once语义

4、支持高度灵活的窗口(window)操作,支持基于time、count、session,以及data-driveb的窗口操作。(spark只有滑动和滚动窗口)

5、支持具有反压功能的持续流模型(避免内存不够导致的任务失败)

6、支持基于轻量级分布式快照(snapshot)实现的容错

7、一个运行时同时支持Batch on Streaming处理和Streaming处理(既可以做流处理也可以做批处理)

8、Flink在JVM内部实现了自己的内存管理,避免了出现oom(spark是JVM内存管理,可能出现oom)

9、支持迭代计算(机器学习)

十七、spark streaming和flink的区别

  1. 架构模型Spark Streaming 在运行时的主要角色包括:Master、Worker、Driver、Executor,Flink 在运行时主要包含:Jobmanager、Taskmanager和Slot。
  2. 任务调度Spark Streaming 连续不断的生成微小的数据批次,构建有向无环图DAG,Spark Streaming 会依次创建 DStreamGraph、JobGenerator、JobScheduler。Flink 根据用户提交的代码生成 StreamGraph,经过优化生成 JobGraph,然后提交给 JobManager进行处理,JobManager 会根据 JobGraph 生成 ExecutionGraph,ExecutionGraph 是 Flink 调度最核心的数据结构,JobManager 根据 ExecutionGraph 对 Job 进行调度。
  1. 时间机制Spark Streaming 支持的时间机制有限,只支持处理时间。 Flink 支持了流处理程序在时间上的三个定义:处理时间、事件时间、注入时间。同时也支持 watermark 机制来处理滞后数据。
  2. 容错机制对于 Spark Streaming 任务,我们可以设置 checkpoint,然后假如发生故障并重启,我们可以从上次 checkpoint 之处恢复,但是这个行为只能使得数据不丢失,可能会重复处理,不能做到恰好一次处理语义。Flink 则使用两阶段提交协议来解决这个问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值