简单实践
读取本地文本文件并统计单词
创建执行环境
StreamExecutionEnvironment的getExecutionEnvironment()方法会根据上下文作出正确处理,若是一般的java程序则创建本地环境,否则会返回一个可以在集群上执行程序的执行环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
读取数据
读取本地文本可以用StreamExecutionEnvironment的readTextFile方法,读取传入路径中的文件作为一个行的序列。
DataStreamSource<String> ds = env.readTextFile("inputs//words.txt");
分割单词并转换为二元组
flatMap可以将流中的数据经过处理后转换为目标结构。如将每一行的字符串按照空格分割为单词,并转换为二元组(word,1)的形式
SingleOutputStreamOperator<Tuple2<String, Integer>> collected_words = ds.flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() {
@Override
public void flatMap(String s, Collector<Tuple2<String, Integer>> collector) throws Exception {
//按空格切分单词
String[] words = s.split(" ");
//转化为二元组(word,1)
for (String word : words) {
Tuple2<String, Integer> uncount_word = Tuple2.of(word, 1);
//使用采集器向下游发送
collector.collect(uncount_word);
}
}
});
按照单词分组并统计
keyby可以按照指定的key选择器将数据进行分组,分组后每组执行求和统计操作,即可得到每个单词的出现次数
KeyedStream<Tuple2<String, Integer>,String> ks = collected_words.keyBy(new KeySelector<Tuple2<String, Integer>, String>() {
@Override
public String getKey(Tuple2<String, Integer> value) throws Exception {
return value.f0;
}
});
SingleOutputStreamOperator<Tuple2<String, Integer>> res = ks.sum(1);
res.print();
执行
编写完逻辑后,最后需要执行作业
env.execute();
结果
- 前缀数字是并行度编号
- 有的单词不止一个输出,说明流数据是来一条处理一条的形式
读取虚拟机发送的文本并统计单词
创建执行环境
指定主机地址和监听端口
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStreamSource<String> ds = env.socketTextStream("192.168.64.128", 8888);
其他逻辑与上述一致
虚拟机端口发送
使用netcat打开端口发送信息
nc -lk 8888
结果
其它配置
-
由于Java9之后引入了模块(module)的概念,不同模块间不允许使用反射来访问非public的字段、方法以及构造函数,除非目标模块设置为对反射开放,即允许自身被其他模块进行non-public反射访问。所以要配置添加以下jvm指令,否则会报错
--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED