1.flink快速入门

前言

下图表示的是一个简单的flink-job的计算图,这种图被称为DAG(有向无环图),表示的这个任务的计算逻辑,无论是spark、hive、还是flink都会把用户的计算逻辑转换为这样的DAG,数据的计算按照DAG触发,理论上只要构建出这样一个DAG图,就可以描述清楚用户的计算逻辑,在DAG的基础上,将Node并行化就可以将整个job并行化。

在Flink之前的上一代流式计算框架Apache Storm的hello world如下(节选了一部分):从storm的helloworld代码可以很清楚的看到storm构建dag是依赖用户自己构建,用户将自己脑中的dag图使用代码画出来,line2创建了一个DAG的builder,line4新增了一个节点,line6也新增了一个节点,dag画完了后在line16将DAG生成出来提交到集群执行。从这里可以看出storm构建DAG的逻辑是用户心中有图,自己画出来。

java 复制代码
// 实例化TopologyBuilder类。
TopologyBuilder topologyBuilder = new TopologyBuilder();
// 设置喷发节点并分配并发数,该并发数将会控制该对象在集群中的线程数。
topologyBuilder.setSpout("SimpleSpout", new SimpleSpout(), 1);
// 设置数据处理节点并分配并发数。指定该节点接收喷发节点的策略为随机方式。
topologyBuilder.setBolt("SimpleBolt", new SimpleBolt(), 3).shuffleGrouping("SimpleSpout");
Config config = new Config();
config.setDebug(true);
if (args != null && args.length > 0) {
    config.setNumWorkers(1);
    StormSubmitter.submitTopology(args[0], config, topologyBuilder.createTopology());
} else {
    // 这里是本地模式下运行的启动代码。
    config.setMaxTaskParallelism(1);
    LocalCluster cluster = new LocalCluster();
    cluster.submitTopology("simple", config, topologyBuilder.createTopology());
}

再看一下flink的helloworld,代码如下,该代码对应的DAG就是文章开头的图片,下面代码中line3获取一个执行的环境,line6从9999端口读入数据,line7做flatmap,ling15做分组操作,line20对分组的数据做sum聚合,line22执行任务;通过和storm的helloworld的对比,可以很明显的看出flink代码中很难看出DAG的样子,flink专注的并不是用户去画DAG,而是用户表达清楚自己的业务,由flink将DAG画出并执行,这也是flink会将storm慢慢淘汰的原因之一

java 复制代码
public class Demo01_hello {
    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(2);

        env.socketTextStream("localhost", 9999)
                .flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() {
                    @Override
                    public void flatMap(String value, Collector<Tuple2<String, Integer>> out) throws Exception {
                        for (String s : value.split(" ")) {
                            out.collect(Tuple2.of(s, 1));
                        }
                    }
                })
                .keyBy(new KeySelector<Tuple2<String, Integer>, String>() {
                    @Override
                    public String getKey(Tuple2<String, Integer> value) throws Exception {
                        return value.f0;
                    }
                }).sum(1).print();

        env.execute();
    }
}

总结一下:flink目前提供了多种api,包裹flink-stream-api,table/sql-api,python-api,这些api的表象不同,但是底层都是将用户表达的逻辑翻译为DAG部署到集群上

那就从Hello-world开始吧

大数据的hello-word都是从wordcount开始的,这是mapreduce时代的传承,让我们再看一下flink的wordcount

java 复制代码
public class Demo01_hello {
    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(2);

        env.socketTextStream("localhost", 9999)
                .flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() {
                    @Override
                    public void flatMap(String value, Collector<Tuple2<String, Integer>> out) throws Exception {
                        for (String s : value.split(" ")) {
                            out.collect(Tuple2.of(s, 1));
                        }
                    }
                })
                .keyBy(new KeySelector<Tuple2<String, Integer>, String>() {
                    @Override
                    public String getKey(Tuple2<String, Integer> value) throws Exception {
                        return value.f0;
                    }
                }).sum(1).print();

        env.execute();
    }
}

line3从StreamExecutionEnvironment获取了一个执行环境,这个环境在本地就是local的,在yarn上就是yarn的,在k8s上就是k8s的

