1.2 Flink的应用场景
Flink的应用场景十分广泛,下面介绍3种常见的应用。
1.2.1 事件驱动型应用
在许多场景中,需要处理的数据往往来自事件。小到一些交互式的用户行为,大到一些复杂的业务操作,它们都会被转化成一条条数据,进而形成数据流(事件流)。事件驱动型应用的特点在于,一些事件会触发特定的计算或其他外部行为,其典型场景有异常检测、反欺诈等。
在传统架构下,数据流通常会流入数据库,随后应用系统读取数据库中的数据,根据数据触发计算。在这种架构下,数据和计算分离,而且在存取数据时需要进行远程访问。与传统架构不同,Flink利用有状态的数据流来完成整个过程的处理,无须将数据先存入数据库再读取出来。数据流的状态数据在本地(local)维护,并且会周期性地持久化以实现容错。图 1-2 展示了传统事务型应用架构与Flink事件驱动型应用架构的区别。
图1-2 传统事务型应用架构与Flink事件驱动型应用架构的区别
Flink事件驱动型应用架构的优势在于,它的状态数据在本地维护,不需要远程访问数据库,由此获得了更低的延迟、更高的吞吐量。同时,不像传统架构那样多个应用共享同一个数据库,任何对数据库的修改都需要谨慎协调,Flink事件驱动型应用架构中的每一个应用都独立地维护状态,可以灵活地进行扩/缩容。
从上面的介绍可以了解到,实现事件驱动型应用的关键在于支持“有状态的数据流”及容错机制。这是Flink最优秀的设计之一。这部分内容会在后文详细分析。
1.2.2 数据分析型应用
从历史发展的角度来看,企业要处理的数据量是由小到大变化的,因此不妨从传统企业的角度来看待数据分析型应用的演变。
过去,传统企业的数据分析型应用往往就是商务智能(business intelligence,BI)系统。一个成熟的BI产品是一套集数据清洗、数据分析、数据挖掘、报表展示等功能于一体的完整解决方案。不过,当数据量过大时传统的BI系统会出现性能瓶颈,而且它的底层是基于关系数据库的,处理非结构化数据时会十分乏力。因此,当今企业在进行技术选型和架构设计时,更倾向于选择Hadoop生态系统组件及其相关架构。
早期大数据场景下的数据分析型应用架构如图1-3所示。
图1-3 早期大数据场景下的数据分析型应用架构
图1-3充分体现了数据分析型应用的核心设计思想,即业务系统与分析系统分离。业务系统的数据周期性地转换并加载到数据仓库中,在数据仓库内部经过分层处理,最终标准化的数据被提供给其他应用使用。这种架构与BI系统的主要区别就是整个流程不再有完整的解决方案,而需要技术人员自己选择工具进行开发和组合。
图1-4 流式架构
从传统的BI系统到早期大数据场景下的数据分析型应用架构,始终存在着一个问题,那就是整个过程中所有的抽取、转换、加载(Extract-Transform-Load,ETL)逻辑都是离线进行的,导致整个分析流程具有较高的延迟。由此,流式架构便应运而生。
流式架构的目的是在不丢失数据的前提下保证整个分析流程的低延迟,如图 1-4所示。
图1-4所示的整个流程少了ETL,直接将数据摄入流处理引擎,经过业务处理后输出给其他应用使用。在早期的技术储备条件下,想要保证低延迟,通常就难以保证结果的准确性,因此流式架构仅适用于那些对数据准确性要求不高,而对数据实时性要求极高的场景。
那么,在早期的技术储备条件下,能否通过架构的演进,既保证数据的实时性,又兼顾数据的准确性呢?开源框架Storm的创始人Nathan Marz提出了Lambda架构,有效地解决了这一问题。
Lambda架构的核心思想是实时处理和离线处理共存,实时处理如流处理一般保证数据的实时性,离线处理通过周期性地合并数据来保证数据的最终一致性。Lambda架构如图1-5所示。
图1-5 Lambda架构
在Lambda架构下,批处理层将准确结果写入批处理表,流处理层则将数据实时地写入速度表,批处理表的结果会定期与速度表中的数据合并以保证其准确性。数据应用则根据需求进行查询。
显而易见,虽然Lambda架构在一定程度上同时保证了数据的准确性与实时性,但它需要开发和维护两套系统,这实在是一笔不小的开销。由此,Kafka的核心成员之一Jay Kreps在Lambda架构的基础上提出了Kappa架构,解决了“两套代码实现一套业务逻辑”的问题。Kappa架构舍弃了批处理层,只保留了流处理层。与流式架构不同的是,Kappa架构需要让业务数据先进入支持数据重播的消息队列(如Kafka)。如果数据出现错误,那么再执行一个流处理作业,以对历史数据进行重新计算。当新启动的作业消费到最新的数据时,让外部应用访问新的服务数据库,完成服务的切换。Kappa架构如图1-6所示。
图1-6 Kappa架构
Kappa架构虽然不需要开发两套代码,但是仍然需要维护两套环境。而且,它所能处理的历史数据会受到消息队列存储策略的限制。
从Lambda架构和Kappa架构的提出者的技术背景可以了解到,他们提出的架构方案都是以他们熟悉的组件特性为基础的。Storm无法很好地保证数据的准确性,因此需要利用批处理层来保证数据的最终一致性。Kafka支持数据重播,因此可以只开发流处理层,在必要的时候对数据进行重播,从而保证数据的准确性。
Kappa架构之所以需要在两套环境中来回切换,主要是因为过去的流处理引擎无法保证数据的准确性,所以需要频繁地重新计算。如果流处理引擎能够像批处理引擎一样保证端到端的数据的最终一致性,从理论上来说就意味着一套环境可以解决所有问题。Flink完美地解决了这一问题。
以Flink作为流处理引擎,其架构如图1-7所示。
图1-7 Flink流式分析架构
Flink内部维护了数据流的状态,并以容错机制、窗口机制等特性作为支持,可以保证精确地实现端到端的数据的最终一致性。同时,Flink提供了从SQL到底层API的多层接口,使分析工作变得十分容易。因为Flink本身也能够进行批处理,所以Flink流式分析架构可以很容易地被转换成批处理架构。
对Kappa架构来说,可以直接选用Flink作为其中的流处理引擎,但此时设计两套环境的主要目的不再是保证数据的准确性,而是当Flink业务代码发生变动时可以执行新的作业,待数据消费到相同位置时及时完成服务的切换。
1.2.3 数据管道型应用
数据管道型应用也常常作为传统ETL流程的替代流程,与传统的ETL流程相比,其优势在于实时性高。Flink以流式的方式处理数据,无须像传统ETL流程一样进行周期性的离线处理。
数据分析型应用实际上包含数据管道型应用,与数据分析型应用不同的是,数据管道型应用的侧重点在于数据的流转。在数据管道型应用中,数据可能仅仅是从一个消息队列流转到另一个消息队列。