flink入门-分词统计demo
一:运行环境
1.docker
2.flink1.13.1
3.maven
4.java8
二:部署maven
下载,解压maven:
> mkdir /usr/local/maven
> cd /usr/local/maven
> wget https://mirrors.bfsu.edu.cn/apache/maven/maven-3/3.8.1/binaries/apache-maven-3.8.1-bin.tar.gz
> tar -zxvf apache-maven-3.8.1-bin.tar.gz
> mkdir /usr/local/maven/maven-repo
更改maven配置文件settings.xml:
> vi /usr/local/maven/apache-maven-3.8.1/conf/settings.xml
<localRepository>/usr/local/maven/apache-maven-3.8.1/maven-repo</localRepository>
配置环境变量:
> vi /etc/profile
追加内容:
export MAVEN_HOME=/usr/local/maven/apache-maven-3.8.1
export PATH=${PATH}:${MAVEN_HOME}/bin
环境变量生效:
> source /etc/profile
查看maven版本
> mvn -v
三:部署flink
下载,解压flink:
> mkdir /usr/local/flink
> cd /usr/local/flink
> wget https://mirrors.bfsu.edu.cn/apache/flink/flink-1.13.1/flink-1.13.1-bin-scala_2.12.tgz
> tar -zxvf flink-1.13.1-bin-scala_2.12.tgz
配置环境变量:
> vi /etc/profile
追加内容:
export FLINK_HOME=/usr/local/flink/flink-1.13.1
export PATH=$FLINK_HOME/bin:$PATH
环境变量生效:
> source /etc/profile
启动flink
> sh /usr/local/flink/flink-1.13.1/bin/start-cluster.sh
浏览器查看web界面 http://flink服务器ip:8081
四:编写分词统计程序
【代码来自,有更改】https://blog.csdn.net/hongzhen91/article/details/89812636
maven创建项目
> cd /usr/local/maven
> mvn archetype:generate \
-DarchetypeGroupId=org.apache.flink \
-DarchetypeArtifactId=flink-quickstart-java \
-DarchetypeVersion=1.13.0 \
-DgroupId=my-flink-project \
-DartifactId=my-flink-project \
-Dversion=0.1 \
-Dpackage=myflink \
-DinteractiveMode=false
在目录下/usr/local/maven/my-flink-project/src/main/java/myflink创建SocketWindowWordCount.java程序文件:
package myflink;
import org.apache.flink.streaming.api.windowing.assigners.TumblingProcessingTimeWindows;
import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.common.functions.ReduceFunction;
import org.apache.flink.api.java.utils.ParameterTool;
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;
/**
* @Author: Henry
* @Description: 滑动窗口计算
* 通过socket模拟产生单词数据,flink对数据进行统计计算
* 需要实现每隔1秒对最近2秒内的数据进行汇总计算
* @Date: Create in 2019/5/3 9:43
**/
public class SocketWindowWordCount {
public static void main(String[] args) throws Exception{
// 设置主机名、分隔符、端口号
String hostname = "127.0.0.1" ;
String delimiter = "\n" ;
int port ;
// 使用parameterTool,通过控制台获取参数
try {
ParameterTool parameterTool = ParameterTool.fromArgs(args);
port = parameterTool.getInt("port") ;
}catch (Exception e){
// 如果没有传入参数,则赋默认值
System.out.println("No port set. use default port 9000--java");
port = 9000 ;
}
//1、获取flink的运行环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
//2、连接socket获取输入的数据
DataStream<String> text = env.socketTextStream(
hostname,port,delimiter);
// 输入:a a c
// 输出:(即flatMap操作)
// a 1
// a 1
// c 1
//3、transformation操作,对数据流实现计算
// FlatMapFunction<T, O>: T代表输入格式,O代表返回格式
DataStream<WordWithCount> windowCounts = text
// 3.1、将用户输入的文本流以非空白符的方式拆开来,得到单个的单词,
// 存入命名为out的Collector中
.flatMap(new FlatMapFunction<String, WordWithCount>() {
@Override
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)); // 为输出写数据
}
}
})
// 3.2、将输入的文本分为不相交的分区,每个分区包含的都是具有相同key的元素。
// 也就是说,相同的单词被分在了同一个区域,下一步的reduce就是统计分区中的个数
.keyBy("word")
// 3.3、指定时间窗口大小为2秒
.window(TumblingProcessingTimeWindows.of(Time.seconds(2)))
// 3.4、一个在KeyedDataStream上“滚动”进行的reduce方法。
// 将上一个reduce过的值和当前element结合,产生新的值并发送出。
// 此处是说,对输入的两个对象进行合并,统计该单词的数量和
// 这里使用 sum 或 reduce 都可以
//.sum("count") ; // 是对 reduce 的封装实现
// reduce 返回类型 SingleOutputStreamOperator,继承了 DataStream
.reduce(new ReduceFunction<WordWithCount>() {
public WordWithCount reduce(WordWithCount a, WordWithCount b) {
return new WordWithCount(a.word, a.count + b.count);
}
});
// 4、把数据打印到控制台并且设置并行度
windowCounts.print().setParallelism(1);
// 这一行代码一定要实现,否则程序不执行
// 报错:Unhandled exception: java.lang.Exception
// 需要对 main 添加异常捕获
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
// 打印显示 word,count
public String toString() {
return "WordWithCount{" +
"word='" + word + '\'' +
", count=" + count +
'}';
}
}
}
五:编译打包程序
更改maven程序入口:
> vi /usr/local/maven/my-flink-project.pom.xml
更改mainClass标签内容为:
<mainClass>myflink.SocketWindowWordCount</mainClass>
编译、打包:
> mvn clean compile
> mvn clean package
打包成功后,/usr/local/maven/my-flink-project/target目录下新增jar包my-flink-project-0.1.jar
六:运行
命令行下启动9000端口,并输入内容回车
> nc -l 127.0.0.1 -p 9000
> hello
> world
>
nc -l 127.0.0.1 -p 9000 向此端口发送数据
nc 127.0.0.1 9000 监听此端口数据
运行分词统计程序
> flink run /usr/local/maven/my-flink-project/target/my-flink-project-0.1.jar
继续向9000 端口输入数据…
查看flink web界面: