1.Maven的pom.xml文件引入依赖
<dependencies>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-java</artifactId>
<version>1.10.1</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java_2.11</artifactId>
<version>1.10.1</version>
</dependency>
</dependencies>
2.准备测试文件
在resources目录下新建一个txt文件,命名为hello.txt,里面按照统一的分隔符进行单词之间的分开,分隔符可以选择空格或者是逗号,这样才好对每一行的数据进行切分,这里测试使用的是空格,此时文件的路径如下:
在Java中" "双引号代表项目的根目录
String path = "src/main/resources/{}.txt"
3.程序主函数
public static void main(String[] args) throws Exception {
//创建执行环境
ExecutionEnvironment flinkEnv = ExecutionEnvironment.getExecutionEnvironment();
//从文件中读取数据
String inputPath = "src/main/resources/hello.txt";
final DataSource<String> dataSource = flinkEnv.readTextFile(inputPath);
//处理数据集合,按空格分词展开,转换成(word,1)二元组
final DataSet<Tuple2<String, Integer>> resultSet = dataSource.flatMap(new MyflatMapper()).groupBy(0).sum(1);
resultSet.print();
}
4.实现每行数据切分并转换成二元组函数
public static class MyflatMapper implements FlatMapFunction<String, Tuple2<String,Integer>>{
@Override
public void flatMap(String s, Collector<Tuple2<String, Integer>> collector) throws Exception {
final String[] words = s.split(" ");
//遍历所有word,包括二元组输出
for (String word:words){
collector.collect(new Tuple2<>(word,1));
}
}
}
运行结果
到这里还没有完,既然Flink是流批一体的,除了上面的批处理实现方法外,自然还有下面的流处理实现方法
流处理实现wordcount
流处理调用的Api,触发的操作分别是
final StreamExecutionEnvironment streamEnv = StreamExecutionEnvironment.getExecutionEnvironment();
streamEnv.execute();
而批处理则是读取完文件的内容后,既数据加载成功就触发了Flink执行操作
1.流处理实现的主函数
自定义的切分数据并转换成二元组的函数与批处理一样
public static void main(String[] args) throws Exception {
//创建流处理执行环境
final StreamExecutionEnvironment streamEnv = StreamExecutionEnvironment.getExecutionEnvironment();
//从文件中读取数据
String inputPath = "src/main/resources/hello.txt";
final DataStreamSource<String> streamSource = streamEnv.readTextFile(inputPath);
//转换操作,按照key的hash code对数据进行重分区的操作
final SingleOutputStreamOperator<Tuple2<String, Integer>> resultStream = streamSource.flatMap(new wordCount.MyflatMapper())
.keyBy(0)
.sum(1);
resultStream.print();
//执行任务,懒加载
streamEnv.execute();
}
2.执行结果
红色框代表当前执行线程的编号,可理解成并行子任务的分区,默认的分区数等于电脑的CPU的核数,我的是16核,但测试数据只用了5核,因为keyBy的key只有5个,要想增大/减小任务的并行度,可以设置分区数,分区数的数量可根据key的数量加1来定。
//设置分区数量
streamEnv.setParallelism(20);
虽然此时流处理的数据来源也是文件,但流处理是实时保存数据处理的中间状态,相当于是一条一条处理,每个单次出现的次数也是多次输出,直到数据读取完全。