什么是Flink?优势是什么,为什么选择Flink?

ApacheFlink是一个框架和分布式处理引擎,用于在无界和有界数据流上进行有状态计算。Flink被设计为在所有通用集群环境中运行,以内存速度和任何规模执行计算。

经典的MapReduce程序

算子的概念:可以并行执行的方法称之为算子。

  1. hadoop:在MR程序执行时,基本上每一次的数据交换都会读写磁盘。在复杂的业务逻辑下,由于执行的job任务多造成多次的磁盘读写,严重的影响了计算的时效性。这就是第一代计算框架hadoop的不足。
  2. Tez:Tez是一个Hive的运行引擎,优化业务之间的读写磁盘次数,性能优于MR。
  3. Spark:Spark的设计模式是读取集群中的数据后,在内存中存储和运算,直到全部运算完毕后,再存储到集群中。
  4. Flink:在批处理的性能与Spark是差不多的,在底层设计的模式上Spark是以批处理为出发点,流是批处理的一种特例,Flink是以流处理为出发点,批处理是流的一种特例。

总结:在处理的的效率上MR的计算方式基本上被淘汰了。在批处理方面Spark&Flink性能是差不多的。在流处理上Spark的SparkStreaming以微批次模仿流处理,实现秒级计算;Flink一行一行处理实现毫秒级计算,在批处理上也被称为有限的流。

Flink架构&批流一体

flink1.9之前的架构

在 Flink1.9以前的架构上,负责物理执行环境的 Runtime 层是统一的流处理,上面分别有独立的 DataStream 和 DataSet 两个 API,两者基于不同的任务类型(Stream Task/Batch Task)和 UDF 接口(Transformation/Operator)。而更上层基于关系代数的 Table API 和 SQL API 虽然表面上是统一的,但实际上编程入口(Environment)是分开的,且内部将流批作业分别翻译到 DataStream API 和 DataSet API 的逻辑也是不一致的。

flink1.10之后的架构

Flink编程API

FlinkAPI官网:https://ci.apache.org/projects/flink/flink-docs-release-1.13/zh/docs/dev/dataset/overview/

1、批处理API

编程步骤

  1. 创建一个执行环境,表示当前执行程序的上下文 ,ExecutionEnvironment 。
  2. 读取数据。
  3. 运用算子处理数据逻辑。
  4. 结果数据存储。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//创建执行环境
ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
//读取数据源
DataSet<String> dataSource = env.readTextFile("data.txt");
//处理数据
DataSet<> dataMap = dataSource.flatMap(new FlatMapFunction<String, String>() {
@Override
public void flatMap(String line, Collector<String> out) throws Exception {
String[] split = line.split(" ");
for (String word : split) {
collector.collect(word);
}
}
});
//打印结果
dataMap.print();

2、流处理API

1
2
3
4
5
6
7
8
9
10
11
12
13
//创建环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
//获取数据源
DataStreamSource<List<Map>> esSoure = bsEnv.addSource(new EsSource());
//逻辑处理
DataStream<> dataFilter = esSoure.filter(new FilterFunction<Map>() {
@Override
public boolean filter(Map value) throws Exception {
return value.get("user_id") != null;
}
});
//结果写入clickhouse
dataFilter.addSink(new Clickhouse());

3、Flink 中的 Window

streaming 流式计算是一种被设计用于处理无限数据集的数据处理引擎,而无限数据集是指一种不断增长的本质上无限的数据集,而 window 是一种切割无限数据为有限块进行处理的手段。

Window 是无限数据流处理的核心,Window 将一个无限的 stream 拆分成有限大 小的”buckets”桶,我们可以在这些桶上做计算操作。

Window 可以分成两类:

  1. CountWindow:按照指定的数据条数生成一个 Window,与时间无关。
  2. TimeWindow:按照时间生成 Window。 对于 TimeWindow,可以根据窗口实现原理的不同分成三类:滚动窗口(Tumbling Window)、滑动窗口(Sliding Window)和会话窗口(Session Window)。
  • 滚动窗口将数据依据固定的窗口长度对数据进行切片。时间对齐,窗口长度固定,没有重叠。
  • 滑动窗口是固定窗口的更广义的一种形式,滑动窗口由固定的窗口长度和滑动间隔组成。 时间对齐,窗口长度固定,可以有重叠。例如,你有 10 分钟的窗口和 5 分钟的滑动,那么每个窗口中 5 分钟的窗口里包含着上个 10 分钟产生的数据。
  • 会话窗口由一系列事件组合一个指定时间长度的 timeout 间隙组成,类似于 web 应用的 session,也就是一段时间没有接收到新数据就会生成新的窗口。

4、时间语义与 Wartermark

时间语义

  1. Event Time:是事件创建的时间。它通常由事件中的时间戳描述,例如采集的日志数据中,每一条日志都会记录自己的生成时间,Flink 通过时间戳分配器访问事件时间戳。
  2. Ingestion Time:是数据进入 Flink 的时间。
  3. Processing Time:是每一个执行基于时间操作的算子的本地系统时间,与机器相关,默认的时间属性就是 Processing Time。
1
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime) 

Wartermark

流处理从事件产生,到流经 source,再到 operator,中间是有一个过程和时间的,虽然大部分情况下,流到 operator 的数据都是按照事件产生的时间顺序来的,但是也不排除由于网络、分布式等原因,导致乱序的产生,所谓乱序,就是指 Flink 接收到的事件的先后顺序不是严格按照事件的 Event Time 顺序排列的。

那么此时出现一个问题,一旦出现乱序,如果只根据 eventTime 决定 window 的运行,我们不能明确数据是否全部到位,但又不能无限期的等下去,此时必须要有个机制来保证一个特定的时间后,必须触发 window 去进行计算了,这个特别的机制,就是 Watermark。

状态编程

容错机制、快照