一、Flink发展
第一代:Storm
低延迟,无法保证准确性以及很难实现高吞吐量。
第二代:Lambda架构
流处理器和批处理器的简单合并,
数据到达 之后,两层处理双管齐下,一方面由流处理器进行实时处理,另一方面写入批处理存储空间, 等待批处理器批量计算。流处理器快速计算出一个近似结果,并将它们写入“流处理表”中。 而批处理器会定期处理存储中的数据,将准确的结果写入批处理表,并从快速表中删除不准确 的结果。最终,应用程序会合并快速表和批处理表中的结果,并展示出来。 优点:兼具了批处理和第一代流处理器的特点,同时保证了低延迟和结果的准确性。缺点:Lambda架构本身很难建立和维护;而且它需要我们对一个应用程序,做出两套语义上等效的逻辑实现,因为批处理和流处理是两套完全独立的系统,他们的API也完全相同。为了实现一个应用,付出了双倍的工作量,这对程序员显然不够友好。
第三代:Flink
解决了乱序数据对结果正确性的影响。这一代系统还做到了精确一次(exactly-once)的执行保障,是第一个具有一致性和准确结果的开源节流处理器。 另外,先前的流处理器仅能在高吞吐和低延迟中二选一,而新一代系统能够同时提供 这两个特性。所以可以说,这一代流处理器仅凭一套系统就完成了 Lambda 架构两套系统的工 作,它的出现使得 Lambda 架构黯然失色。 除了低延迟、容错和结果准确性之外,新一代流处理器还在不断添加新的功能,例如高可 用的设置,以及与资源管理器(如 YARN 或 Kubernetes)的紧密集成等等
二、Flink的核心特性
Flink区别与传统数据处理框架的特性如下。
- 高吞吐和低延迟。每秒处理数百万个事件,毫秒级延迟
- 结果的准确性。Flink提供了事件事件(event-time)和处理时间(processin-time)语义。对于乱序事件流,事件时间语义仍然能提供一致且准确的结果。
- 精确一次(exactly-once)的状态一致性保证。
- 可以连接到最常用的存储系统,如 Apache Kafka、Apache Cassandra、Elasticsearch、 JDBC 、 Kinesis 和(分布式)文件系统,如 HDFS 和 S3 。
- 高可用。本身高可用的设置,加上与 K8s , YARN 和 Mesos 的紧密集成,再加上从故 障中快速恢复和动态扩展任务的能力,Flink 能做到以极少的停机时间 7 × 24 全天候运行。
- 能够更新应用程序代码并将作业(jobs)迁移到不同的 Flink 集群,而不会丢失应用 程序的状态。
三、分层API
除了上述这些特性之外,Flink还是一个非常易于开发的框架,因为它拥有易于使用的分层API,整体API分层如图1-2所示。
四、Flink vs Spark
大数据处理引擎,Apache Spark 是一个通用大规模数据分析引擎。
它提出的内存计算概念让大家耳目一新,得以从 Hadoop 繁重的 MapReduce 程序中解脱出来, 可以说是划时代的大数据处理框架。除了计算速度快、可扩展性强, Spark 还为批处理( Spark SQL )、流处理( Spark Streaming )、机器学习( Spark MLlib )、图计算( Spark GraphX )提供 了统一的分布式数据处理平台,整个生态经过多年的蓬勃发展已经非常完善。
数据处理框架
我们已经知道,数据处理的基本方式,可以分为批处理和流处理两种。批处理针对的是有界的数据集,非常适合需要访问海量的全部数据才能完成的计算工作,一般用于离线统计。流处理主要针对的数据流,特点是无界‘实时,对系统传输的每个数据依次执行操作,一般用于实时统计。从根本上说,Spark 和 Flink 采用了完全不同的数据处理方式。可以说,两者的世界观是 截然相反的。 Spark以批处理为根本,并尝试在批处理之上支持流处理计算;在Spark的世界观中万物接批次,离线数据是一个大批次,而实时数据则是由一个个无限的小批次组成。所以对于流处理框架Spark Streaming而言,其实并不是真正意义上的“流”处理,而是“微批次”(micro-batching)处理如下图1-3
而Flink认为,流处理才是最基本的操作,批处理也可以统一为流处理。在Flink的世界观中,万物皆流,实施数据时标准的、没有界限的流,而离线数据则是有界限的流。 1、无界数据流(UNbounded Data Stream) 所谓无界数据流,就是有头没尾,数据的生成和传递会开始但永远不会结束。如下图1-4,我们无法等待所有的数据都到达,因为输入是无界的,永无止境,数据没有“都到达”的时候。所以对于无界数据流,必须连续处理,也就是说必须在获取数据后立即处理。在处理无界流时,为了保证结果的正确性,我们必须能够做到按照顺序处理数据。
2、有界数据流(Bouned Data Stream) 对应的,有界数据流有明确的开始和结束,如上图1-4,所以我们可以通过获取所有数据来处理有界流。处理有界流就不需要严格保证数据的顺序了,因为总可以对有界数据集进行排序。有界流的处理也就是批处理。 正因为这种架构上的不同,Spark和Flink在不同的应用领域上表现会有差别。一般来说,Spark基于微批处理的方式做同步总有一个“攒批”的过程,所以会有额外开销,因此无法在流处理的低延迟上做到极致。在低延迟流处理场景,Flink已经有明显的优势。而在海量数据的批处理领域,Spark能够处理的吞吐量更大,加上其完善的生态和成熟易用的API,目前同样优势比较明显。
数据模型和运行架构
除了三观不合,Spark 和 Flink 在底层实现最主要的差别就在于数据模型不同。 Spark 底层数据模型是弹性分布式数据集(RDD),Spark Streaming 进行微批处理的底层接口 DStream,实际上处理的也是一组组小批数据 RDD 的集合。可以看出,Spark 在设计上本身就是以批量的数据集作为基准的,更加适合批处理的场景。 而 Flink 的基本数据模型是数据流(DataFlow),以及事件(Event)序列。Flink 基本上是 完全按照 Google 的 DataFlow 模型实现的,所以从底层数据模型上看,Flink 是以处理流式数 据作为设计目标的,更加适合流处理的场景。 数据模型不同,对应在运行处理的流程上,自然也会有不同的架构。Spark 做批计算,需要将任务对应的 DAG 划分阶段(Stage),一个完成后经过 shuffle 再进行下一阶段的计算。而Flink是标准的流式执行模式,一个事件在一个节点处理完后可以直接发往下一个节点进行处理。
Spark 还是 Flink?
Spark和Flink可以说目前各擅胜场,批处理领域Spark称王,而在流处理方面Flink当仁不让。具体到项目应用中,不仅要看是流处理还是批处理,还需要在延迟、吞吐量、可靠性,以及开发容易度等多个方面进行权衡。
如果在工作中需要从Spark和Flink这两个主流框架中选择一个来进行实时流处理,我们更加推荐使用Flink,主要的原因有:
- Flink的延迟是毫秒级别,而Spark Streaming的延迟是秒级延迟。
- Flink提供了严格的精确一次性语义保证。
- Flink的窗口API更加灵活,语义丰富。
- Flink提供事件时间语义,可以正确处理延迟数据。
- Flink提供了更加灵活的对状态编程的API。
基于以上特点,使用Flink可以解放程序员,加快编程效率,把本来需要程序员花费大力气手动完成的工作交给框架完成。
当然,在海量数据的批处理方面,Spark还是具有明显的优势。而且Spark的生态更加成熟,也会使其在应用中更为方面。