一、准备工作
Flink是一个以Java及Scala作为开发语言的开源大数据项目,代码开源在GitHub上,并使用Maven来编译和构建项目。对于大部分使用Flink的同学来说,Java,Maven和Git这三个工具是必不可少的。
工具 | 注释 |
---|---|
Java | Java 版本至少是 Java 8,且最好选用 Java 8u51 及以上版本 |
Maven | 必须使用 Maven 3,建议使用 Maven 3.2.5。Maven 3.3.x 能够编译成功,但是在 Shade 一些 Dependencies 的过程中有些问题 |
Git | Flink 的代码仓库是: https://github.com/apache/flink |
二、安装 Flink
2.1 通过homebrew来安装
在Mac OS X上安装Flink是非常方便的。推荐通过homebrew来安装。
brew install apache-flink
2.2 检查安装
flink --version
Version: 1.9.1, Commit ID: 4d56de8
2.3 启动 flink
/usr/local/Cellar/apache-flink/1.9.1/libexec/bin/start-cluster.sh
Starting cluster.
[INFO] 1 instance(s) of standalonesession are already running on C02W41DWG8WN.local.
Starting standalonesession daemon on host C02W41DWG8WN.local.
[INFO] 1 instance(s) of taskexecutor are already running on C02W41DWG8WN.local.
Starting taskexecutor daemon on host C02W41DWG8WN.local.
接着就可以进入 web 页面(http://localhost:8081/) 查看
三、Demo
3.1 创建 Maven 项目
我们将使用Flink Maven Archetype来创建我们的项目结构和一些初始的默认依赖。在你的项目目录下,运行如下命令来创建项目:
mvn archetype:generate \
-DarchetypeGroupId=org.apache.flink \
-DarchetypeArtifactId=flink-quickstart-java \
-DarchetypeVersion=1.9.1 \
-DgroupId=my-flink-project \
-DartifactId=my-flink-project \
-Dversion=0.1 \
-Dpackage=myflink \
-DinteractiveMode=false
你可以编辑上面的 groupId, artifactId, package 成你喜欢的路径。使用上面的参数,Maven 将自动为你创建如下所示的项目结构:
$ tree my-flink-project
my-flink-project
├── pom.xml
└── src
└── main
├── java
│ └── myflink
│ ├── BatchJob.java
│ └── StreamingJob.java
└── resources
└── log4j.properties
我们的pom.xml文件已经包含了所需的Flink依赖,并且在src/main/java下有几个示例程序框架。接下来我们将开始编写第一个Flink程序。
3.2 编写 Flink 程序
启动 IntelliJ IDEA,选择“Import Project”(导入项目),选择 my-flink-project 根目录下的pom.xml。根据引导,完成项目导入。
在 src/main/java/myflink 下创建 SocketWindowWordCount.java ,加入以下代码:
package myflink;
import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.util.Collector;
public class SocketWindowWordCount {
public static void main(String[] args) throws Exception{
/**
* 创建 execution environment
*/
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
/**
* 通过连接 socket 获取输入数据,这里连接到9000端口
*/
DataStream<String> text = env.socketTextStream("localhost", 9000, "\n");
/**
* 解析数据,按 word 进行分组,开窗,聚合
*/
// tuple要使用java包里面的(scala import org.apache.flink.api.java.tuple._),而不是scala自带的tuple,不然也会认为是geneic类型,导致报错
DataStream<Tuple2<String, Integer>> wordCounts = text.flatMap(new LineSplitter());
DataStream<Tuple2<String, Integer>> windowCounts = wordCounts
// 将数据流按照单词字段(即0号索引字段)做分组
.keyBy(0)
// 每5秒聚合一次单词数
.timeWindow(Time.seconds(5))
// 按照次数字段(即1号索引字段)相加
.sum(1);
/**
* 将结果打印到控制台,注意这里使用的是单线程打印,而非多线程
*/
windowCounts.print().setParallelism(1);
/**
* env.execute 调用是启动实际Flink作业所必需的。
* 所有算子操作(例如创建源、聚合、打印)只是构建了内部算子操作的图形。只有在execute()被调用时才会在提交到集群上或本地计算机上执行。
*/
env.execute("Socket Window WordCount");
}
public static final class LineSplitter implements FlatMapFunction<String, Tuple2<String, Integer>>{
@Override
public void flatMap(String s, Collector<Tuple2<String, Integer>> collector) throws Exception {
for (String word : s.split("\\W+")){
collector.collect(new Tuple2<String, Integer>(word, 1));
}
}
}
}
3.3 运行程序
要运行示例代码,首先我们在终端启动netcat获得输入流:
nc -lk 9000
然后直接运行 SocketWindowWordCount 的main方法。
接下来只需要在netcat控制台输入单词,就能在 SocketWindowWordCount 的控制台看到每个单词的词频统计。如果想看到大于1的计数,请在5秒内反复键入相同的单词。