Flink入门

Flink简介

Apache Flink是一个面向数据流处理和批量数据处理的可分布式的开源计算框架,它基于同一个Flink流式执行模型(streaming execution model),能够支持流处理和批处理两种应用类型。

由于流处理和批处理所提供的SLA(服务等级协议)是完全不相同, 流处理一般需要支持低延迟、Exactly-once保证,而批处理需要支持高吞吐、高效处理,所以在实现的时候通常是分别给出两套实现方法,或者通过一个独立的开源框架来实现其中每一种处理方案。比较典型的有:实现批处理的开源方案有MapReduce、Spark;实现流处理的开源方案有Storm;Spark的Streaming 其实本质上也是微批处理。

Flink在实现流处理和批处理时,与传统的一些方案完全不同,它从另一个视角看待流处理和批处理,将二者统一起来:Flink是完全支持流处理,也就是说作为流处理看待时输入数据流是无界的;批处理被作为一种特殊的流处理,只是它的输入数据流被定义为有界的。

Flink能在所有常见集群环境中运行,并能运行任意规模应用。Flink 旨在任意规模上运行有状态流式应用。因此,应用程序被并行化为可能数千个任务,这些任务分布在集群中并发执行。所以应用程序能够充分利用无尽的 CPU、内存、磁盘和网络 IO。而且 Flink 很容易维护非常大的应用程序状态。其异步和增量的检查点算法对处理延迟产生最小的影响,同时保证精确一次状态的一致性。

Flink很好的利用内存性能,有状态的 Flink 程序针对本地状态访问进行了优化。任务的状态始终保留在内存中,如果状态大小超过可用内存,则会保存在能高效访问的磁盘数据结构中。任务通过访问本地(通常在内存中)状态来进行所有的计算,从而产生非常低的处理延迟。Flink 通过定期和异步地对本地状态进行持久化存储来保证故障场景下精确一次的状态一致性。

处理无界和有界数据

在Flink的世界观中,一切都是由流组成的,离线数据是有界的流;实时数据是一个没有界限的流。

  • 无界流:有定义流的开始,但没有定义流的结束。它们会无休止地产生数据。无界流的数据必须持续处理,即数据被摄取后需要立刻处理。我们不能等到所有数据都到达再处理,因为输入是无限的,在任何时候输入都不会完成。处理无界数据通常要求以特定顺序摄取事件,例如事件发生的顺序,以便能够推断结果的完整性。

  • 有界流:有定义流的开始,也有定义流的结束。有界流可以在摄取所有数据后再进行计算。有界流所有数据可以被排序,所以并不需要有序摄取。有界流处理通常被称为批处理。

avatar

Apache Flink 擅长处理无界和有界数据集 精确的时间控制和状态化使得 Flink 的运行时(runtime)能够运行任何处理无界流的应用。有界流则由一些专为固定大小数据集特殊设计的算法和数据结构进行内部处理,产生了出色的性能。

Flink的应用场景

  1. 实时数仓。当下游要构建实时数仓时,上游则可能需要实时的 Stream ETL。这个过程会进行实时清洗或扩展数据,清洗完成后写入到下游的实时数仓的整个链路中,可保证数据查询的时效性,形成实时数据采集、实时数据处理以及下游的实时 Query。

  2. 搜索引擎数据同步。搜索引擎这块以淘宝为例,当卖家上线新商品时,后台会实时产生消息流,该消息流经过 Flink 系统时会进行数据的处理、扩展。然后将处理及扩展后的数据生成实时索引,写入到搜索引擎中。这样当淘宝卖家上线新商品时,能在秒级或者分钟级实现搜索引擎的搜索。

  3. 实时监控。对用户行为或者相关事件进行实时监测和分析,基于风控规则进行预警。

  4. 实时大屏、实时报表。双11、双12等活动直播大屏,数据化运营等。

流式处理的演变

传统事务处理架构

传统的事务处理一般分为两层:计算层和存储层。计算层可以是我们的各个业务系统,计算层在数据计算时,可能需要用到一些外部数据,或者还要去修改这些外部数据,这样我们就需要跟传统的一些关系型数据库交互。所以我们的业务系统在收到请求时,需要去关系型数据库去查取数据,或者修改数据,然后进行计算,将计算结果包装成响应返回给用户。具体架构如下:

avatar

在使用过程中就会发现一些问题,因为数据量太大,数据来源多种多样,可能来自于mysql,sqlserver,orcale等多个关系型数据库,和一些非结构化的数据,比如前端埋点数据,可能为JSON或其他格式,一个单纯的关系型数据库根本无法处理。并且关系型数据库的数据存储会受到限制,存储的数据是有限的,所以我们一般只会存储一些与业务强关联的数据,但我们的一些埋点数据,我们是不需要把它存储起来的,或者说不需要存储到关系型数据库中,这个时候我们分析处理架构就诞生了。

离线分析处理架构

