原文连接
Apache Flink是一个用于对无边界和有边界数据流进行有状态计算的框架和分布式处理引擎。Flink设计为运行在全部常见的集群环境中,而且之内存速度和任意规模执行计算。html
在这里,咱们解释Flink架构的相关重要内容。java
任何类型的数据都是做为事件流产生的。信用卡交易事务,传感器测量,机器日志以及网站或移动应用程序上的用户交互行为,全部这些数据都生成流。web
数据能够做为无边界或有边界流处理。正则表达式
Apache Flink是一个分布式系统,须要计算资源才能执行应用程序。Flink与全部常见的集群资源管理器(如Hadoop YARN,Apache Mesos和Kubernetes)集成,但也能够做为独立集群运行。
Flink旨在很好地适用于以前列出的每一个资源管理器。这是经过特定于资源管理器的部署模式实现的,这些模式容许Flink以其惯用的方式与每一个资源管理器进行交互。
部署Flink应用程序时,Flink会根据应用程序配置的并行度自动识别所需资源,并从资源管理器请求它们。若是发生故障,Flink会经过请求新的资源来替换发生故障的容器。提交或控制应用程序的全部通讯都经过REST调用进行。这简化了Flink在许多环境中的集成。算法
Flink旨在以任意规模运行有状态流式应用程序。应用程序能够并行化为数千个在集群中分布和同时执行的任务。所以,应用程序能够利用几乎无限量的CPU,内存,磁盘和网络IO。并且,Flink能够轻松维护很是大的应用程序的状态。其异步和增量检查点算法确保对延迟处理的影响最小,同时保证精确一次的状态一致性。
用户报告了在其生产环境中运行的Flink应用程序的扩展数字使人印象十分深入,例如:数据库
有状态的Flink应用程序针对本地状态访问进行了优化。任务状态始终驻留在内存中,或者,若是状态大小超过可用内存,则保存在访问高效的磁盘上的数据结构中。所以,任务经过访问本地(一般是内存中)状态来执行全部计算,从而产生很是低的处理延迟。Flink经过按期和异步检查点将本地状态到持久存储来保证在出现故障时的精确一次的状态一致性。apache
原文连接
Apache Flink是一个用于对无边界和有边界数据流进行有状态计算的框架。Flink在不一样的抽象级别提供多个API,并为常见用例提供专用库。
在这里,咱们介绍Flink易于使用以及富有表现力的API和库。
后端
流式计算框架构建和运行的应用程序的类型,由框架控制流、状态以及时间的程度来定义。在下文中,咱们描述了流处理应用程序的这些构建块,并解释了Flink处理他们的方法。api
显然,流是流式处理的一个基本方面。然而,流能够有不一样的特征,这些特征会影响流的处理方式。Flink是一个多功能的处理框架,它能够处理任意类型的流。网络
每一个非凡的流式应用都是有状态的。只有对个别事件应用转换的应用程序才不须要状态。运行基本业务逻辑的任何应用程序都须要记住事件或中间结果,以便在以后的时间点访问它们,例如在收到下一个事件时或在特定持续时间以后。
应用程序的状态在Flink中是一等公民。您能够经过查看Flink在状态处理环境(上下文context)中提供的全部功能(函数)来查看。
时间是流式应用的另外一个重要组成成分。大多数事件流都具备固定的时间语义,由于每一个事件都是在特定的时间点生成的。此外,许多常见的流计算基于时间,例如窗口聚合、会话化、模式监测和基于时间的链接。流处理的一个重要方面是应用程序如何测量时间,即时间时间和处理时间之间的差别。
Flink提供了一组丰富的与时间相关的功能。
Flink提供三层API。每一个API在简洁性和表达性之间提供不一样的权衡,并针对不一样的用例。
咱们简要介绍每一个API,讨论它的应用程序,并展现一个代码示例。
ProcessFunctions是Flink提供的最具表现力的功能接口。Flink提供ProcessFunctions来处理来自一个或两个输入流中的单个事件或分组到一个窗口的事件。ProcessFunctions提供对时间和状态的细粒度控制。ProcessFunction能够任意修改其状态并注册将在将来触发回调函数的定时器。所以,ProcessFunctions能够实现许多有状态事件驱动应用程序所需的复杂的每一个事件业务逻辑。
如下示例显示了KeyedProcessFunction对KeyedStream,匹配START以及END事件进行操做的示例。当一个START事件被接收时,该函数在记住其状态时间戳和而且注册四个小时的计时器。若是在计时器触发以前收到END事件,则该函数计算事件END和START事件之间的持续时间,清除状态并返回值。不然,计时器只会触发并清除状态。
package com.longyun.flink.processfuncs; import org.apache.flink.api.common.state.ValueState; import org.apache.flink.api.common.state.ValueStateDescriptor; import org.apache.flink.api.java.tuple.Tuple2; import org.apache.flink.configuration.Configuration; import org.apache.flink.streaming.api.functions.KeyedProcessFunction; import org.apache.flink.util.Collector; /** * @author lynnyuan * @ClassName com.longyun.flink.processfuncs.StartEndDuration * @Description TODO * K key * IN input * OUT output * @Date 2018/12/3 15:02 * @Version 1.0 **/ public class StartEndDuration extends KeyedProcessFunction<String, Tuple2<String, String>, Tuple2<String, Long>> { private ValueState<Long> startTime; @Override public void open(Configuration configuration) throws Exception { //obtain state handle startTime = getRuntimeContext().getState( new ValueStateDescriptor<Long>("startTIme", Long.class)); } /** * called for each processed event * @param in * @param context * @param out * @throws Exception */ @Override public void processElement(Tuple2<String, String> in, Context context, Collector<Tuple2<String, Long>> out) throws Exception { switch (in.f1){ case "START": //set the start time if we receive a start event. startTime.update(context.timestamp()); //register a timer in four hours from the start event. context.timerService() .registerEventTimeTimer(context.timestamp() + 4 * 60 * 60 * 1000); break; case "END": //emit the duration between start and end event Long sTime = startTime.value(); if(sTime != null){ out.collect(Tuple2.of(in.f0, context.timestamp() - sTime)); //clear the state startTime.clear(); } break; default: break; } } /** Called when a timer fires */ @Override public void onTimer(long timestamp, OnTimerContext ctx, Collector<Tuple2<String, Long>> out) throws Exception { //Time out interval exceeded. Cleaning up the state. startTime.clear(); } }
这个例子说明了KeyedProcessFunction的表达能力,但也强调了它是一个至关冗长的接口。
DataStream API提供了许多通用流处理操做原语。如窗口,record-at-a-time转换,查询外部数据存储丰富事件原语。DataStream API可用于Java和Scala且它是基于函数的,如map()、reduce()以及aggregate()。能够经过扩展接口或lambda函数来定义函数参数。
如下示例展现如何对点击流进行会话化以及记录每一个session的点击次数。
// a stream of website clicks DataStream<Click> clicks = ... DataStream<Tuple2<String, Long>> result = clicks // project clicks to userId and add a 1 for counting .map( // define function by implementing the MapFunction interface. new MapFunction<Click, Tuple2<String, Long>>() { @Override public Tuple2<String, Long> map(Click click) { return Tuple2.of(click.userId, 1L); } }) // key by userId (field 0) .keyBy(0) // define session window with 30 minute gap .window(EventTimeSessionWindows.withGap(Time.minutes(30L))) // count clicks per session. Define function as lambda function. .reduce((a, b) -> Tuple2.of(a.f0, a.f1 + b.f1));
Flink有两种关系化API特性, Table API和SQL。这两个API都是用于批处理和流处理的统一API,即,在无边界的实时流或有边界的记录流上以相同的语义执行查询,并产生相同的结果。Table API和SQL利用Apache Calicite来解析,校验以及查询优化。它们能够与DataStream和DataSet API无缝集成,并支持用户定义的标量,聚合以及表值函数。
Flink的关系化API旨在简化数据分析,数据流水线和ETL应用程序的定义。
如下示例展现如何对点击流进行会话化以及记录每一个session的点击次数。与DataStream API中的示例是相同的用例。
SELECT userId, COUNT(*) FROM clicks GROUP BY SESSION(clicktime, INTERVAL '30' MINUTE), userId
Flink具备几个用于常见数据处理用例的库。这些库一般嵌入在API中,而不是彻底独立的。所以,它们能够从API的全部特性中受益,并与其余库集成。
Apache Flink是一个用于对无边界和有边界数据流进行有状态计算的框架。因为许多流应用程序设计为以最短的停机时间连续运行,所以流处理器必须提供出色的故障恢复,以及在应用程序运行时监控和维护应用程序的工具。
Apache Flink很是关注流处理的操做方面。在这里,咱们将解释Flink的故障恢复机制,并介绍其管理和监督正在运行的应用程序的特性。
机器和处理故障在分布式系统中无处不在。像Flink这样的分布式流处理器必须从故障中恢复,以便可以全天候运行流应用程序。显然,这不只意味着在故障发生后从新启动应用程序,并且还要确保其内部状态保持一致,以便应用程序能够继续处理,就像从未发生过故障同样。
Flink提供了多种特性,以确保应用程序保持运行并保持一致:
须要维护为关键业务服务提供支持的流应用程序。须要修复错误,而且须要实现改进或新功能特性。可是,更新有状态流应用程序并不是易事。一般,咱们不能简单地中止应用程序并从新启动固定版本或改进版本,由于没法承受丢失应用程序的状态。
Flink的Savepoints是一个独特而强大的功能特性,能够解决更新有状态应用程序和许多其余相关挑战的问题。保存点是应用程序状态的一致快照,所以它与检查点很是类似。可是,与检查点相比,须要手动触发保存点,而且在应用程序中止时不会自动删除保存点。保存点可用于启动状态兼容的应用程序并初始化其状态。保存点可启用如下功能:
与任何其余服务同样,持续运行的流应用程序须要受到监督并集成到组织的运营(operations)基础架构(即监控和日志记录服务)中。监控有助于预测问题并提早作出反应。日志记录让咱们能够依据根缘由分析来调查故障。最后,控制运行应用程序的易于访问的界面也是一个重要特性。
Flink与许多常见的日志记录和监视服务已经很好地集成,并提供REST API来控制应用程序和查询信息。