深入浅出Flink
Flink之基础知识
Flink的特性
处理无界和有界数据
flink既可以处理无界流,也可以处理有界流。
- 无界流:定义了流的开始,没有定义流的结束
- 有界流:既定义了流的开始,也定义了留的结束
Flink擅长处理有界和无界数据集。精确地时间控制和状态化使得Flink的运行时能够运行任何处理无界流的应用。有界流则由一些专为固定大小数据集特殊设计的算法和数据结构进行内部处理,产生了出色的性能。
部署到任意地方
flink是一个分布式系统,需要计算资源来执行应用程序。flink集成了常见的集群资源管理器。包括Yarn、Mesos、k8s,同时也可以作为独立集群运行
运行任意规模应用
Flink旨在任意规模运行有状态流式应用。Flink很容易维护非常大的应用程序状态。其异步和增量的检查点算法对处理延迟产生最小的影响,同时保证精确一次状态的一致性。
利用内存性能
有状态的Flink程序针对本地状态访问进行了优化。任务的状态始终保留在内存中,如果状态大小超过可用内存,则会保存在能高效访问的紫盘数据结构中。任务通过访问本地状态来进行所有的计算,从而产生非常低的处理延迟。Flink通过定期和异步地对本地状态进行持久化存储来保证故障场景下精确一次的状态一致性。
Flink核心概念
stateful
Task的执行状态,用来记录当前task中执行数据的结果。
Operator
各类操作的抽象,可以分为三类:source operator、transform Operator、sink Operator、
数据传输策略
forward strategy
1. 一个task的输出只发送给一个task作为输入
2. 如果两个task都在一个JVM中的话,可以避免网络开销
key based strategy(key by)
- 数据需要按照某个属性进行分组
- 相同key的数据需要传输给同一个task,在一个task中进行处理
broadcast strategy
广播策略
random strategy
- 数据随机的从一个task中传输给下一个operator所有的subtask
- 保证数据能均匀的传输给所有的subtask
Flink分布式运行环境
Flink分布式四层模型
flink代码开发就是要构件一个dataflow,这个dataflow运行需要经历如下四个阶段:
- Stream Graph(Client 端完成)
- Job Graph (Client端完成)
- Execution Graph(Job Manager端完成)
- Physical Execution Graph(发送到Task manager的执行图)
Flink任务分布式运行流程
Flink之State
State状态管理如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZG8XqsaV-1625458857300)(E:\IDEAWorkSpace\bigData-learn\笔记\flink\State状态管理.png)]
state: 一般指一个具体的task/operator的状态。State可以被记录,在失败的情况下数据还可以恢复,Flink中有两种基本类型的State:Keyed State,Operator State,他们都可以以两种形式存在:原始状态和托管状态
托管状态: 由Flink框架管理的状态,我们通常使用的是这种状态
原始状态: 由用户自行管理状态具体的数据结构,框架在做checkPoint的时候,使用byte[]来读写状态内容,对其内部数据结构义务所知。当实现一个用户自定义的Operator时,会使用该模式
State类型
- Operator State: state是task级别的state,即每个task对应一个state
- ListState
- BroadCastState
- Keyed State : 记录的是每个key的状态
- ValueState
- ListState
- MapState
- ReducingState
- AggregatingState
案列演示
Keyed state案例演示
ValueState
package org.spiral.myflink.state.keyed;
import org.apache.flink.api.common.functions.RichFlatMapFunction;
import org.apache.flink.api.common.state.ValueState;
import org.apache.flink.api.common.state.ValueStateDescriptor;
import org.apache.flink.api.common.typeinfo.Types;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.util.Collector;
import java.util.Objects;
/**
* 计算每三个Key的数据的平均值
* @author : spiral
* @since : 2021/3/24 - 下午8:34
*/
public class ValueStateMapFunction extends RichFlatMapFunction<Tuple2<Long, Long>, Tuple2<Long, Double>> {
private ValueState<Tuple2<Long, Long>> countAndSum;
@Override
public void open(Configuration parameters) throws Exception {
//定义State的描述
ValueStateDescriptor<Tuple2<Long, Long>> descriptor = new ValueStateDescriptor<>("average",
Types.TUPLE(Types.LONG, Types.LONG));
//初始化ValueState
countAndSum = getRuntimeContext().getState(descriptor);
}
@Override
public void flatMap(Tuple2<Long, Long> value, Collector<Tuple2<Long, Double>> out) throws Exception {
Tuple2<Long, Long> currentStates = countAndSum.value();
if (Objects.isNull(currentStates)) {
currentStates = Tuple2.of(0L, 0L);
}
currentStates.f0 = currentStates.f0 + 1;
currentStates.f1 = currentStates.f1 + value.f1;
countAndSum.update(currentStates);
if (currentStates.f0 == 3) {
out.collect(Tuple2.of(value.f0, currentStates.f1 / 3.0));
countAndSum.clear();
}
}
}
ListState
package org.