文章目录
- [1. 实战概述](#1. 实战概述)
- [2. 实战步骤](#2. 实战步骤)
-
- [2.1 准备数据文件](#2.1 准备数据文件)
- [2.2 创建Maven项目](#2.2 创建Maven项目)
- [2.3 添加项目相关依赖](#2.3 添加项目相关依赖)
- [2.4 添加Scala SDK](#2.4 添加Scala SDK)
- [2.5 创建日志属性文件](#2.5 创建日志属性文件)
- [2.6 创建HDFS配置文件](#2.6 创建HDFS配置文件)
- [2.7 在源程序目录里创建包](#2.7 在源程序目录里创建包)
- [2.8 词频统计 - 批处理模式](#2.8 词频统计 - 批处理模式)
-
- [2.7.1 创建`BatchWordCount`对象](#2.7.1 创建
BatchWordCount对象) - [2.7.2 运行程序,查看结果](#2.7.2 运行程序,查看结果)
- [2.7.1 创建`BatchWordCount`对象](#2.7.1 创建
- [2.9 词频统计 - 流处理模式](#2.9 词频统计 - 流处理模式)
-
- [2.9.1 创建`StreamingWordCount`对象](#2.9.1 创建
StreamingWordCount对象) - [2.9.2 运行程序,查看结果](#2.9.2 运行程序,查看结果)
- [2.9.1 创建`StreamingWordCount`对象](#2.9.1 创建
- [2.10 词频统计 - 处理流数据](#2.10 词频统计 - 处理流数据)
-
- [2.10.1 利用`nc`产生流数据](#2.10.1 利用
nc产生流数据) - [2.10.2 启动`nc`监听端口并保持开放](#2.10.2 启动
nc监听端口并保持开放) - [2.10.3 创建`StreamingDataWordCount`对象](#2.10.3 创建
StreamingDataWordCount对象) - [2.10.4 启动程序,利用`nc`输入数据,控制台查看结果](#2.10.4 启动程序,利用
nc输入数据,控制台查看结果) - [2.10.5 退出`nc`,程序结束](#2.10.5 退出
nc,程序结束)
- [2.10.1 利用`nc`产生流数据](#2.10.1 利用
- [3. 实战总结](#3. 实战总结)
1. 实战概述
- 本实战项目基于 Flink 1.20.5 与 Scala 语言,旨在构建一套完整的词频统计系统。项目涵盖了从 Maven 环境搭建、HDFS 数据准备到代码编写的全过程。核心开发了三种模式的处理程序:基于
BATCH模式的离线批处理、基于STREAMING模式的有界流处理,以及利用socketTextStream接入nc命令产生的无界数据流进行实时计算。通过对比不同模式下的执行结果,深入理解了 Flink 在批处理与流处理上的统一 API 应用。
2. 实战步骤
2.1 准备数据文件
-
创建本地文件
- 执行命令:
vim words.txt

- 执行命令:
-
创建HDFS目录
- 执行命令:
hdfs dfs -mkdir -p /wordcount/input

- 执行命令:
-
上传文件到HDFS
- 执行命令:
hdfs dfs -put words.txt /wordcount/input

- 执行命令:
2.2 创建Maven项目
-
配置项目基本信息

-
单击【Create】按钮,生成项目基本骨架

-
将
java改成scala
2.3 添加项目相关依赖
-
在Maven仓库里查看
Flink: Streaming Scala的最新版本是1.20.5
-
在
pom.xml文件里添加6个依赖
xml<dependencies> <!-- 1. Flink 核心库 (包含 TextLineInputFormat) --> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-core</artifactId> <version>1.20.5</version> </dependency> <!-- 2. Flink 流处理 API --> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-streaming-scala_2.12</artifactId> <version>1.20.5</version> </dependency> <!-- 3. Flink 客户端 (用于本地运行和提交) --> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-clients</artifactId> <version>1.20.5</version> </dependency> <!-- 4. 文件连接器 (提供 FileSource) --> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-connector-files</artifactId> <version>1.20.5</version> </dependency> <!-- 5. Flink Hadoop 兼容包 --> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-hadoop-compatibility_2.12</artifactId> <version>1.18.0</version> </dependency> <!-- 6. Hadoop 客户端 --> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>3.3.4</version> </dependency> </dependencies> -
设置源程序目录

-
刷新项目依赖

2.4 添加Scala SDK
- 操作录屏演示

- 在
scala目录里就可以创建Scala类或文件

2.5 创建日志属性文件
-
在
resources目录里创建log4j.properties文件
shelllog4j.rootLogger=error, stdout, logfile log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n log4j.appender.logfile=org.apache.log4j.FileAppender log4j.appender.logfile.File=target/flink.log log4j.appender.logfile.layout=org.apache.log4j.PatternLayout log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
2.6 创建HDFS配置文件
-
在
resources目录里创建hdfs-site.xml文件
xml<?xml version="1.0" encoding="utf-8" ?> <configuration> <property> <name>dfs.client.use.datanode.hostname</name> <value>true</value> </property> </configuration> -
设置
dfs.client.use.datanode.hostname属性值为true,用于启用客户端通过 DataNode 主机名(而非 IP)访问 HDFS,常用于集群网络配置或主机名解析场景。
2.7 在源程序目录里创建包
- 创建
net.huawei.flink.wc包

2.8 词频统计 - 批处理模式
2.7.1 创建BatchWordCount对象
-
在
net.huawei.flink.wc包里创建BatchWordCount对象
scalapackage net.huawei.flink.wc import org.apache.flink.api.common.RuntimeExecutionMode import org.apache.flink.streaming.api.scala._ /** * 功能:采用批处理模式进行词频统计 * 作者:华卫 * 日期:2026年06月20日 */ object BatchWordCount { def main(args: Array[String]): Unit = { // 获取执行环境 val env = StreamExecutionEnvironment.getExecutionEnvironment // 设置为批处理模式 env.setRuntimeMode(RuntimeExecutionMode.BATCH) // 读取 HDFS 文件 val lines = env.readTextFile("hdfs://master:9000/wordcount/input/words.txt") // 词频统计:分词 -> 映射为(word, 1) -> 按单词分组 -> 对计数求和 val wc = lines .flatMap(_.split(" ")) .map(w => (w, 1)) .keyBy(_._1) .sum(1) // 打印结果 wc.print() // 触发执行 env.execute("Batch Word Count") } } -
代码说明 :本程序基于 Flink Scala API 1.20.5 实现词频统计。通过
StreamExecutionEnvironment获取执行环境,并设置为BATCH批处理模式。从 HDFS 读取文本文件后,依次经过flatMap分词、map映射为(word, 1)元组、keyBy按单词分组、sum对计数聚合,最终将统计结果打印至控制台。整体流程简洁高效,适用于离线文本分析场景。
2.7.2 运行程序,查看结果
- 运行
BatchWordCount对象

2.9 词频统计 - 流处理模式
2.9.1 创建StreamingWordCount对象
-
在
net.huawei.flink.wc包里创建StreamingWordCount对象
scalapackage net.huawei.flink.wc import org.apache.flink.api.common.RuntimeExecutionMode import org.apache.flink.streaming.api.scala._ /** * 功能:采用流处理模式进行词频统计 * 作者:华卫 * 日期:2026年06月20日 */ object StreamingWordCount { def main(args: Array[String]): Unit = { // 获取执行环境 val env = StreamExecutionEnvironment.getExecutionEnvironment // 设置为批处理模式 env.setRuntimeMode(RuntimeExecutionMode.STREAMING) // 设置并行度为2 env.setParallelism(2); // 读取 HDFS 文件 val lines = env.readTextFile("hdfs://master:9000/wordcount/input/words.txt") // 词频统计:分词 -> 映射为(word, 1) -> 按单词分组 -> 对计数求和 val wc = lines .flatMap(_.split(" ")) .map(w => (w, 1)) .keyBy(_._1) .sum(1) // 打印结果 wc.print() // 触发执行 env.execute("Streaming Word Count") } } -
代码说明 :本程序基于 Flink Scala API 1.20.5 实现流式词频统计。通过
StreamExecutionEnvironment获取执行环境,设置为STREAMING流处理模式,并将并行度设为 2。从 HDFS 读取文本文件后,依次经过flatMap分词、map映射为(word, 1)元组、keyBy按单词分组、sum增量聚合计数,最终将实时统计结果输出至控制台。适用于持续数据流的实时分析场景。
2.9.2 运行程序,查看结果
- 运行
StreamingWordCount对象

- 该运行结果展示了 Flink 流处理模式 下的词频统计输出。由于设置了并行度为 2,控制台日志前的数字
1>和2>代表不同子任务(Subtask)的输出线程 ID。结果显示了单词计数的增量更新过程 :例如(hello,1)随后变为(hello,2),表明 Flink 正在实时处理数据流并动态累加计数,而非等待所有数据处理完毕后一次性输出最终结果。这验证了流计算"来一条算一条"的实时特性。
2.10 词频统计 - 处理流数据
2.10.1 利用nc产生流数据
- 文件充其量只能算有界数据流,如何才能产生无界数据流呢?可以利用Kafka消息队列,当然为了简单起见,我们采用
nc来产生流数据。nc是款非常实用的网络工具,它能够建立并接受传输控制协议(TCP)和用户数据报协议(UDP)的连接。小巧而功能强大,被誉为网络安全界的"瑞士军刀"。nc被设计成一个可靠的后端(back-end) 工具,拥有功能丰富的网络调试和开发工具,它可以通过手工或者脚本与应用层的网络应用程序或服务进行交互,可以帮你轻易的建立几乎任何类型的连接,同时还可以当服务器使用,能监听任意指定端口的连接请求,并可做同样的读写操作。 - 执行命令:
nc -h

2.10.2 启动nc监听端口并保持开放
- 启动
nc,监听9999端口,保持开放,可以不断写入数据

2.10.3 创建StreamingDataWordCount对象
-
在
net.huawei.flink.wc包里创建StreamingDataWordCount对象
scalapackage net.huawei.flink.wc import org.apache.flink.api.common.RuntimeExecutionMode import org.apache.flink.streaming.api.scala._ /** * 功能:对流数据进行词频统计 * 作者:华卫 * 日期:2026年06月20日 */ object StreamingDataWordCount { def main(args: Array[String]): Unit = { // 获取执行环境 val env = StreamExecutionEnvironment.getExecutionEnvironment // 设置为批处理模式 env.setRuntimeMode(RuntimeExecutionMode.STREAMING) // 设置并行度为2 env.setParallelism(2) // 读取socket文本流数据 val inputStream = env.socketTextStream("master", 9999) // 词频统计:分词 -> 映射为(word, 1) -> 按单词分组 -> 对计数求和 val wc = inputStream .flatMap(_.split(" ")) .map(w => (w, 1)) .keyBy(_._1) .sum(1) // 打印结果 wc.print() // 触发执行 env.execute("Streaming Data Word Count") } } -
代码说明 :本程序基于 Flink Scala API 1.20.5 实现实时流式词频统计。通过
StreamExecutionEnvironment获取环境并设置为STREAMING模式,并行度设为 2。利用socketTextStream监听master:9999端口接收数据,核心逻辑依次经过flatMap分词、map映射为(word, 1)、keyBy按单词分组及sum增量聚合计数,最终将实时计算结果打印至控制台,适用于网络数据流的即时分析场景。
2.10.4 启动程序,利用nc输入数据,控制台查看结果
- 启动
StreamingDataWordCount对象,利用nc输入几行数据,在控制台查看词频统计结果

- 查看
nc输入的数据

- 查看控制台输出的词频统计结果

2.10.5 退出nc,程序结束
- 切换到
nc窗口,按Ctrl + C结束nc进程

- 此时,程序正常结束

3. 实战总结
-
本次实战成功实现了基于 Flink Scala API 的词频统计功能,达到了预期的学习目标。首先,在环境配置阶段,通过 Maven 精确引入了
flink-streaming-scala、flink-hadoop-compatibility等核心依赖,并完成了 Log4j 与 HDFS 的配置,为后续开发奠定了坚实基础。 -
在代码实现层面,深刻体会到了 Flink 1.20.5 版本中
RuntimeExecutionMode的灵活性。无论是采用BATCH模式一次性输出最终统计结果,还是采用STREAMING模式进行增量计算,核心的转换逻辑(flatMap、map、keyBy、sum)保持高度一致,仅在数据源接入方式和执行模式设置上有所区别。 -
特别在流处理实战中,通过
nc(Netcat)工具模拟实时数据流,直观地验证了 Flink 的实时计算能力。观察到控制台输出的计数器动态累加过程,验证了流处理"来一条算一条"的低延迟特性。同时,通过对比有界数据流(文件)与无界数据流(Socket)的运行结果,加深了对 Flink 时间语义和窗口机制的初步理解。本次实践不仅掌握了 Flink 程序的基本骨架,更理解了批流统一的编程模型,为后续复杂业务开发积累了宝贵经验。