简述

WordCount(单词计数)一直是大数据入门的经典案例,下面用java和scala实现Flink的WordCount代码;

采用IDEA + Maven + Flink 环境;文末附 pom 文件和相关技术点总结;

Java实现Flink批处理版本

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.DataSet;
import org.apache.flink.api.java.ExecutionEnvironment;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.util.Collector; public class WordCountBatchByJava {
public static void main(String[] args) throws Exception { // 创建执行环境
ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); // 加载或创建源数据
DataSet<String> text = env.fromElements("this a book", "i love china", "i am chinese"); // 转化处理数据
DataSet<Tuple2<String, Integer>> ds = text.flatMap(new LineSplitter()).groupBy(0).sum(1); // 输出数据到目的端
ds.print(); // 执行任务操作
// 由于是Batch操作,当DataSet调用print方法时,源码内部已经调用Excute方法,所以此处不再调用,如果调用会出现错误
//env.execute("Flink Batch Word Count By Java"); } static class LineSplitter implements FlatMapFunction<String, Tuple2<String,Integer>> {
@Override
public void flatMap(String line, Collector<Tuple2<String, Integer>> collector) throws Exception {
for (String word:line.split(" ")) {
collector.collect(new Tuple2<>(word,1));
}
}
}
}

运行输出结果如下:

(a,1)
(am,1)
(love,1)
(china,1)
(this,1)
(i,2)
(book,1)
(chinese,1)

Java实现Flink流处理版本

import org.apache.flink.api.common.functions.FlatMapFunction;
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; public class WordCountStreamingByJava {
public static void main(String[] args) throws Exception { // 创建执行环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
// 设置socket数据源
DataStreamSource<String> source = env.socketTextStream("192.168.1.111", 9999, "\n");
// 转化处理数据
DataStream<WordWithCount> dataStream = source.flatMap(new FlatMapFunction<String, WordWithCount>() {
@Override
public void flatMap(String line, Collector<WordWithCount> collector) throws Exception {
for (String word : line.split(" ")) {
collector.collect(new WordWithCount(word, 1));
}
}
}).keyBy("word")//以key分组统计
.timeWindow(Time.seconds(2),Time.seconds(2))//设置一个窗口函数,模拟数据流动
.sum("count");//计算时间窗口内的词语个数 // 输出数据到目的端
dataStream.print(); // 执行任务操作
env.execute("Flink Streaming Word Count By Java"); } public static class WordWithCount{
public String word;
public int count; public WordWithCount(){ } public WordWithCount(String word, int count) {
this.word = word;
this.count = count;
} @Override
public String toString() {
return "WordWithCount{" +
"word='" + word + '\'' +
", count=" + count +
'}';
}
}
}

启动一个shell窗口,联通9999端口,输入数据:

[root@spark111 flink-1.6.2]# nc -l 9999
山东 天津 北京 河北 河南 山东 上海 北京
山东 海南 青海 西藏 四川 海南

IDEA 输出结果如下:

4> WordWithCount{word='北京', count=2}
1> WordWithCount{word='上海', count=1}
5> WordWithCount{word='天津', count=1}
4> WordWithCount{word='河南', count=1}
7> WordWithCount{word='山东', count=2}
3> WordWithCount{word='河北', count=1}
------------------------为了区分前后时间窗口结果,手动加的这条线--------------------------
8> WordWithCount{word='海南', count=2}
8> WordWithCount{word='四川', count=1}
7> WordWithCount{word='山东', count=1}
1> WordWithCount{word='西藏', count=1}
5> WordWithCount{word='青海', count=1}

Scala实现Flink批处理版本

