前面已经学习了flink的批处理WordCount,现在来学习下flink的流处理WordCount,其实和批处理差不多,区别在于获取执行环境方法和接收的数据方式不一样。批处理通过ExecutionEnvironment.getExecutionEnvironment
方法获取批处理执行环境,再通过readTextFile("inputParth")
方法获取文件,流处理通过StreamExecutionEnvironment.getExecutionEnvironment
获取流处理执行环境,再通过socketTextStream(host, port)
获取socket流数据。后续的统计处理逻辑一致。
先引入pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.fuyun</groupId>
<artifactId>flinkLearning</artifactId>
<version>1.0-SNAPSHOT</version>
<repositories>
<repository>
<id>aliyun</id>
<url>http://repository.apache.org/content/groups/snapshots/</url>
</repository>
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
<repository>
<id>jboss</id>
<url>http://repository.jboss.com/nexus/content/groups/public</url>
</repository>
</repositories>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<flink.version>1.12.0</flink.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-java</artifactId>
<version>${flink.version}</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-java</artifactId>
<version>${flink.version}</version>
<!-- provided在这表示此依赖只在代码编译的时候使用,运行和打包的时候不使用 -->
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java_2.11</artifactId>
<version>${flink.version}</version>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-scala_2.11</artifactId>
<version>${flink.version}</version>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-scala_2.11</artifactId>
<version>${flink.version}</version>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-clients_2.12</artifactId>
<version>${flink.version}</version>
</dependency>
</dependencies>
</project>
flink流处理代码
package com.fuyun.flink
import org.apache.flink.api.java.utils.ParameterTool
import org.apache.flink.streaming.api.scala._
object StreamingWordCount {
def main(args: Array[String]): Unit = {
//从外部命令中提取参数,作为socket主机名和端口号
val paramTool = ParameterTool.fromArgs(args)
val host = paramTool.get("host")
val port = paramTool.getInt("port")
// 创建流处理执行环境
val senv = StreamExecutionEnvironment.getExecutionEnvironment
// 设置并行度
senv.setParallelism(8)
// 接收socket文本流
//val inputDataStream = senv.socketTextStream("bigdata-training.fuyun.com", 9000)
val inputDataStream = senv.socketTextStream(host, port)
// 进行转换处理统计
val resultDataStream = inputDataStream
.flatMap(_.split("\\s"))
.filter(_.nonEmpty)
.map((_, 1))
.keyBy(0)
.sum(1)
// 打印统计结果
resultDataStream.print()
// 必须调用execute方法执行,不然不会触发执行操作,参数为jobName
senv.execute("stream word count")
}
}
IDEA执行
在IDEA的Run–>>Edit Configurations–>>program arguments配置host和port
配置完参数后在虚拟机上执行命令nc -lk 9000
, 然后在IDEA上执行程序,在虚拟机上输入单词,IDEA上将会看到统计结果。
IDEA上结果显示有会截图中前面的3>
的数字出现,因为在代码程序中设置了并行度为8,3>
及表示并行度的id为3,所以id不会大于8,并且并行度可以在程序内每个算计中都可以进行设置,比如上面的代码中在创建流处理环境后设置了并行度为8,并行度默认用计算机本身cpu核心数(如果程序中没有设置并行度),如果在算子中设置了并行度,则使用设置的并行度,比如在上面的代码中:resultDataStream.print()
改为resultDataStream.print().setParallelism(1)
时,打印的结果将不会出现类似3>
的结果,因为并行度只有1。