将数据从业务数据库或业务日志复制到数仓,再进行分析查询。基本过程就是,将数据拉取经过ETL处理之后,放到Data Warehouse中,然后直接基于数仓进行计算,生成我们需要的报表,或者将计算结果返回给用户。具体架构如下:

avatar

这个过程就是我们大数据离线计算的基本应用流程,优点在于:我们能处理的数据更多更加的丰富。缺点在于:我们需要把所有的数据都提取出来放到数仓中,所以这个过程的实时性就无法保证,我们的传统事务处理架构,它是能保证处理结果的实时性的。基于这个问题,流式处理架构又产生了。

有状态的流式处理架构

流式处理架构的产生主要是为了解决传统事务处理架构和离线分析处理架构存在的问题,我们为了保证处理的实时性,直接将数据保存在本地内存中,传统数据处理架构中,我们将数据存储在关系型数据库中,流式处理直接将数据存储在本地内存中,我们成为本地状态。优点在于内存数据的读取更快,当数据存储大小受限时,直接扩展集群即可。流式处理架构可以实现每一条请求或者数据到达,经过流式处理,都可以快速得到一条对应的响应。

流式处理像一个管道,数据从一边流入,进行处理后,从另一边流出,但后边如果像继续使用,也可以拿出来消费。

为了保证容错性,架构中还有check point机制,既定时周期性的将本地状态保存在远程的存储空间中,这样当出现故障我们可以通过远程存储中把它恢复出来。具体架构如下:

avatar

这样我们就解决了传统处理和离线处理架构中存储大和高延迟的问题。当数据量大时,可以做成分布式,但是分布式可能存在网络延迟带来的乱序问题,这时我们怎么保证数据处理的正确性呢,因为我们流式处理架构是集群架构,我们无法保证当因为网络或者其他问题导致数据延迟到达而产生的的问题(例如我们要统计截止当天结束的某些数据,但是有些数据因为延迟导致它在当天时间节点结束后才到达,这样就会导致计算出现误差甚至错误),此流式架构就无法解决此问题,所以流式处理架构有了一些演变,就产生了lambda架构。

Lambda架构

为了解决数据的正确性问题,Lambda架构使用两套系统,同时保证低延迟和结果准确性(流处理保证数据的实时性,批处理保证数据的准确性)。

当有数据输入时,来一条处理一条,隔一段时间,采用批处理的方式,处理一批数据,保证结果的准确性,所以用户这边看到的情况是,数据实时显示,但隔一段时间后,数据可能还会变化。

具体架构如下:

avatar

Batch Layer:该层主要利用分布式处理系统处理大批量的数据,在数据集上预先计算查询函数,并构建查询所对应的Batch View。即所谓的批处理,适合处理离线数据。

Speed Layer:该层的目的是提供低延时的 Real-time View,处理的都是实时的增量数据。

Serving Layer:Serving Layer 用于响应用户的查询请求,它将 Batch Views 和 Real-time Views 的结果进行了合并,得到最后的结果。

Lambda架构存在以下缺点:

  1. Lambda 架构需要在两个不同的API中对同样的业务逻辑进行两次编程:一次为批量计算的系统,一次为流式计算的系统。针对同一个业务问题产生了两个代码库,各有不同的漏洞。这种系统实际上非常难维护。
  2. 随着数据增量的增大,T+1 的批处理计算时间可能不够(当天的数据,一个晚上可能处理不完)。
  3. 实时与批量计算结果不一致引起的数据口径问题。

Kappa架构

与 Lambda 架构不同的是,Kappa 架构去掉了批处理层这一体系结构,而只保留了Speed层。你只需要在业务逻辑改变又或者是代码更改的时候进行数据的重新处理。具体架构如下:

avatar

其核心思想就是,使用系统(例如:Kafka)保存历史消息数据, 然后通过回放数据,利用 Real-time Layer 这一层的流处理框架(Flink , Spark Streaming , Storm)来完成业务上的批处理需求。核心步骤如下:

  1. 数据需要可以被重放(重新处理)。例如, 用 Kafka 来保存数据,你需要几天的数据量就保存几天。

  2. 用新实例重新处理计算重放的数据。即当需要全量重新计算时,重新起一个流计算实例,从头开始读取数据进行处理,并输出到一个新的结果存储中。

  3. 当新的实例做完后,停止老的流计算实例,并把老的一些结果删除。

需要说明的是:Flink实现了真正的流处理,并且做到了低延迟、高吞吐 和 exactly-once 语义;同时还支持有状态的计算(即使在发生故障时也能准确的处理计算状态) 和 基于事件时间的处理。可见,Flink不管是在 Lambda 架构还是 Kappa 架构中都能占有一席之地,特别是在Kappa 架构中,使用Flink是个很好的选择。

最后更新: 2021年02月05日 16:54

原始链接: https://jjw-story.github.io/2021/02/05/Flink入门/

× 请我吃糖~
打赏二维码