创建第一个 Flink 项目
一、运行环境介绍
Flink执行环境主要分为本地环境和集群环境,本地环境主要为了方便用户编写和调试代码使用,而集群环境则被用于正式环境中,可以借助Hadoop Yarn、k8s 或 Mesos等不同的资源管理器部署自己的应用。
环境依赖:【1】JDK环境:Flink核心模块均使用 Java开发,所以运行环境需要依赖 JDK,JDK版本需要保证在1.8以上。
【2】Maven编译环境:Flink的源代码目前仅支持通过 Maven进行编译,所以如果需要对源代码进行编译,或通过 IDE开发Flink Application,则建议使用 Maven作为项目工程编译方式。需要注意的是,Flink程序需要 Maven的版本在3.0.4及以上,否则项目编译可能会出问题,建议用户根据要求进行环境的搭建。
【3】IDEA:需要安装 scala 插件以及 scala 环境等;
二、Flink项目 Scala版 DataSet 有界流
需求:同进文件文件中的单词出现的次数;
【1】创建Maven项目,pom.xml 文件中配置如下依赖
1 <dependencies> 2 <dependency> 3 <groupId>org.apache.flink</groupId> 4 <artifactId>flink-scala_2.12</artifactId> 5 <version>1.10.0</version> 6 </dependency> 7 <!-- https://mvnrepository.com/artifact/org.apache.flink/flink-streaming-scala --> 8 <dependency> 9 <groupId>org.apache.flink</groupId> 10 <artifactId>flink-streaming-scala_2.12</artifactId> 11 <version>1.10.0</version> 12 </dependency> 13 </dependencies> 14 15 <build> 16 <plugins> 17 <!-- 该插件用于将Scala代码编译成class文件 --> 18 <plugin> 19 <groupId>net.alchim31.maven</groupId> 20 <artifactId>scala-maven-plugin</artifactId> 21 <version>3.4.6</version> 22 <executions> 23 <execution> 24 <goals> 25 <!--声明绑定到 maven 的compile阶段--> 26 <goal>compile</goal> 27 </goals> 28 </execution> 29 </executions> 30 </plugin> 31 <plugin> 32 <groupId>org.apache.maven.plugins</groupId> 33 <artifactId>maven-assembly-plugin</artifactId> 34 <version>3.0.0</version> 35 <configuration> 36 <descriptorRefs> 37 <descriptorRef>jar-with-dependencies</descriptorRef> 38 </descriptorRefs> 39 </configuration> 40 <executions> 41 <execution> 42 <id>make-assembly</id> 43 <phase>package</phase> 44 <goals> 45 <goal>single</goal> 46 </goals> 47 </execution> 48 </executions> 49 </plugin> 50 </plugins> 51 </build>
【2】resource 目录中添加需要进行统计的文件文件及内容
1 import org.apache.flink.api.scala._ 2 3 /** 4 * @Description 批处理 word count 5 * @Author zhengzhaoxiang 6 * @Date 2020/7/12 18:55 7 * @Param 8 * @Return 9 */ 10 object WordCount { 11 def main(args: Array[String]): Unit = { 12 //创建一个批处理的执行环境 13 val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment 14 //从文件中读取数据 15 var inputDateSet: DataSet[String] = env.readTextFile("E:\\Project\\flink\\src\\main\\resources\\wordcount.txt") 16 //基于Dataset 做转换,首先按空格打散,然后按照 word作为key做group by 17 val resultDataSet: DataSet[(String,Int)] = inputDateSet 18 .flatMap(_.split(" "))//分词得到所有 word构成的数据集 19 .map((_,1))//_表示当前 word 转换成一个二元组(word,count) 20 .groupBy(0)//以二元组中第一个元素作为key 21 .sum(1) //1表示聚合二元组的第二个元素的值 22 23 //打印输出 24 resultDataSet.print() 25 } 26 }
【4】统计结果展示:
三、Flink项目 Scala版 DataStream 无界流
【1】StreamWordCount.java 文件内容如下
1 package com.zzx.flink 2 3 import org.apache.flink.streaming.api.scala._ 4 5 object StreamWordCount { 6 def main(args: Array[String]): Unit = { 7 // 创建一个流处理执行环境 8 val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment 9 // 接受 socket 文本流 10 val inputDataStream: DataStream[String] = env.socketTextStream("hadoop1",6666); 11 //定义转换操作 word count 12 val resultDataStream: DataStream[(String,Int)] = inputDataStream 13 .flatMap(_.split(" "))//以空格分词,得到所有的 word 14 .filter(_.nonEmpty) 15 .map((_,1))//转换成 word count 二元组 16 .keyBy(0)//按照第一个元素分组 17 .sum(1)//按照第二个元素求和 18 19 resultDataStream.print() 20 21 //上面的只是定义了处理流程,同时定义一个名称。不会让任务结束 22 env.execute("stream word count word") 23 } 24 }
【2】我这里在 Hadoop1 中通过 nc -lk xxx 打开一个 socket通信
1 package com.zzx.flink 2 3 import org.apache.flink.api.java.utils.ParameterTool 4 import org.apache.flink.streaming.api.scala._ 5 6 object StreamWordCount { 7 def main(args: Array[String]): Unit = { 8 // 创建一个流处理执行环境 9 val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment 10 // 接受 socket 文本流 hostname:prot 从程序运行参数中读取 11 val params: ParameterTool = ParameterTool.fromArgs(args); 12 val hostname: String = params.get("host"); 13 val port: Int = params.getInt("port"); 14 val inputDataStream: DataStream[String] = env.socketTextStream(hostname,port); 15 //定义转换操作 word count 16 val resultDataStream: DataStream[(String,Int)] = inputDataStream 17 .flatMap(_.split(" "))//以空格分词,得到所有的 word 18 .filter(_.nonEmpty) 19 .map((_,1))//转换成 word count 二元组 20 .keyBy(0)//按照第一个元素分组 21 .sum(1)//按照第二个元素求和 22 23 resultDataStream.print() 24 25 //上面的只是定义了处理流程,同时定义一个名称。不会让任务结束 26 env.execute("stream word count word") 27 } 28 }