Flink Streaming流式滑動窗口單詞計數_With IntelliJ IDEA
文章目錄
1. 需求分析
任務描述:
手工模擬流式數據產生,通過socket實時產生一些單詞,使用Flink實時接收數據,對指定時間窗口內(例如:2秒)的數據進行聚合統計,並且把時間窗口內計算的結果打印出來。
Flink程序開發步驟
-
獲得一個執行環境
-
加載/創建 初始化數據
-
指定操作數據的transaction算子
-
指定把計算好的數據放在哪
-
調用execute()觸發執行程序
【注意】Flink程序是延遲計算的,只有最後調用execute()方法的時候纔會真正觸發執行程序。(跟Spark中算子的執行一樣,都可以稱爲懶(lazy)執行)。
延遲計算的好處:在開發一個複雜程序時,Flink可以講複雜的程序轉化成一個執行計劃,將執行計劃作爲一個整體的單元執行!(提高計算效率)
執行環境
-
Ubuntu 18.04
-
Java 1.8
-
Flink 1.9.1
-
Maven 3.3.9
2. 啓動Flink
進入Flink的安裝目錄
cd /usr/local/flink
./bin/start-cluster.sh
用jps
查看啓動的java線程,可以看到TaskManagerRunner和StandaloneSessionClusterEntrypoint已啓動。
3. 在IntelliJ IDEA中開發調試SlidingWindowWordCount程序
3.1 新建Project
啓動進入IDEA,如下圖所示,新建一個項目。
執行如下圖所示的操作:(注意不要勾選"Create from archetype"前面的小方框)
如下圖所示,填寫GroupId和ArtifactId。這裏的GroupId是cn.stu.silver ,ArtifactId是streaming-wordcount。
這時生成的項目目錄結構如下圖所示。
3.2 修改pom.xml
該程序依賴Flink Java API,因此,我們需要通過Maven進行編譯打包。打開pom.xml,然後,將pom.xml內容修改如下,用來聲明該獨立應用程序的信息以及與Flink的依賴關係:
<?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>cn.stu.silver</groupId>
<artifactId>streaming-wordcount</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-java</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java_2.11</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-clients_2.11</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-scala_2.11</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-scala_2.11</artifactId>
<version>1.9.1</version>
</dependency>
</dependencies>
</project>
3.3 創建package
如下圖所示,創建Package。
如下圖所示,輸入package的名稱爲“cn.stu.silver”。
如下圖所示,新建一個java class文件。
如下圖所示,輸入文件名稱SlidingWindowWordCount。
###3.4 SlidingWindowWordCount.java
package cn.stu.silver;
import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.utils.ParameterTool;
//import org.apache.flink.runtime.state.filesystem.FsStateBackend;
//import org.apache.flink.runtime.state.memory.MemoryStateBackend;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.util.Collector;
/**
* 滑動窗口計算
*
* 通過socket模擬產生單詞數據
* flink對數據進行統計計算
*
* 需要實現每隔1秒對最近2秒內的數據進行彙總計算
*
*/
public class SlidingWindowWordCount {
public static void main(String[] args) throws Exception{
//獲取需要的端口號
int port;
try {
ParameterTool parameterTool = ParameterTool.fromArgs(args);
port = parameterTool.getInt("port");
}catch (Exception e){
System.err.println("No port set. use default port 9000--java");
port = 9000;
}
//獲取flink的運行環境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
String hostname = "ubuntu";
String delimiter = "\n";
//連接socket獲取輸入的數據
DataStreamSource<String> text = env.socketTextStream(hostname, port, delimiter);
// a a c
// a 1
// a 1
// c 1
DataStream<WordWithCount> windowCounts = text.flatMap(new FlatMapFunction<String, WordWithCount>() {
public void flatMap(String value, Collector<WordWithCount> out) throws Exception {
String[] splits = value.split("\\s");
for (String word : splits) {
out.collect(new WordWithCount(word, 1L));
}
}
}).keyBy("word")
.timeWindow(Time.seconds(2), Time.seconds(1))//指定時間窗口大小爲2秒,指定時間間隔爲1秒
.sum("count");//在這裏使用sum或者reduce都可以
/*.reduce(new ReduceFunction<WordWithCount>() {
public WordWithCount reduce(WordWithCount a, WordWithCount b) throws Exception {
return new WordWithCount(a.word,a.count+b.count);
}
})*/
//把數據打印到控制檯並且設置並行度
windowCounts.print().setParallelism(1);
//這一行代碼一定要實現,否則程序不執行
env.execute("Socket window count");
}
public static class WordWithCount{
public String word;
public long count;
public WordWithCount(){}
public WordWithCount(String word,long count){
this.word = word;
this.count = count;
}
@Override
public String toString() {
return "WordWithCount{" +
"word='" + word + '\'' +
", count=" + count +
'}';
}
}
}
注意修改程序中hostname變量爲自己的hostname,如果不清楚的話可以在終端中輸入hostname
查看自己的主機名。
3.5 執行前的處理
編寫完代碼以後會發現代碼中會出現大量標紅,說明相關的依賴沒有導入。
如下圖所示,在左側目錄樹的pom.xml文件上單擊鼠標右鍵,在彈出的菜單中選擇Maven,再在彈出的菜單中選擇Generate Sources and Update Folders,接着再在彈出的菜單中選擇Reimport。
如果是第一次下載相關依賴需要等待幾分鐘:
3.6 運行結果
打開SlidingWindowWordCount.java代碼文件,在這個代碼文件的代碼區域,鼠標右鍵單擊,彈出菜單中選中“Run SlidingWindowWordCount.main()”。
同時在終端中輸入
nc -l 9000
接着可以在終端中輸入一下字符,按下回車會發現IntelliJ IDEA控制檯會打印出窗口內出現的字符計數,結果如下:
完成!