Apache Flink 学习:系统特性学习
window窗口
窗口大小
窗口大小是用户自己设定的,但是窗口的起始和结束时间点是系统根据窗口大小和自然数进行设定的,不会出现设置了一分钟的窗口,统计的数据是2:30到3:30的数据
[window_start_time, window_end_time)根据窗口大小和自然数进行设定
如果window大小是3秒,那么1分钟内会把window划分为如下的形式:
1 | [00:00:00,00:00:03) |
如果window大小是10秒,则window会被分为如下的形式:
1 | [00:00:00,00:00:10) |
watermark
1 |
|
watermark = max( [当前已到达的时间戳最新的数据(currentMaxTimestamp)] - [最大乱序等待时间(maxOutOfOrderness)], watermark )
触发窗口运算条件
1.当前最新数据到达进行判断:当前到达event的time(timestamp) < watermark则触发,表示数据是超过了最大等待时间,已经延迟到达的,则会触发
2.当前最新数据到达进行判断:最新的watermark >= window_end_time(对于out-of-order以及正常的数据而言),在[window_start_time, window_end_time)中有数据存在
3.而且,这里要强调一点,watermark和currentMaxTimestamp是一个全局的值,不是某一个key下的值,所以即使不是同一个key的数据,其warmark也会增加
语义是:currentMaxTimestamp是当前到达的最大时间戳数据,代表时间戳为currentMaxTimestamp的数据已经到达了,所以所能等待的数据的时间戳(max_out_of_orderness)只能为watermark = currentMaxTimestamp - maxOutOfOrderness
窗口计算
Window reduce,Window aggregate 和 Window Fold 是增量聚合,每来一条数据就计算一次,高效
Window apply(Window process 的老版本) 和 Window process 是全量聚合,触发窗口计算时全量计算
被Keys化与非被Keys化Windows
要指定的第一件事是您的流是否应该使用keyedWindow,一般都与业务逻辑有关,比如说使用一分钟的窗口进行去重。使用keyBy(…)将您的无限流分成逻辑Key化的数据流。如果keyBy(…)未调用,则表示您的流不是被Keys化的。
对于被Key化的数据流,可以将传入数据(Object)的的任何属性用作键)。拥有被Key化的数据流将允许您的窗口计算由多个任务并行执行,因为每个Key化的数据流可以独立于其余任务进行处理。引用相同Keys的所有数据将被发送到同一个并行任务进行计算。
在非被Key化的数据流的情况下,您的原始流将不会被拆分为多个逻辑流,并且所有窗口逻辑将由单个任务执行,即并行度为1。
sql
1.在flinkSql中,如果使用groupBy,尽量使用窗口,否则会认为被groupBy的数据会默认人为整个窗口内的数据还没有到达,所以会一直等待,不会产出数据
update-mode: append / update
分为 update stream 模式和 append stream 模式
window聚合为append mode stream,groupby聚合为update mode stream
Flink生成 Timestamps 和 Watermarks
为了让event time工作,Flink需要知道事件的时间戳,这意味着流中的每个元素都需要分配其事件时间戳。这个通常是通过抽取或者访问事件中某些字段的时间戳来获取的。
时间戳的分配伴随着水印的生成,告诉系统事件时间中的进度。
这里有两种方式来分配时间戳和生成水印:
- 直接在数据流源中进行。
- 通过timestamp assigner和watermark generator生成:在Flink中,timestamp分配器也定义了用来发射的水印。
数据流源生成Timestamps和Watermarks
数据流源可以直接为它们产生的数据元素分配timestamp,并且他们也能发送水印。这样做的话,就没必要再去定义timestamp分配器了,需要注意的是:如果一个timestamp分配器被使用的话,由源提供的任何timestamp和watermark都会被重写。
时间戳分配器/水印生成器(Timestamp Assigners / Watermark Generators)
Timestamp分配器获取一个流并生成一个新的带有Timestamp元素和水印的流。如果原始流已经有时间戳和/或水印,则Timestamp分配程序将覆盖它们
Timestamp分配器通常在数据源之后立即指定,但这并不是严格要求的。通常是在timestamp分配器之前先解析(MapFunction)和过滤(FilterFunction)。在任何情况下,都需要在事件时间上的第一个操作(例如第一个窗口操作)之前指定timestamp分配程序。有一个特殊情况,当使用Kafka作为流作业的数据源时,Flink允许在源内部指定timestamp分配器和watermark生成器。更多关于如何进行的信息请参考Kafka Connector的文档。
直接在FlinkKafkaConsumer010上面使用assignTimestampsAndWatermarks可以根据kafka source的partitions的特性进行设置Timestamps和Watermarks,让用户做一些特殊的处理
Running timestamp extractors / watermark generators directly inside the Kafka source, per Kafka
partition, allows users to let them exploit the per-partition characteristics.
log
Web UI查找log
JobManger log: 展示整个作业的状态变化(例如,从create 到deploy到running再到failed),通过jobManger log可以查看作业历史失败的记录和直接原因。
TaskManager log: 调度到该TaskManager上的task 的打印的相关log。
shuffle
被keyBy的数据流中,相同的key的数据会被发送到同一个slot中运行(partitiner决定),也就是TaskManager中slot进行shuffle的过程
如果有多个producer并且producer的数量和partition数量相同,则每个producer写一个partition
Savepoints和Checkpoints
用 Data Stream API 编写的程序可以从 savepoint 继续执行。Savepoints 允许在不丢失任何状态的情况下升级程序和 Flink 集群。
Savepoints 是手动触发的 Checkpoints,它依靠常规的 Checkpoint 机制获取程序的快照并将其写入 state backend。在执行期间,程序会定期在 worker 节点上创建快照并生成 Checkpoints。对于恢复,Flink 仅需要最后完成的 Checkpoint,而一旦完成了新的 Checkpoint,旧的就可以被丢弃。
Savepoints 类似于这些定期的 Checkpoints,除了它们是由用户触发并且在新的 Checkpoints 完成时不会自动过期。你可以通过命令行 或在取消一个 job 时通过 REST API 来创建 Savepoints。