专栏名称: IT大咖说
大咖干货,不再错过。 让不在大会现场的程序猿、攻城狮也能体验现场的精彩瞬间。
目录
相关文章推荐
国际旅游岛商报  ·  发生大规模冲突!足协通报 ·  4 小时前  
国际旅游岛商报  ·  发生大规模冲突!足协通报 ·  4 小时前  
51好读  ›  专栏  ›  IT大咖说

超级大佬用4500字带你彻底吃透开源流计算框架之ApacheFlink

IT大咖说  · 公众号  ·  · 2024-04-17 20:00

正文

A pache Flink

随着流计算领域的不断发展,关于流计算的理论和模型逐渐清晰和完善。Flink是这些流计算领域最新理论和模型的优秀实践。相比Spark在批处理领域的流行,Apache Flink(简称Flink)可以说是目前流计算领域最耀眼的新贵了。Flink是一个分布式流处理和批处理平台,相比Spark偏向于批处理,Flink的核心是流计算引擎。

系统架构

Flink的系统架构如图6-7所示。Flink是一个主从(master/worker)架构的分布式系统。主节点负责调度流计算作业,管理和监控任务执行。当主节点从客户端接收到与作业相关的Jar包和资源后,便对其进行分析和优化,生成执行计划,即需要执行的任务,然后将相关的任务分配给各个从节点,由从节点负责任务的具体执行。

Flink可以部署在诸如YARN、Mesos和Kubernetes等分布式资源管理器上,其整体架构与Storm、Spark Streaming等分布式流计算框架类似。

与这些流计算框架不同的是,Flink明确地把状态管理(尤其是流信息状态管理)纳入其系统架构中了。

图6-7 Flink的系统架构

在Flink节点执行任务的过程中,可以将状态保存到本地,然后通过checkpoint机制,再配合诸如HDFS、S3和NFS这样的分布式文件系统,Flink在不降低性能的同时实现了状态的分布式管理。

流的描述

在Flink中,DataStream用来描述数据流。DataStream在Flink中扮演的角色犹如Spark中的RDD。值得一提的是,Flink也支持批处理DataSet的概念,DataSet内部同样由DataStream构成。在Flink中,这种将批处理视为流处理特殊情况的做法与Spar.Streaming中将流处理视为连续批处理的做法截然相反。

Flink的数据输入(Source)、处理(Transformation)和输出(Sink)均与DataStream有关。

·Source:用于描述Flink流数据的输入源,输入的流数据表示为DataStream。Flink的Source可以是消息中间件、数据库、文件系统或其他各种数据源。

·Transformation:将一个或多个DataStream转化为一个新的DataStream,是Flink实施流处理逻辑的地方。目前,Flink提供Map、FlatMap、Filter、KeyBy、Reduce、Fold、Aggregations、Window、Union、Join、Split、Select和Iterate等类型的Trans-formation。

·Sink:Flink将DataStream输出到外部系统的地方,如写入控制台、数据库、文件系统或消息中间件等。

流的执行

我们从流的输入、流的处理、流的输出和反向压力4个方面来讨论Flink中流的执行过程。

1.流的输入

Flink使用
StreamExecutionEnvironment.addSource设置流的数据源Source。为了使用方便,Flink在StreamExecutionEnvironment.addSource的基础上提供了一些内置的数据源实现。


StreamExecutionEnvironment提供的输入方式主要包含以下4类。

·基于文件的输入:从文件中读入数据作为流数据源,如readTextFile和readFile等。

·基于套结字的输入:从TCP套接字中读入数据作为流数据源,如socketTextStream等。

·基于集合的输入:用集合作为流数据源,如fromCollection、fromElements、fromParallelCollection和generateSequence等。

·自定义输入:
StreamExecutionEnvironment.addSource是通用的流数据源生成方法,用户可以在其基础上开发自己的流数据源。一些第三方数据源,如flink-connector-kafka中的FlinkKafkaConsumer08就是针对Kafka消息中间件开发的流数据源。

Flink将从数据源读出的数据流表示为DataStream。下面的示例演示了从TCP连接中构建文本数据输入流的过程。

final StreamExecutionEnvironment env =

StreamExecutionEnvironment.getExecutionEnvironment();

DataStream text = env.socketTextStream("localhost", 9999, "\n");

2.流的处理

Flink对流的处理是通过DataStream的各种转化操作完成的。相比Spark中DStream的转化操作混淆了流数据状态管理和流信息状态管理,Flink的设计思路更加清晰,明确地将流信息状态管理从流数据状态管理中分离出去。

DataStream的转换操作只包含两类操作,一类是常规的流式处理操作,如map、filter、reduce、count、transform等。另一类是流数据状态相关的操作,如union、join、cogroup、window等。这两类操作都是针对流本身的处理和管理。从设计模式中单一职责原则的角度来看,Flink关于流的设计显然更胜一筹。

下面是一个对DataStream进行转化操作的例子。

DataStream windowCounts = text

.flatMap(new FlatMapFunction () {

@Override

public void flatMap(String value, Collector out) {

for (String word : value.split("\\s")) {

out.collect(new WordWithCount(word, 1L));

}

}

})

.keyBy("word")

.timeWindow(Time.seconds(5), Time.seconds(1))

.reduce(new ReduceFunction () {

@Override

public WordWithCount reduce(WordWithCount a, WordWithCount b) {

return new WordWithCount(a.word, a.count + b.count);

}

});

在上面的例子中,先将从socket中读出文本流lines,对每行文本分词后,用flatMap转化为单词计数元组流pairs;然后用keyBy对计数元组流pairs从分组第一个元素(即word)开始进行分组,形成分组的计数元组流keyedPairs;最后用timeWindow以5秒为时间窗口对分组后的流进行划分,并在窗口上进行sum聚合计算,最终得到wordCounts,即每5秒各个单词出现的次数。

3.流的输出

Flink使用DataStream.addSink设置数据流的输出方法。另外,Flink在DataStream.addSource的基础上提供了一些内置的数据流输出实现。DataStream提供的输出API主要包含以下4类。

·输出到文件系统:将流数据输出到文件系统,如writeAsText、writeAsCsv和write-UsingOutputFormat。

·输出到控制台:将数据流输出到控制台,如print和printToErr。

·输出到套接字:将数据流输出到TCP套接字,如writeToSocket。

·自定义输出:DataStream.addSink是最通用的流数据输出方法,用户可以在其基础上开发自己的流数据输出方法。例如,flinkconnector-kafka中的FlinkKafkaProducer011就是针对Kafka消息中间件开发的流输出方法。

下面的示例演示了将DataStream表示的流数据输出到控制台的过程。

windowCounts.print().setParallelism(1);

4.反向压力

Flink对反向压力的支持非常好,不仅实现了反向压力功能,而且直接内置了反向压力的监控功能。Flink采用有限容量的分布式阻塞队列来进行数据传递,当下游任务从消费队列读取消息的速度过慢时,上游任务往队列中写入消息的速度就非常自然地减慢了。这种反向压力的实现思路和使用JDK自带的BlockingQueue实现反向压力的方法基本一致。

值得一提的是,与Storm和Spar.Streaming需要明确打开启动开关才能使用反向压力功能不一样的是,Flink的反向压力功能是其数据传送方案自带的,不需特别再去实现,使用时也无须特别打开启动开关。

流的状态

Flink是第一个明确地将流信息状态管理从流数据状态管理剥离出来的流计算框架。大多数流计算框架要么没有流信息状态管理,要么实现的流信息状态管理非常有限,要么流信息状态管理混淆在了流数据状态管理中,使用起来并不方便和明晰。







请到「今天看啥」查看全文