import org.apache.flink.api.scala._
import org.apache.flink.api.scala.ExecutionEnvironment object WordCountBatchByScala {
def main(args: Array[String]): Unit = { //获取执行环境
val env = ExecutionEnvironment.getExecutionEnvironment //加载数据源
val source = env.fromElements("china is the best country","beijing is the capital of china") //转化处理数据
val ds = source.flatMap(_.split(" ")).map((_,1)).groupBy(0).sum(1) //输出至目的端
ds.print() // 执行操作
// 由于是Batch操作,当DataSet调用print方法时,源码内部已经调用Excute方法,所以此处不再调用,如果调用会出现错误
//env.execute("Flink Batch Word Count By Scala") }
}

运行结果如下:

(is,2)
(beijing,1)
(the,2)
(china,2)
(country,1)
(of,1)
(best,1)
(capital,1)

Scala实现Flink流处理版本

import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.streaming.api.windowing.time.Time object WordCountStreamingByScala {
def main(args: Array[String]): Unit = { //获取执行环境
val env = StreamExecutionEnvironment.getExecutionEnvironment //加载或创建数据源
val source = env.socketTextStream("192.168.1.111",9999,'\n') //转化处理数据
val dataStream = source.flatMap(_.split(" "))
.map((_,1))
.keyBy(0)
.timeWindow(Time.seconds(2),Time.seconds(2))
.sum(1) //输出到目的端
dataStream.print() //执行操作
env.execute("Flink Streaming Word Count By Scala") }
}

启动shell窗口,开启9999端口通信,输入词语:

[root@spark111 flink-1.6.2]# nc -l 9999
time is passed what is the time?
time is nine time passed again

运行结果如下:

4> (what,1)
5> (time,1)
8> (is,2)
5> (time?,1)
8> (passed,1)
5> (the,1)
------------------------为了区分前后时间窗口结果,手动加的这条线--------------------------
8> (is,1)
5> (time,2)
8> (passed,1)
7> (nine,1)
6> (again,1)

POM文件

<?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>com.ssrs</groupId>
<artifactId>flinkdemo</artifactId>
<version>1.0</version> <properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<encoding>UTF-8</encoding>
<scala.version>2.11.12</scala.version>
<scala.binary.version>2.11</scala.binary.version>
<hadoop.version>2.8.4</hadoop.version>
<flink.version>1.6.1</flink.version>
</properties>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-java</artifactId>
<version>${flink.version}</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-scala_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-scala_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-clients_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>${hadoop.version}</version>
</dependency>
</dependencies>
</project>

总结

  1. flink处理任务流程如下:

    ​ ① 获取执行环境 (Environment)

    ​ ② 加载或者创建数据源(source)

    ​ ③ 转化处理数据(transformation)

    ​ ④ 输出目的端(sink)

    ​ ⑤ 执行任务(execute)

  2. 在批处理中,如果输出目的端,执行的 print 命令(除此之外,还有count,collect方法),则执行任务Execute不需要调用(因为这些方法内部已经调用了Execute方法);如果调用,虽然也有正确结果,但是会有错误信息输出;错误如下:

    Exception in thread "main" java.lang.RuntimeException: No new data sinks have been defined since the last execution. The last execution refers to the latest call to 'execute()', 'count()', 'collect()', or 'print()'.
    at org.apache.flink.api.java.ExecutionEnvironment.createProgramPlan(ExecutionEnvironment.java:940)
    at org.apache.flink.api.java.ExecutionEnvironment.createProgramPlan(ExecutionEnvironment.java:922)
    at org.apache.flink.api.java.LocalEnvironment.execute(LocalEnvironment.java:85)
    at com.ssrs.WordCountBatchByJava.main(WordCountBatchByJava.java:27)
  3. 如果批处理代码中,输出目的端调用writeAsCsv、writeAsText等其他方法,则后面需要调用Execute;

  4. 批处理获取执行环境用ExecutionEnvironment,流处理获取环境用StreamExecutionEnvironment

  5. 批处理后的数据是DataSet,流处理后的数据是DataStream.

【Flink】Flink基础之WordCount实例(Java与Scala版本)的更多相关文章

  1. 小记--------sparksql和DataFrame的小小案例java、scala版本

    sparksql是spark中的一个模块,主要用于进行结构化数据的处理,他提供的最核心的编程抽象,就是DataFrame.同时,sparksql还可以作为分布式的sql查询引擎. 最最重要的功能就是从 ...

  2. hadoop记录-[Flink]Flink三种运行模式安装部署以及实现WordCount(转载)

    [Flink]Flink三种运行模式安装部署以及实现WordCount 前言 Flink三种运行方式:Local.Standalone.On Yarn.成功部署后分别用Scala和Java实现word ...

  3. 【Flink】flink执行jar报错:java.io.IOException: Error opening the Input Split file 或者 java.io.FileNotFoundException

    报错内容 flink执行jar时,报如下错误: org.apache.flink.client.program.ProgramInvocationException: Job failed. (Job ...

  4. Apache Flink 零基础入门(转)

    这是一份很好的 Apache Flink 零基础入门教程. Apache Flink 零基础入门(一&二):基础概念解析 Apache Flink 零基础入门(三):开发环境搭建和应用的配置. ...

  5. Hadoop3 在eclipse中访问hadoop并运行WordCount实例

    前言:       毕业两年了,之前的工作一直没有接触过大数据的东西,对hadoop等比较陌生,所以最近开始学习了.对于我这样第一次学的人,过程还是充满了很多疑惑和不解的,不过我采取的策略是还是先让环 ...

  6. 大数据计算引擎之Flink Flink CEP复杂事件编程

    原文地址: 大数据计算引擎之Flink Flink CEP复杂事件编程 复杂事件编程(CEP)是一种基于流处理的技术,将系统数据看作不同类型的事件,通过分析事件之间的关系,建立不同的时事件系序列库,并 ...

  7. 【Java基础】4、java中的内部类

    内部类的分类:常规内部类.静态内部类.私有内部类.局部内部类.匿名内部类. 实例1:常规内部类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 ...

  8. Python实现MapReduce,wordcount实例,MapReduce实现两表的Join

    Python实现MapReduce 下面使用mapreduce模式实现了一个简单的统计日志中单词出现次数的程序: from functools import reduce from multiproc ...

  9. WordCount by Java

    WordCount by Java 软测第二周作业 该项目github地址如下: https://github.com/YuQiao0303/WordCount 一.概述 项目WordCount的需求 ...

随机推荐

  1. 关于javascript闭包的最通俗易懂的理解

    这两天在研究闭包,网上一通找,有牛人写的帖子,有普通人写的帖子,但是大多没戳中本小白所纠结的点,而且大多插入了立即执行函数,其实根本不需要的,反而让人产生了误解.这里我用我的方式讲解一下闭包. 1.目 ...

  2. OptimalSolution(4)--字符串问题(2)进阶

    一.将整数字符串转成整数值 二.判断字符数组中是否所有的字符都只出现过一次 三.在有序但含有空的数组中查找字符串 四.数组中两个字符串的最小距离 五.添加最少字符使字符串整体都是回文字符串 六.括号字 ...

  3. laravel6.0控制器-资源控制器

    控制器:控制器用来处理业务的,不应该处理逻辑,如果是小项目可以把逻辑写到控制器里,大点的项目应该抽离出来业务处理层如下:services业务处理层:比如:获取值,验证值,异常捕获命名规则:控制器名:用 ...

  4. FastJson的使用心得

      本文为早前整理,参考文献已找不到,如有侵权请与我联系,添加参考链接. 一丶基本使用 1.1主要API fastjson入口类是com.alibaba.fastjson.JSON,主要的API是JS ...

  5. 非旋treap (fhq treap) 指针版

    传送门 看了一圈,好像真的没什么用指针的呢.. 明明觉得指针很好看(什么??你说RE???听不见听不见) 其实我觉得用数组的话不RE直接WA调起来不是更困难嘛,毕竟通过gdb还可以知道哪里RE,WA就 ...

  6. [考试反思]1026csp-s模拟测试88:发展

    不用你们说,我自己来:我颓闪存我没脸. 昨天的想法, 今天的回答. 生存, 发展. 总分榜应该稍有回升,但是和上面的差距肯定还是很大. 继续. 为昨天的谬误,承担代价. T2和T3都值得张记性. T2 ...

  7. 差异---虐爆了yxs的 后缀数组裸题 板子题 单调栈的简单应用 字符串的基础理解考察题

    先玩柿子,发现可以拆开,前半部分可以瞬间求出,于是只求后半部分 然后抄板子就好了,完结撒花! 下边是个人口胡,因为已经被虐爆头脑不清醒了 定义:LCP(a,b)为排名为a,b两个后缀的最长公共前缀 证 ...

  8. 【工利其器】Android Lint篇——为Android量身定做的静态代码审查工具

    前言 我们在进行代码优化的时候,往往是通过开发者的经验来判断哪些代码可能存在潜在问题,哪些资源的使用不合规范等.实际上Android SDK提供了一款功能非常强大的工具,来帮助开发者自动检测代码的质量 ...

  9. python学习之【第二篇】:Python中的数字及其所具有的方法

    1.前言 Python 数字(number)数据类型用于存储数值.数据类型是不允许改变的,这就意味着如果改变数字数据类型的值,将重新分配内存空间. 2.创建数字对象 以下实例在变量赋值时 Number ...

  10. m101 真*sb($\huge 全场最瞎$)

    不想说这场考试,T1全场切,但是我: T3全场30,但是: 鬼知道我为什么敲的是p*p啊(而且还炸精了!) kuku----! $\huge 全场最瞎$