1.Flink特点
- Flink是基于事件驱动的(Event-driven)
事件可以理解为消息。
事件驱动的应用程序是一种状态应用程序,它会从一个或者多个流中注入事件,通过触发计算更新状态,或外部动作对注入的事件作出反应
- Flink是基于流处理的,也就是说,在Flink中,一切都是流形式,离线数据被称为有界流,实时数据被称为无界流
Flink最强悍的一点其实就是万物皆流
离线就是有开头有结尾的流式数据,实时就是有开头无边界的流式数据
2.Flink VS SparkStreaming
- 数据模型角度
Spark底层采用RDD模型,SparkStreaming的DStream实际上也就是一组小批数据RDD的集合
Flink基本数据模型是数据流,基于事件驱动的(Event-driven)
- 运行时架构
SparkStreaming是批计算,将DAG划分为不同的Stage,一个完成后才可以计算下一个
Flink是标准的流执行模式,一个事件在一个节点处理完后可以直接发往下一个节点处理
后续会出一篇专门针对两个组件的详细对比文章
3.快速上手WordCount
- 批处理实现WordCount
使用Java-8提供的lambada方式实现:
//构建上下文环境
ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
DataSource<String> dataSource = env.readTextFile("C:\\Users\\yue\\Desktop\\files.txt");
/**
* FLINK的LAMBADA和SPARK的LAMBADA有些不同
*/
dataSource.flatMap((String line,Collector<String> ctx)->{
String[] split = line.split(" ");
for (String s : split) {
ctx.collect(s);
}
}).returns(Types.STRING).map(x-> new Tuple2<String,Integer>(x,1)).returns(Types.TUPLE(Types.STRING, Types.INT)).groupBy(0).sum(1).print();
使用实现接口的方式(最常用的)
public static void main(String[] args) throws Exception {
ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
DataSource<String> dataSource = env.readTextFile("/Users/superyue/Desktop/a.txt");
dataSource.flatMap(new MyFlatMap()).groupBy(0).sum(1).print();
}
public static class MyFlatMap implements FlatMapFunction<String, Tuple2<String, Integer>> {
@Override
public void flatMap(String s, Collector<Tuple2<String, Integer>> out) {
// 按空格分词
String[] words = s.split(" ");
// 遍历所有word,包成二元组输出
for (String str : words) {
out.collect(new Tuple2<>(str, 1));
}
}
}
- 流式批处理实现WordCount
//构建上下文环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStreamSource<String> dataSource = env.readTextFile("C:\\Users\\yue\\Desktop\\files.txt");
/**
* FLINK的LAMBADA和SPARK的LAMBADA有些不同
* FLINK的LAMBADA必须要给他返回一个数据类型 --》returns(Types.STRING)
* 而SPARK的LAMBADA则不需要此操作
*/
dataSource.flatMap((String line,Collector<String> ctx)->{
String[] split = line.split(" ");
for (String s : split) {
ctx.collect(s);
}
}).returns(Types.STRING).map(x-> new Tuple2<String,Integer>(x,1)).returns(Types.TUPLE(Types.STRING, Types.INT)).keyBy(0).sum(1).print();
env.execute();
- 流式处理实现WordCount
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStreamSource<String> datasource = env.socketTextStream("localhost", 7777);
datasource.flatMap(new Batch.MyFlatMap()).keyBy(0).sum(1).print();
env.execute();
小结
批处理中上下文环境是:ExecutionEnvironment
批处理中计算的API是GROUP BY+SUM
流处理中计算的API是KEYBY+SUM
流处理必须要调用EXCUTE()方法
execute()之前的代码,可以理解为是在定义任务,只有执行env.execute()后,Flink才把前面的代码片段当作一个任务整体(每个线程根据这个任务操作,并行处理流数据)
流处理中如果不指定并行度,默认用的本机CPU的核数