line4设置任务的并行度,这里遇到了第一个概念:并行度,并行度表示任务的并行个数,比如数据源kafka有2个分区,那么最佳的并行度就是2,因为一个分区只能被一个消费者消费,并行度大于2则多余的消费者消费不到数据

line6设置了数据源为socket,监听9999端口

line7对数据源的数据做flatmap操作,输入是string,输出是tuple2<string,integer>

line15对tuple2<string,integer>做了分组操作,按照string分组,这里涉及了另一个概念shuffle,shuffle就是打乱的意思

line20对分组后的数据tuple2<string,integer>做了sum操作,计算出每一个string的数量

ling22执行任务

下图展示了该任务如何从代码变成可以运行的执行图运行在分布式环境中

可以看到上图中有四张图,编写的代码会经历

StreamGraph -> JobGraph -> ExecutionGraph -> 物理执行图,最终提交到集群执行

(1)StreamGraph

a)StreamNode:表示每一个operator,并且携带了这个operator的若干信息

b)StreamEdge:表示streamnode之间的边,边上还携带了标识:rebalance、hash、forward,表示streamnode之间的数据传输方式

c)StreamGraph其实已经很像前言中的dag图了,但是还有些不同

(2)JobGraph

a)JobVertex:streamgraph中的streamnode如果存在可以优化的情况,比如operator-chain,那么多个streamnode就可以合并为一个jobvertex,operator-chain的条件是streamedge=forward且前后两个streamnode并行度相同

b) IntermediateDataset:jobvertex的产出数据,即若干个operator处理后的结果集

c)JobEdge:数据传输通道,从intermediatedataset传输数据到下游jobvertex

(3)ExecutionGraph

a)ExecutionVertex: jobvertex的并行化节点

b)ExecutionJobVertex:jobvertex对应的节点,一一对应

c)IntermediateResultPartition: 表示ExecutionVertex的输出结果,一个ExecutionVertex对应一个IntermediateResultPartition

d)IntermediateResult:和IntermediateDataset一一对应

e)ExecutionEdge:连接IntermediateResultPartition和ExecutionVertex一一对应

(4)物理执行图

a)Task:具体的调度task,封装了operator的操作,包括用户的逻辑

b)ResultPartition:对应IntermediateResultPartition,一一对应

c)ResultSubPartition:是Resultpartition的子分区,他的数量和下游的task有关,如果source算子就一个,所以他的ResultPartition就一个,但是下游有两个flatmap算子,所以这个ResultPartition会分成2个ResultSubPartition,分别给下游两个flatmap算子消费

d)InputChannel:连接ResultSubPartition和下游task算子的数据通道

相关推荐
大数据追光猿2 小时前
Python应用算法之贪心算法理解和实践
大数据·开发语言·人工智能·python·深度学习·算法·贪心算法
人类群星闪耀时3 小时前
物联网与大数据:揭秘万物互联的新纪元
大数据·物联网·struts
warrah9 小时前
flink-cdc同步数据到doris中
flink·doris
坚定信念,勇往无前9 小时前
Spring Boot中整合Flink CDC 数据库变更监听器来实现对MySQL数据库
数据库·spring boot·flink
桃林春风一杯酒9 小时前
HADOOP_HOME and hadoop.home.dir are unset.
大数据·hadoop·分布式
桃木山人10 小时前
BigData File Viewer报错
大数据·java-ee·github·bigdata
B站计算机毕业设计超人10 小时前
计算机毕业设计Python+DeepSeek-R1高考推荐系统 高考分数线预测 大数据毕设(源码+LW文档+PPT+讲解)
大数据·python·机器学习·网络爬虫·课程设计·数据可视化·推荐算法
数造科技10 小时前
紧随“可信数据空间”政策风潮,数造科技正式加入开放数据空间联盟
大数据·人工智能·科技·安全·敏捷开发
undo_try11 小时前
大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(2)
flink·bigdata·paimon
逸Y 仙X13 小时前
Git常见命令--助力开发
java·大数据·git·java-ee·github·idea