批处理 是有界数据流处理的范例。在这种模式下,可以选择在计算结果输出之前输入整个数据集,这也就意味着你可以对整个数据集的数据进行排序、统计或汇总计算后再输出结果。
流处理 正相反,其涉及无界数据流。至少理论上来说,它的数据输入永远不会结束,因此程序必须持续不断地对到达的数据进行处理。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LnYlQ9Z7-1640774068983)(20200914090758635.png)]
Apache Flink 是一个在无界和有界数据流上进行状态计算的框架和分布式处理引擎。
JobManager 具有许多与协调 Flink 应用程序的分布式执行有关的职责:它决定何时调度下一个 task(或一组 task)、对完成的 task 或执行失败做出反应、协调 checkpoint、并且协调从失败中恢复等等。这个进程由三个不同的组件组成:
ResourceManager
ResourceManager 负责 Flink 集群中的资源提供、回收、分配 - 它管理 task slots,这是 Flink 集群中资源调度的单位(请参考TaskManagers)。Flink 为不同的环境和资源提供者(例如 YARN、Mesos、Kubernetes 和 standalone 部署)实现了对应的 ResourceManager。在 standalone 设置中,ResourceManager 只能分配可用 TaskManager 的 slots,而不能自行启动新的 TaskManager。
Dispatcher
Dispatcher 提供了一个 REST 接口,用来提交 Flink 应用程序执行,并为每个提交的作业启动一个新的 JobMaster。它还运行 Flink WebUI 用来提供作业执行信息。
JobMaster
JobMaster 负责管理单个JobGraph的执行。Flink 集群中可以同时运行多个作业,每个作业都有自己的 JobMaster。
始终至少有一个 JobManager。高可用(HA)设置中可能有多个 JobManager,其中一个始终是 leader,其他的则是 standby
TaskManager(也称为 worker)执行作业流的 task,并且缓存和交换数据流。
必须始终至少有一个 TaskManager。在 TaskManager 中资源调度的最小单位是 task slot。TaskManager 中 task slot 的数量表示并发处理 task 的数量。请注意一个 task slot 中可以执行多个算子。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fDzknGDu-1640774068984)(processes.svg)]
其中slot个数等于最大并行数,一个slot中可以执行多个算子
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qsmSMpLE-1640774068984)(tasks_slots.svg)]
默认情况下,Flink 允许 subtask 共享 slot,即便它们是不同的 task 的 subtask,只要是来自于同一作业即可。结果就是一个 slot 可以持有整个作业管道。允许 slot 共享有两个主要优点:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tWVHv2Cc-1640774068985)(https://ci.apache.org/projects/flink/flink-docs-release-1.12/fig/slot_sharing.svg)]
slot内存是隔离的互不影响 同一个taskmanager上共用cpu
前后发生的不同任务可以共享同一个slot
slot共享可以让资源充分利用
main()
方法在集群上而不是客户端上运行。提交作业是一个单步骤过程:无需先启动 Flink 集群,然后将作业提交到现有的 session 集群;相反,将应用程序逻辑和依赖打包成一个可执行的作业 JAR 中,并且集群入口(ApplicationClusterEntryPoint
)负责调用 main()
方法来提取 JobGraph。例如,这允许你像在 Kubernetes 上部署任何其他应用程序一样部署 Flink 应用程序。因此,Flink Application 集群的寿命与 Flink 应用程序的寿命有关。注意: Flink Job 集群可以看做是 Flink Application 集群”客户端运行“的替代方案。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C0leiDOR-1640774068986)(levels_of_abstraction.svg)]
Flink API 最底层的抽象是Stateful Stream Processing, 抽象实现为process Function(获取状态、注册定时器、获取当前事件的信息)
Flink API 第二层抽象是 Core APIs(使用api中的算子进行相对简单的操作)
Flink API 第三层抽象是 Table API(使用类sql语言进行更加简洁的操作,Flink 允许用户在编写应用程序时将 Table API 与 DataStream/DataSet API 混合使用)
Flink API 最顶层抽象是 SQL(直接使用sql进行操作)
Event Time : 事件创建的时间 (一般为kafka中消息中的时间字段,为事件消息的创建事件)
Ingestion Time:数据进入Flink的时间 (如source读取到kafka流时的时间)
Processing Time:执行操作算子的本地系统时间,与机器有关(算子执行当前时间时的时间)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SUWpr12S-1640774068986)(f461d93e248f0c51291055debd50ad00.png)]
实时计算的输入数据是持续不断的,当我们进行窗口操作时需要一个有效的进度指标。Watermark就是一种衡量事件进展的有效机制。(窗口关闭前闭后开)
注意:在上有游数据源输入是多个分区(分片)输入时,Watermark取所有并行数据源中Watermark的最小值。(也就是说如果有一个分区无数据发送,Watermark不会更新)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U5lO3eKk-1640774068987)(parallel_kafka_watermarks.svg)]
作用:watermark处理乱序数据,在开窗口操作时,设置watermark和延迟时间,等待乱序时间到来触发计算。
Watermark策略:
会话窗口不重叠,也没有固定的开始和结束时间。当会话窗口在特定时间段内没有接收到元素时,会话窗口将关闭。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1MQZuw7b-1640774068987)(session-windows.svg)]
可指定窗口大小和滑动步长,具有固定长度的窗口长度,可能重叠。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-egi2HuRN-1640774068988)(sliding-windows.svg)]
翻滚窗口具有固定大小并且不重叠
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-77xKNPPp-1640774068988)(tumbling-windows.svg)]
滑动窗口计算
@Override
public Collection<TimeWindow> assignWindows(
Object element, long timestamp, WindowAssignerContext context) {
if (timestamp > Long.MIN_VALUE) {
List<TimeWindow> windows = new ArrayList<>((int) (size / slide));
long lastStart = TimeWindow.getWindowStartWithOffset(timestamp, offset, slide);
for (long start = lastStart; start > timestamp - size; start -= slide) {
windows.add(new TimeWindow(start, start + size));
}
return windows;
} else {
throw new RuntimeException(
"Record has Long.MIN_VALUE timestamp (= no timestamp marker). "
+ "Is the time characteristic set to 'ProcessingTime', or did you forget to call "
+ "'DataStream.assignTimestampsAndWatermarks(...)'?");
}
}
// 计算最后一个窗口的开始时间
public static long getWindowStartWithOffset(long timestamp, long offset, long windowSize) {
return timestamp - (timestamp - offset + windowSize) % windowSize;
}
这块来一个算窗口的图
ProcessFunction
是一个低级流处理操作,可以访问所有(非循环)流应用程序的基本构建块:
Checkpoint 是 Flink 应用状态的一个一致性副本,定时记录了程序运行中的算子状态、Keyed State等,使得 Flink 能够恢复状态和在流中的位置,从而向应用提供和无故障执行时一样的语义。(可自动恢复)
程序从checkpoint恢复时读取的是最新一次的完整Checkpoint 。
设置Exactly Once,barrier对齐(多分区时)。
对于并行度是1的情况,每个算子收到barrier时,对barrier之前的计算结果进行checkpoint。
对于并行度是n的情况,每个算子收到上游所有的barrier时,对之前的的所有计算结果进行checkpoint。在这之前收到单个分区的barrier后,将barrier后的数据进行缓存,不向下游发送。
checkpoint调优
背压问题
优化GC: 如果频繁发生full GC
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qx0vwEnr-1640774068989)(image-20210831192643652.png)]