Apache Flink是一个用于对无界和有界数据流进行有状态计算的框架。Flink在不同的抽象级别提供多个API,并为常见用例提供专用库。
流媒体应用程序的构建块
可以由流处理框架构建和执行应用程序类型由框架控制流,状态和时间的程度来定义.
流
流是流处理的基本方面.Flink可以处理任何类型的流
州
每个平凡的流应用程序都是有状态的,即只有对单个事件应用转换的应用程序才需要状态。运行基本业务逻辑的任何应用程序都需要记住事件或中间结果,以便在以后的时间点访问它们,例如在收到下一个事件时或在特定持续时间之后。
时间
时间是流媒体应用的另一个重要组成部分 大多数事件流都具有固有的时间语义,因为每个事件都是在特定时间点生成的。此外,许多常见的流计算基于时间,例如窗口聚合,会话化,模式检测和基于时间的连接。流处理的一个重要方面是应用程序如何测量时间,即事件时间和处理时间的差异。
Flink提供了一组丰富的与时间相关的功能.
分层API
Flink提供三层API. 每个API在简洁性和表达之间提供不同的权衡,并针对不同的用例
* SQL/Table API (dynamic tables)
* DataStream API(streams, windows)
* ProcessFunction(event,state,time)
ProcessFunctions
ProcessFunctions是Flink提供的最具表现力的功能接口。Flink提供ProcessFunctions来处理来自窗口中分组的一个或两个输入流或事件的单个事件。ProcessFunctions提供对时间和状态的细粒度控制。ProcessFunction可以任意修改其状态并注册将在未来触发回调函数的定时器。因此,ProcessFunctions可以实现许多有状态事件驱动应用程序所需的复杂的每事件业务逻辑。
以下示例显示了KeyedProcessFunction对a KeyedStream和match START以及END事件进行操作的示例。当一个START被接收的事件,则该函数在记住其状态时间戳和寄存器在四个小时的计时器。如果END在计时器触发之前收到事件,则该函数计算事件END和START事件之间的持续时间,清除状态并返回值。否则,计时器只会触发并清除状态。
/**
* Matches keyed START and END events and computes the difference between
* both elements' timestamps. The first String field is the key attribute,
* the second String attribute marks START and END events.
*/
public static class StartEndDuration extends keyedProcessFunction,Tuple2>{
private ValueState startTime;
@Override
public void open(Configuration conf){
startTime = getRuntimeContext().getState(new ValueStateDescriptor("startTime",Long.class));
}
}
@Override
public void processElement(Tuple2 in, Context ctx,
Collector> out) throws Exception{
switch(in.f1){
case "START":
startTime.update(ctx.timestamp);
ctx.timerService().registerEventTimeTimer(ctx.timestamp() + 4*60*60*1000);
break;
case "END":
Long sTime = startTime.value();
if(sTime != null){
out.collect(Tuple2.of(in.fo,ctx.timestamp() - sTime));
startTime.clear();
}
default:
}
@Override
public void onTimer(long timestamp,OnTimerContext ctx,CollectorTuple2 out){
startTime.clear();
}
}
DataStream API
所述的数据流中的API通过查询外部数据存储提供了许多常见的流处理操作,如窗口,记录在-A-时间变换,并丰富事件原语.数据流API可用于Java和Scala和基于功能,如Map(,reduce()和aggregate()
// a stream of website clicks
DataStream clicks ...
DataStream> result = clicks.map(
new MapFunction>(){
@Overrider
public Tuple2 map(Click click){
return Tuple2.of(click.userId, 1L);
}
}
)
.keyBy(0).windows(EventTimeSessionWindwos.withGap(Time.minutes(20L))).reduce((a,b) -> Tuple.of(a.fo,a.f1 + b.f1));
SQL和Table API
Flink有两个关系API,Table API和SQL。这两个API都是用于批处理和流处理的统一API,即,在无界的实时流或有界的记录流上以相同的语义执行查询,并产生相同的结果。Table API和SQL利用Apache Calcite进行解析,验证和查询优化。它们可以与DataStream和DataSet API无缝集成,并支持用户定义的标量,聚合和表值函数。
Flink的关系API旨在简化数据分析,数据流水线和ETL应用程序的定义。
以下示例显示了用于对点击流进行会话并计算每个会话的点击次数的SQL查询。这与DataStream API示例中的用例相同。
SELECT userId, COUNT(*) FROM clicks GROUP BY SESSION(clicktime, INTERVAL '30' MINUTE), userId
图书馆
Flink具有几个用于常见数据处理用例的库。这些库通常嵌入在API中,而不是完全独立的。因此,他们可以从API的所有功能中受益,并与其他库集成。
复杂事件处理(CEP):模式检测是事件流处理的一个非常常见的用例。Flink的CEP库提供了一个API来指定事件模式(想想正则表达式或状态机)。CEP库与Flink的DataStream API集成,以便在DataStream上评估模式。CEP库的应用包括网络入侵检测,业务流程监控和欺诈检测。
DataSet API:DataSet API是Flink用于批处理应用程序的核心API。DataSet API的原语包括 map, reduce,(外部)join, co-group和 iterate。所有操作均由算法和数据结构支持,这些算法和数据结构对内存中的序列化数据进行操作,并在数据大小超过内存预算时溢出到磁盘。Flink的DataSet API的数据处理算法受到传统数据库运算符的启发,例如混合散列连接或外部合并排序。
Gelly:Gelly是一个可扩展的图形处理和分析库。Gelly是在DataSet API之上实现的,并与DataSet API集成在一起。因此,它受益于其可扩展且强大的运营商。Gelly具有内置算法,如标签传播,三角枚举和页面排名,但也提供了一个简化自定义图算法实现的 Graph API。