flink是一个低延迟、高吞吐、统一的大数据计算引擎。
flink的计算平台可以实现毫秒级的延迟情况下,每秒钟处理上亿次的消息或者事件。
提供一个Exactly-once的一致性语义,保证了数据的正确性;使得flink大数据引擎可以提供金融级的数据处理能力。
flink作为主攻流式计算的大数据引擎,不仅仅是一个高吞吐、低延迟的计算引擎,同时还提供很多高级的功能,例如它提供了有状态的计算,支持状态管理,支持强一致性的数据语义以及支持Event Time,WaterMark对消息乱序的处理。
诞生于欧洲的一个大数据研究项目StratoSphere,柏林大学的一个研究性项目。
flink计算的主流方向被定为Streaming,即用流式计算来做所有大数据的计算。
同时支持流处理和批处理的计算引擎:一个是spark,另一个是flink。
spark的技术理念基于批来模拟流的计算。
flink基于流计算来模拟批计算。
flink区别于起亚的流计算引擎的是statefule,即有状态计算。
flink提供了内置的对状态的一致性的处理,即使发生意外,其状态不会丢失、不会被多算少算,同时提供了非常高性能。
flink提供了内置的状态管理,可以把这些状态存储在flink内部,降低了计算引擎对外部系统的依赖以及部署使运维更加简单;对性能带来了极大的提升。
同时Flink会定期将这些状态做Checkpoint持久化,把Checkpoint存储到一个分布式的持久化系统中,比如HDFS。
flink的流式计算跟storm性能差不多,支持毫秒级计算,而spark则只能支持秒级计算。
spark
以批处理为核心,用微批去模拟流式处理
支持SQL处理,流处理,批处理
对于流处理:因为是微批处理,所以实时性弱,吞吐量高,延迟度高
flink
以流式处理为核心,用流处理去模拟批处理
支持流处理,SQL处理,批处理
对于流处理:实时性强,吞吐量高,延迟度低
storm
一条一条处理数据,实时性强,吞吐量低,延迟度低
事件驱动应用
欺诈识别
异常检测
基于规则的警报
业务流程监控
数据分析应用
电信网络的质量监控
分析移动应用程序中的产品更新和实验评估
对消费者技术中的实时数据进行特别分析
大规模图分析
数据管道
电子商务中的实时搜索索引构建
电子商务中持续的ETL
抽象层次
最低级抽象只提供有状态流,它通过Process Function嵌入到DataStream API中。
在实践中,大多数应用程序不需要上述低级抽象,而是针对DataStream API(有界/无界流)和DataSet API (有界数据集)。
scala版
def main(args: Array[String]): Unit = {
//隐式转换
import org.apache.flink.api.scala._
//获取文件信息并进行转换
ExecutionEnvironment.getExecutionEnvironment
.readTextFile("data/textfile")
.flatMap({_.split(" ")})
.map({(_,1)})
.groupBy(0)
.sum(1).print()
}
java版
public static void main(String[] args) {
//获取上下文对象
ExecutionEnvironment environment = ExecutionEnvironment.getExecutionEnvironment();
//读取文件
DataSource<String> source = environment.readTextFile("data/textfile");
//使用flatmap算子
FlatMapOperator<String, Tuple2<String,Integer>> flatMap = source.flatMap(new FlatMapFunction<String, Tuple2<String,Integer>>() {
scala版
def main(args: Array[String]): Unit = {
?
//引入隐式转换
import org.apache.flink.api.scala._
//设置上下文环境
val env=StreamExecutionEnvironment.getExecutionEnvironment
//配置主机和端口
//进行转换计算
env.socketTextStream("node01",9999)
.flatMap({_.split(" ")})
.map((_,1))
.keyBy(0)
.sum(1)
.print()
env.execute("window WordCount")
}
与spark的区别点
不再使用spark的算子reducebykey
运用keyby和sum算子
必须引入隐式转换
流式机必须手动触发,即env.execute("window WordCount")
批处理时运用groupBy算子加上sum算子
java版
public static void main(String[] args) {
//获取运行环境
StreamExecutionEnvironment environment = StreamExecutionEnvironment.getExecutionEnvironment();
//配置端口和主机
DataStreamSource<String> source = environment.socketTextStream("node01", 9999);
//使用flatmap算子
SingleOutputStreamOperator<Tuple2<String, Integer>> flatMap = source.flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() {
flink程序的基本构建是在流和转换操作上
执行时flink程序映射到流数据上,由流和转换符组成,每一个数据流都以一个或者多个源开头,并以一个或多个接收器结束。
数据流类似于任意有向无环图。
代码书写流程
创建ExecutionEnvironment/StreamExecutionEnvironment 执行环境对象
通过执行环境对象创建出source(源头)对象
基于source对象做各种转换
定义结果输出位置
最后调用StreamExecutionEnvironment/ExecutionEnvironment 的excute方法,触发执行
注意
每个flink程序由source operator + transformation operator + sink operator组成。
flink中的key
flink处理数据不是K,V格式编程模型,它是虚拟的key。
Flink中Java Api编程中的Tuple需要使用Flink中的Tuple,最多支持25个。
批处理用groupBY 算子,流式处理用keyBy算子。
flink指定可以的三种方式
使用Tuple来指定key
public static void main(String[] args) {
StreamExecutionEnvironment executionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment();
DataStreamSource<String> ds = executionEnvironment.socketTextStream("node01", 9999);
?
SingleOutputStreamOperator<Tuple3<String, String, Integer>> map = ds.map(new MapFunction<String, Tuple3<String, String, Integer>>() {
使用Field Expression来指定key
public static void main(String[] args) {
StreamExecutionEnvironment executionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment();
DataStreamSource<String> ds = executionEnvironment.socketTextStream("node01", 9999);
SingleOutputStreamOperator<StudentInfo> map = ds.map(new MapFunction<String, StudentInfo>() {