精华内容
下载资源
问答
  • 2019-07-09 19:15:25

    原文链接

    简介

    大数据是收集、整理、处理大容量数据集,并从中获得见解所需的非传统战略和技术的总称。虽然处理数据所需的计算能力或存储容量早已超过一台计算机的上限,但这种计算类型的普遍性、规模,以及价值在最近几年才经历了大规模扩展。

    在之前的文章中,我们曾经介绍过有关大数据系统的常规概念、处理过程,以及各种专门术语,本文将介绍大数据系统一个最基本的组件:处理框架。处理框架负责对系统中的数据进行计算,例如处理从非易失存储中读取的数据,或处理刚刚摄入到系统中的数据。数据的计算则是指从大量单一数据点中提取信息和见解的过程。
    下文将介绍这些框架:

    仅批处理框架:
        Apache Hadoop
    仅流处理框架:
        Apache Storm
        Apache Samza
    混合框架:
        Apache Spark
        Apache Flink
    

    大数据处理框架是什么?

    处理框架和处理引擎负责对数据系统中的数据进行计算。虽然“引擎”和“框架”之间的区别没有什么权威的定义,但大部分时候可以将前者定义为实际负责处理数据操作的组件,后者则可定义为承担类似作用的一系列组件。

    例如Apache Hadoop可以看作一种以MapReduce作为默认处理引擎的处理框架。引擎和框架通常可以相互替换或同时使用。例如另一个框架Apache Spark可以纳入Hadoop并取代MapReduce。组件之间的这种互操作性是大数据系统灵活性如此之高的原因之一。

    虽然负责处理生命周期内这一阶段数据的系统通常都很复杂,但从广义层面来看它们的目标是非常一致的:通过对数据执行操作提高理解能力,揭示出数据蕴含的模式,并针对复杂互动获得见解。

    为了简化这些组件的讨论,我们会通过不同处理框架的设计意图,按照所处理的数据状态对其进行分类。一些系统可以用批处理方式处理数据,一些系统可以用流方式处理连续不断流入系统的数据。此外还有一些系统可以同时处理这两类数据。

    在深入介绍不同实现的指标和结论之前,首先需要对不同处理类型的概念进行一个简单的介绍。

    一、批处理系统

    批处理在大数据世界有着悠久的历史。批处理主要操作大容量静态数据集,并在计算过程完成后返回结果。

    批处理模式中使用的数据集通常符合下列特征…

    有界:批处理数据集代表数据的有限集合
    持久:数据通常始终存储在某种类型的持久存储位置中
    大量:批处理操作通常是处理极为海量数据集的唯一方法
    

    批处理非常适合需要访问全套记录才能完成的计算工作。例如在计算总数和平均数时,必须将数据集作为一个整体加以处理,而不能将其视作多条记录的集合。这些操作要求在计算进行过程中数据维持自己的状态。

    需要处理大量数据的任务通常最适合用批处理操作进行处理。无论直接从持久存储设备处理数据集,或首先将数据集载入内存,批处理系统在设计过程中就充分考虑了数据的量,可提供充足的处理资源。由于批处理在应对大量持久数据方面的表现极为出色,因此经常被用于对历史数据进行分析。

    大量数据的处理需要付出大量时间,因此批处理不适合对处理时间要求较高的场合。

    Apache Hadoop

    Apache Hadoop是一种专用于批处理的处理框架。Hadoop是首个在开源社区获得极大关注的大数据框架。基于谷歌有关海量数据处理所发表的多篇论文与经验的Hadoop重新实现了相关算法和组件堆栈,让大规模批处理技术变得更易用。

    新版Hadoop包含多个组件,即多个层,通过配合使用可处理批数据:

    HDFS:HDFS是一种分布式文件系统层,可对集群节点间的存储和复制进行协调。HDFS确保了无法避免的节点故障发生后数据依然可用,可将其用作数据来源,可用于存储中间态的处理结果,并可存储计算的最终结果。
    YARN:YARN是Yet Another Resource Negotiator(另一个资源管理器)的缩写,可充当Hadoop堆栈的集群协调组件。该组件负责协调并管理底层资源和调度作业的运行。通过充当集群资源的接口,YARN使得用户能在Hadoop集群中使用比以往的迭代方式运行更多类型的工作负载。
    MapReduce:MapReduce是Hadoop的原生批处理引擎。
    

    批处理模式

    Hadoop的处理功能来自MapReduce引擎。MapReduce的处理技术符合使用键值对的map、shuffle、reduce算法要求。基本处理过程包括:

    从HDFS文件系统读取数据集
    将数据集拆分成小块并分配给所有可用节点
    针对每个节点上的数据子集进行计算(计算的中间态结果会重新写入HDFS)
    重新分配中间态结果并按照键进行分组
    通过对每个节点计算的结果进行汇总和组合对每个键的值进行“Reducing”
    将计算而来的最终结果重新写入 HDFS
    

    优势和局限

    由于这种方法严重依赖持久存储,每个任务需要多次执行读取和写入操作,因此速度相对较慢。但另一方面由于磁盘空间通常是服务器上最丰富的资源,这意味着MapReduce可以处理非常海量的数据集。同时也意味着相比其他类似技术,Hadoop的MapReduce通常可以在廉价硬件上运行,因为该技术并不需要将一切都存储在内存中。MapReduce具备极高的缩放潜力,生产环境中曾经出现过包含数万个节点的应用。

    MapReduce的学习曲线较为陡峭,虽然Hadoop生态系统的其他周边技术可以大幅降低这一问题的影响,但通过Hadoop集群快速实现某些应用时依然需要注意这个问题。

    围绕Hadoop已经形成了辽阔的生态系统,Hadoop集群本身也经常被用作其他软件的组成部件。很多其他处理框架和引擎通过与Hadoop集成也可以使用HDFS和YARN资源管理器。

    总结

    Apache Hadoop及其MapReduce处理引擎提供了一套久经考验的批处理模型,最适合处理对时间要求不高的非常大规模数据集。通过非常低成本的组件即可搭建完整功能的Hadoop集群,使得这一廉价且高效的处理技术可以灵活应用在很多案例中。与其他框架和引擎的兼容与集成能力使得Hadoop可以成为使用不同技术的多种工作负载处理平台的底层基础。

    二、流处理系统

    流处理系统会对随时进入系统的数据进行计算。相比批处理模式,这是一种截然不同的处理方式。流处理方式无需针对整个数据集执行操作,而是对通过系统传输的每个数据项执行操作。

    流处理中的数据集是“无边界”的,这就产生了几个重要的影响:

    完整数据集只能代表截至目前已经进入到系统中的数据总量。
    工作数据集也许更相关,在特定时间只能代表某个单一数据项。
    处理工作是基于事件的,除非明确停止否则没有“尽头”。处理结果立刻可用,并会随着新数据的抵达继续更新。
    

    流处理系统可以处理几乎无限量的数据,但同一时间只能处理一条(真正的流处理)或很少量(微批处理,Micro-batch Processing)数据,不同记录间只维持最少量的状态。虽然大部分系统提供了用于维持某些状态的方法,但流处理主要针对副作用更少,更加功能性的处理(Functional processing)进行优化。

    功能性操作主要侧重于状态或副作用有限的离散步骤。针对同一个数据执行同一个操作会或略其他因素产生相同的结果,此类处理非常适合流处理,因为不同项的状态通常是某些困难、限制,以及某些情况下不需要的结果的结合体。因此虽然某些类型的状态管理通常是可行的,但这些框架通常在不具备状态管理机制时更简单也更高效。

    此类处理非常适合某些类型的工作负载。有近实时处理需求的任务很适合使用流处理模式。分析、服务器或应用程序错误日志,以及其他基于时间的衡量指标是最适合的类型,因为对这些领域的数据变化做出响应对于业务职能来说是极为关键的。流处理很适合用来处理必须对变动或峰值做出响应,并且关注一段时间内变化趋势的数据。

    Apache Storm

    Apache Storm是一种侧重于极低延迟的流处理框架,也许是要求近实时处理的工作负载的最佳选择。该技术可处理非常大量的数据,通过比其他解决方案更低的延迟提供结果。

    流处理模式

    Storm的流处理可对框架中名为Topology(拓扑)的DAG(Directed Acyclic Graph,有向无环图)进行编排。这些拓扑描述了当数据片段进入系统后,需要对每个传入的片段执行的不同转换或步骤。

    拓扑包含:

    Stream:普通的数据流,这是一种会持续抵达系统的无边界数据。
    Spout:位于拓扑边缘的数据流来源,例如可以是API或查询等,从这里可以产生待处理的数据。
    Bolt:Bolt代表需要消耗流数据,对其应用操作,并将结果以流的形式进行输出的处理步骤。Bolt需要与每个Spout建立连接,随后相互连接以组成所有必要的处理。在拓扑的尾部,可以使用最终的Bolt输出作为相互连接的其他系统的输入。
    

    Storm背后的想法是使用上述组件定义大量小型的离散操作,随后将多个组件组成所需拓扑。默认情况下Storm提供了“至少一次”的处理保证,这意味着可以确保每条消息至少可以被处理一次,但某些情况下如果遇到失败可能会处理多次。Storm无法确保可以按照特定顺序处理消息。

    为了实现严格的一次处理,即有状态处理,可以使用一种名为Trident的抽象。严格来说不使用Trident的Storm通常可称之为Core Storm。Trident会对Storm的处理能力产生极大影响,会增加延迟,为处理提供状态,使用微批模式代替逐项处理的纯粹流处理模式。

    为避免这些问题,通常建议Storm用户尽可能使用Core Storm。然而也要注意,Trident对内容严格的一次处理保证在某些情况下也比较有用,例如系统无法智能地处理重复消息时。如果需要在项之间维持状态,例如想要计算一个小时内有多少用户点击了某个链接,此时Trident将是你唯一的选择。尽管不能充分发挥框架与生俱来的优势,但Trident提高了Storm的灵活性。

    Trident拓扑包含:

    流批(Stream batch):这是指流数据的微批,可通过分块提供批处理语义。
    操作(Operation):是指可以对数据执行的批处理过程。
    

    优势和局限

    目前来说Storm可能是近实时处理领域的最佳解决方案。该技术可以用极低延迟处理数据,可用于希望获得最低延迟的工作负载。如果处理速度直接影响用户体验,例如需要将处理结果直接提供给访客打开的网站页面,此时Storm将会是一个很好的选择。

    Storm与Trident配合使得用户可以用微批代替纯粹的流处理。虽然借此用户可以获得更大灵活性打造更符合要求的工具,但同时这种做法会削弱该技术相比其他解决方案最大的优势。话虽如此,但多一种流处理方式总是好的。

    Core Storm无法保证消息的处理顺序。Core Storm为消息提供了“至少一次”的处理保证,这意味着可以保证每条消息都能被处理,但也可能发生重复。Trident提供了严格的一次处理保证,可以在不同批之间提供顺序处理,但无法在一个批内部实现顺序处理。

    在互操作性方面,Storm可与Hadoop的YARN资源管理器进行集成,因此可以很方便地融入现有Hadoop部署。除了支持大部分处理框架,Storm还可支持多种语言,为用户的拓扑定义提供了更多选择。

    总结

    对于延迟需求很高的纯粹的流处理工作负载,Storm可能是最适合的技术。该技术可以保证每条消息都被处理,可配合多种编程语言使用。由于Storm无法进行批处理,如果需要这些能力可能还需要使用其他软件。如果对严格的一次处理保证有比较高的要求,此时可考虑使用Trident。不过这种情况下其他流处理框架也许更适合。

    Apache Samza

    Apache Samza是一种与Apache Kafka消息系统紧密绑定的流处理框架。虽然Kafka可用于很多流处理系统,但按照设计,Samza可以更好地发挥Kafka独特的架构优势和保障。该技术可通过Kafka提供容错、缓冲,以及状态存储。

    Samza可使用YARN作为资源管理器。这意味着默认情况下需要具备Hadoop集群(至少具备HDFS和YARN),但同时也意味着Samza可以直接使用YARN丰富的内建功能。

    流处理模式

    Samza依赖Kafka的语义定义流的处理方式。Kafka在处理数据时涉及下列概念:

    Topic(话题):进入Kafka系统的每个数据流可称之为一个话题。话题基本上是一种可供消耗方订阅的,由相关信息组成的数据流。
    Partition(分区):为了将一个话题分散至多个节点,Kafka会将传入的消息划分为多个分区。分区的划分将基于键(Key)进行,这样可以保证包含同一个键的每条消息可以划分至同一个分区。分区的顺序可获得保证。
    Broker(代理):组成Kafka集群的每个节点也叫做代理。
    Producer(生成方):任何向Kafka话题写入数据的组件可以叫做生成方。生成方可提供将话题划分为分区所需的键。
    Consumer(消耗方):任何从Kafka读取话题的组件可叫做消耗方。消耗方需要负责维持有关自己分支的信息,这样即可在失败后知道哪些记录已经被处理过了。
    

    由于Kafka相当于永恒不变的日志,Samza也需要处理永恒不变的数据流。这意味着任何转换创建的新数据流都可被其他组件所使用,而不会对最初的数据流产生影响。

    优势和局限

    乍看之下,Samza对Kafka类查询系统的依赖似乎是一种限制,然而这也可以为系统提供一些独特的保证和功能,这些内容也是其他流处理系统不具备的。

    例如Kafka已经提供了可以通过低延迟方式访问的数据存储副本,此外还可以为每个数据分区提供非常易用且低成本的多订阅者模型。所有输出内容,包括中间态的结果都可写入到Kafka,并可被下游步骤独立使用。

    这种对Kafka的紧密依赖在很多方面类似于MapReduce引擎对HDFS的依赖。虽然在批处理的每个计算之间对HDFS的依赖导致了一些严重的性能问题,但也避免了流处理遇到的很多其他问题。

    Samza与Kafka之间紧密的关系使得处理步骤本身可以非常松散地耦合在一起。无需事先协调,即可在输出的任何步骤中增加任意数量的订阅者,对于有多个团队需要访问类似数据的组织,这一特性非常有用。多个团队可以全部订阅进入系统的数据话题,或任意订阅其他团队对数据进行过某些处理后创建的话题。这一切并不会对数据库等负载密集型基础架构造成额外的压力。

    直接写入Kafka还可避免回压(Backpressure)问题。回压是指当负载峰值导致数据流入速度超过组件实时处理能力的情况,这种情况可能导致处理工作停顿并可能丢失数据。按照设计,Kafka可以将数据保存很长时间,这意味着组件可以在方便的时候继续进行处理,并可直接重启动而无需担心造成任何后果。

    Samza可以使用以本地键值存储方式实现的容错检查点系统存储数据。这样Samza即可获得“至少一次”的交付保障,但面对由于数据可能多次交付造成的失败,该技术无法对汇总后状态(例如计数)提供精确恢复。

    Samza提供的高级抽象使其在很多方面比Storm等系统提供的基元(Primitive)更易于配合使用。目前Samza只支持JVM语言,这意味着它在语言支持方面不如Storm灵活。

    总结

    对于已经具备或易于实现Hadoop和Kafka的环境,Apache Samza是流处理工作负载一个很好的选择。Samza本身很适合有多个团队需要使用(但相互之间并不一定紧密协调)不同处理阶段的多个数据流的组织。Samza可大幅简化很多流处理工作,可实现低延迟的性能。如果部署需求与当前系统不兼容,也许并不适合使用,但如果需要极低延迟的处理,或对严格的一次处理语义有较高需求,此时依然适合考虑。

    三、混合处理系统:批处理和流处理

    一些处理框架可同时处理批处理和流处理工作负载。这些框架可以用相同或相关的组件和API处理两种类型的数据,借此让不同的处理需求得以简化。

    如你所见,这一特性主要是由Spark和Flink实现的,下文将介绍这两种框架。实现这样的功能重点在于两种不同处理模式如何进行统一,以及要对固定和不固定数据集之间的关系进行何种假设。

    虽然侧重于某一种处理类型的项目会更好地满足具体用例的要求,但混合框架意在提供一种数据处理的通用解决方案。这种框架不仅可以提供处理数据所需的方法,而且提供了自己的集成项、库、工具,可胜任图形分析、机器学习、交互式查询等多种任务。

    Apache Spark

    Apache Spark是一种包含流处理能力的下一代批处理框架。与Hadoop的MapReduce引擎基于各种相同原则开发而来的Spark主要侧重于通过完善的内存计算和处理优化机制加快批处理工作负载的运行速度。

    Spark可作为独立集群部署(需要相应存储层的配合),或可与Hadoop集成并取代MapReduce引擎。

    批处理模式

    与MapReduce不同,Spark的数据处理工作全部在内存中进行,只在一开始将数据读入内存,以及将最终结果持久存储时需要与存储层交互。所有中间态的处理结果均存储在内存中。

    虽然内存中处理方式可大幅改善性能,Spark在处理与磁盘有关的任务时速度也有很大提升,因为通过提前对整个任务集进行分析可以实现更完善的整体式优化。为此Spark可创建代表所需执行的全部操作,需要操作的数据,以及操作和数据之间关系的Directed Acyclic Graph(有向无环图),即DAG,借此处理器可以对任务进行更智能的协调。

    为了实现内存中批计算,Spark会使用一种名为Resilient Distributed Dataset(弹性分布式数据集),即RDD的模型来处理数据。这是一种代表数据集,只位于内存中,永恒不变的结构。针对RDD执行的操作可生成新的RDD。每个RDD可通过世系(Lineage)回溯至父级RDD,并最终回溯至磁盘上的数据。Spark可通过RDD在无需将每个操作的结果写回磁盘的前提下实现容错。

    流处理模式

    流处理能力是由Spark Streaming实现的。Spark本身在设计上主要面向批处理工作负载,为了弥补引擎设计和流处理工作负载特征方面的差异,Spark实现了一种叫做微批(Micro-batch)*的概念。在具体策略方面该技术可以将数据流视作一系列非常小的“批”,借此即可通过批处理引擎的原生语义进行处理。

    Spark Streaming会以亚秒级增量对流进行缓冲,随后这些缓冲会作为小规模的固定数据集进行批处理。这种方式的实际效果非常好,但相比真正的流处理框架在性能方面依然存在不足。

    优势和局限

    使用Spark而非Hadoop MapReduce的主要原因是速度。在内存计算策略和先进的DAG调度等机制的帮助下,Spark可以用更快速度处理相同的数据集。

    Spark的另一个重要优势在于多样性。该产品可作为独立集群部署,或与现有Hadoop集群集成。该产品可运行批处理和流处理,运行一个集群即可处理不同类型的任务。

    除了引擎自身的能力外,围绕Spark还建立了包含各种库的生态系统,可为机器学习、交互式查询等任务提供更好的支持。相比MapReduce,Spark任务更是“众所周知”地易于编写,因此可大幅提高生产力。

    为流处理系统采用批处理的方法,需要对进入系统的数据进行缓冲。缓冲机制使得该技术可以处理非常大量的传入数据,提高整体吞吐率,但等待缓冲区清空也会导致延迟增高。这意味着Spark Streaming可能不适合处理对延迟有较高要求的工作负载。

    由于内存通常比磁盘空间更贵,因此相比基于磁盘的系统,Spark成本更高。然而处理速度的提升意味着可以更快速完成任务,在需要按照小时数为资源付费的环境中,这一特性通常可以抵消增加的成本。

    Spark内存计算这一设计的另一个后果是,如果部署在共享的集群中可能会遇到资源不足的问题。相比Hadoop MapReduce,Spark的资源消耗更大,可能会对需要在同一时间使用集群的其他任务产生影响。从本质来看,Spark更不适合与Hadoop堆栈的其他组件共存一处。

    总结

    Spark是多样化工作负载处理任务的最佳选择。Spark批处理能力以更高内存占用为代价提供了无与伦比的速度优势。对于重视吞吐率而非延迟的工作负载,则比较适合使用Spark Streaming作为流处理解决方案。

    Apache Flink

    Apache Flink是一种可以处理批处理任务的流处理框架。该技术可将批处理数据视作具备有限边界的数据流,借此将批处理任务作为流处理的子集加以处理。为所有处理任务采取流处理为先的方法会产生一系列有趣的副作用。

    这种流处理为先的方法也叫做Kappa架构,与之相对的是更加被广为人知的Lambda架构(该架构中使用批处理作为主要处理方法,使用流作为补充并提供早期未经提炼的结果)。Kappa架构中会对一切进行流处理,借此对模型进行简化,而这一切是在最近流处理引擎逐渐成熟后才可行的。

    流处理模型

    Flink的流处理模型在处理传入数据时会将每一项视作真正的数据流。Flink提供的DataStream API可用于处理无尽的数据流。Flink可配合使用的基本组件包括:

    Stream(流):是指在系统中流转的,永恒不变的无边界数据集
    Operator(操作方):是指针对数据流执行操作以产生其他数据流的功能
    Source(源):是指数据流进入系统的入口点
    Sink(槽):是指数据流离开Flink系统后进入到的位置,槽可以是数据库或到其他系统的连接器
    

    为了在计算过程中遇到问题后能够恢复,流处理任务会在预定时间点创建快照。为了实现状态存储,Flink可配合多种状态后端系统使用,具体取决于所需实现的复杂度和持久性级别。

    此外Flink的流处理能力还可以理解“事件时间”这一概念,这是指事件实际发生的时间,此外该功能还可以处理会话。这意味着可以通过某种有趣的方式确保执行顺序和分组。

    批处理模型

    Flink的批处理模型在很大程度上仅仅是对流处理模型的扩展。此时模型不再从持续流中读取数据,而是从持久存储中以流的形式读取有边界的数据集。Flink会对这些处理模型使用完全相同的运行时。

    Flink可以对批处理工作负载实现一定的优化。例如由于批处理操作可通过持久存储加以支持,Flink可以不对批处理工作负载创建快照。数据依然可以恢复,但常规处理操作可以执行得更快。

    另一个优化是对批处理任务进行分解,这样即可在需要的时候调用不同阶段和组件。借此Flink可以与集群的其他用户更好地共存。对任务提前进行分析使得Flink可以查看需要执行的所有操作、数据集的大小,以及下游需要执行的操作步骤,借此实现进一步的优化。

    优势和局限

    Flink目前是处理框架领域一个独特的技术。虽然Spark也可以执行批处理和流处理,但Spark的流处理采取的微批架构使其无法适用于很多用例。Flink流处理为先的方法可提供低延迟,高吞吐率,近乎逐项处理的能力。

    Flink的很多组件是自行管理的。虽然这种做法较为罕见,但出于性能方面的原因,该技术可自行管理内存,无需依赖原生的Java垃圾回收机制。与Spark不同,待处理数据的特征发生变化后Flink无需手工优化和调整,并且该技术也可以自行处理数据分区和自动缓存等操作。

    Flink会通过多种方式对工作进行分许进而优化任务。这种分析在部分程度上类似于SQL查询规划器对关系型数据库所做的优化,可针对特定任务确定最高效的实现方法。该技术还支持多阶段并行执行,同时可将受阻任务的数据集合在一起。对于迭代式任务,出于性能方面的考虑,Flink会尝试在存储数据的节点上执行相应的计算任务。此外还可进行“增量迭代”,或仅对数据中有改动的部分进行迭代。

    在用户工具方面,Flink提供了基于Web的调度视图,借此可轻松管理任务并查看系统状态。用户也可以查看已提交任务的优化方案,借此了解任务最终是如何在集群中实现的。对于分析类任务,Flink提供了类似SQL的查询,图形化处理,以及机器学习库,此外还支持内存计算。

    Flink能很好地与其他组件配合使用。如果配合Hadoop 堆栈使用,该技术可以很好地融入整个环境,在任何时候都只占用必要的资源。该技术可轻松地与YARN、HDFS和Kafka 集成。在兼容包的帮助下,Flink还可以运行为其他处理框架,例如Hadoop和Storm编写的任务。

    目前Flink最大的局限之一在于这依然是一个非常“年幼”的项目。现实环境中该项目的大规模部署尚不如其他处理框架那么常见,对于Flink在缩放能力方面的局限目前也没有较为深入的研究。随着快速开发周期的推进和兼容包等功能的完善,当越来越多的组织开始尝试时,可能会出现越来越多的Flink部署。

    总结

    Flink提供了低延迟流处理,同时可支持传统的批处理任务。Flink也许最适合有极高流处理需求,并有少量批处理任务的组织。该技术可兼容原生Storm和Hadoop程序,可在YARN管理的集群上运行,因此可以很方便地进行评估。快速进展的开发工作使其值得被大家关注。

    结论

    大数据系统可使用多种处理技术。

    对于仅需要批处理的工作负载,如果对时间不敏感,比其他解决方案实现成本更低的Hadoop将会是一个好选择。

    对于仅需要流处理的工作负载,Storm可支持更广泛的语言并实现极低延迟的处理,但默认配置可能产生重复结果并且无法保证顺序。Samza与YARN和Kafka紧密集成可提供更大灵活性,更易用的多团队使用,以及更简单的复制和状态管理。

    对于混合型工作负载,Spark可提供高速批处理和微批处理模式的流处理。该技术的支持更完善,具备各种集成库和工具,可实现灵活的集成。Flink提供了真正的流处理并具备批处理能力,通过深度优化可运行针对其他平台编写的任务,提供低延迟的处理,但实际应用方面还为时过早。

    最适合的解决方案主要取决于待处理数据的状态,对处理所需时间的需求,以及希望得到的结果。具体是使用全功能解决方案或主要侧重于某种项目的解决方案,这个问题需要慎重权衡。随着逐渐成熟并被广泛接受,在评估任何新出现的创新型解决方案时都需要考虑类似的问题。

    更多相关内容
  • 批处理与流处理详解

    千次阅读 2019-09-18 16:34:50
    大数据是收集、整理、处理大容量数据集,并从中获得见解所需的非传统战略和技术的总称。虽然处理数据所需的计算能力或存储容量早已超过一台计算机的上限,但这种计算类型的普遍性、规模,以及价值在最近几年才经历了...

    大数据是收集、整理、处理大容量数据集,并从中获得见解所需的非传统战略和技术的总称。虽然处理数据所需的计算能力或存储容量早已超过一台计算机的上限,但这种计算类型的普遍性、规模,以及价值在最近几年才经历了大规模扩展。

    本文将介绍大数据系统一个最基本的组件:处理框架。处理框架负责对系统中的数据进行计算,例如处理从非易失存储中读取的数据,或处理刚刚摄入到系统中的数据。数据的计算则是指从大量单一数据点中提取信息和见解的过程。

    下文将介绍这些框架:

    仅批处理框架:

    Apache Hadoop

    仅流处理框架:

    Apache Storm

    Apache Samza

    混合框架:

    Apache Spark

    Apache Flink

    批处理系统

    image

    批处理在大数据世界有着悠久的历史。批处理主要操作大容量静态数据集,并在计算过程完成后返回结果。

    批处理模式中使用的数据集通常符合下列特征...

    • 有界:批处理数据集代表数据的有限集合

    • 持久:数据通常始终存储在某种类型的持久存储位置中

    • 大量:批处理操作通常是处理极为海量数据集的唯一方法

    批处理非常适合需要访问全套记录才能完成的计算工作。例如在计算总数和平均数时,必须将数据集作为一个整体加以处理,而不能将其视作多条记录的集合。这些操作要求在计算进行过程中数据维持自己的状态。

    需要处理大量数据的任务通常最适合用批处理操作进行处理。无论直接从持久存储设备处理数据集,或首先将数据集载入内存,批处理系统在设计过程中就充分考虑了数据的量,可提供充足的处理资源。由于批处理在应对大量持久数据方面的表现极为出色,因此经常被用于对历史数据进行分析。

    大量数据的处理需要付出大量时间,因此批处理不适合对处理时间要求较高的场合。
    Apache Hadoop
    Apache Hadoop是一种专用于批处理的处理框架。Hadoop是首个在开源社区获得极大关注的大数据框架。基于谷歌有关海量数据处理所发表的多篇论文与经验的Hadoop重新实现了相关算法和组件堆栈,让大规模批处理技术变得更易用。

    新版Hadoop包含多个组件,即多个层,通过配合使用可处理批数据:

    HDFS:HDFS是一种分布式文件系统层,可对集群节点间的存储和复制进行协调。HDFS确保了无法避免的节点故障发生后数据依然可用,可将其用作数据来源,可用于存储中间态的处理结果,并可存储计算的最终结果。

    YARN:YARN是Yet Another Resource Negotiator(另一个资源管理器)的缩写,可充当Hadoop堆栈的集群协调组件。该组件负责协调并管理底层资源和调度作业的运行。通过充当集群资源的接口,YARN使得用户能在Hadoop集群中使用比以往的迭代方式运行更多类型的工作负载。

    MapReduce:MapReduce是Hadoop的原生批处理引擎。

    批处理模式
    Hadoop的处理功能来自MapReduce引擎。MapReduce的处理技术符合使用键值对的map、shuffle、reduce算法要求。基本处理过程包括:

    从HDFS文件系统读取数据集

    将数据集拆分成小块并分配给所有可用节点

    针对每个节点上的数据子集进行计算(计算的中间态结果会重新写入HDFS)

    重新分配中间态结果并按照键进行分组

    通过对每个节点计算的结果进行汇总和组合对每个键的值进行“Reducing”

    将计算而来的最终结果重新写入 HDFS

    优势和局限
    由于这种方法严重依赖持久存储,每个任务需要多次执行读取和写入操作,因此速度相对较慢。但另一方面由于磁盘空间通常是服务器上最丰富的资源,这意味着MapReduce可以处理非常海量的数据集。同时也意味着相比其他类似技术,Hadoop的MapReduce通常可以在廉价硬件上运行,因为该技术并不需要将一切都存储在内存中。MapReduce具备极高的缩放潜力,生产环境中曾经出现过包含数万个节点的应用。

    MapReduce的学习曲线较为陡峭,虽然Hadoop生态系统的其他周边技术可以大幅降低这一问题的影响,但通过Hadoop集群快速实现某些应用时依然需要注意这个问题。

    围绕Hadoop已经形成了辽阔的生态系统,Hadoop集群本身也经常被用作其他软件的组成部件。很多其他处理框架和引擎通过与Hadoop集成也可以使用HDFS和YARN资源管理器。

    总结
    Apache Hadoop及其MapReduce处理引擎提供了一套久经考验的批处理模型,最适合处理对时间要求不高的非常大规模数据集。通过非常低成本的组件即可搭建完整功能的Hadoop集群,使得这一廉价且高效的处理技术可以灵活应用在很多案例中。与其他框架和引擎的兼容与集成能力使得Hadoop可以成为使用不同技术的多种工作负载处理平台的底层基础。

    流处理系统

    image

    流处理系统会对随时进入系统的数据进行计算。相比批处理模式,这是一种截然不同的处理方式。流处理方式无需针对整个数据集执行操作,而是对通过系统传输的每个数据项执行操作。

    流处理中的数据集是“无边界”的,这就产生了几个重要的影响:

    • 完整数据集只能代表截至目前已经进入到系统中的数据总量。

    • 工作数据集也许更相关,在特定时间只能代表某个单一数据项。

    • 处理工作是基于事件的,除非明确停止否则没有“尽头”。处理结果立刻可用,并会随着新数据的抵达继续更新。

    流处理系统可以处理几乎无限量的数据,但同一时间只能处理一条(真正的流处理)或很少量(微批处理,Micro-batch Processing)数据,不同记录间只维持最少量的状态。虽然大部分系统提供了用于维持某些状态的方法,但流处理主要针对副作用更少,更加功能性的处理(Functional processing)进行优化。

    功能性操作主要侧重于状态或副作用有限的离散步骤。针对同一个数据执行同一个操作会或略其他因素产生相同的结果,此类处理非常适合流处理,因为不同项的状态通常是某些困难、限制,以及某些情况下不需要的结果的结合体。因此虽然某些类型的状态管理通常是可行的,但这些框架通常在不具备状态管理机制时更简单也更高效。

    此类处理非常适合某些类型的工作负载。有近实时处理需求的任务很适合使用流处理模式。分析、服务器或应用程序错误日志,以及其他基于时间的衡量指标是最适合的类型,因为对这些领域的数据变化做出响应对于业务职能来说是极为关键的。流处理很适合用来处理必须对变动或峰值做出响应,并且关注一段时间内变化趋势的数据。

    Apache Storm

    Apache Storm是一种侧重于极低延迟的流处理框架,也许是要求近实时处理的工作负载的最佳选择。该技术可处理非常大量的数据,通过比其他解决方案更低的延迟提供结果。

    流处理模式

    Storm的流处理可对框架中名为Topology(拓扑)的DAG(Directed Acyclic Graph,有向无环图)进行编排。这些拓扑描述了当数据片段进入系统后,需要对每个传入的片段执行的不同转换或步骤。

    拓扑包含:

    • Stream:普通的数据流,这是一种会持续抵达系统的无边界数据。

    • Spout:位于拓扑边缘的数据流来源,例如可以是API或查询等,从这里可以产生待处理的数据。

    • Bolt:Bolt代表需要消耗流数据,对其应用操作,并将结果以流的形式进行输出的处理步骤。Bolt需要与每个Spout建立连接,随后相互连接以组成所有必要的处理。在拓扑的尾部,可以使用最终的Bolt输出作为相互连接的其他系统的输入。

    Storm背后的想法是使用上述组件定义大量小型的离散操作,随后将多个组件组成所需拓扑。默认情况下Storm提供了“至少一次”的处理保证,这意味着可以确保每条消息至少可以被处理一次,但某些情况下如果遇到失败可能会处理多次。Storm无法确保可以按照特定顺序处理消息。

    为了实现严格的一次处理,即有状态处理,可以使用一种名为Trident的抽象。严格来说不使用Trident的Storm通常可称之为Core Storm。Trident会对Storm的处理能力产生极大影响,会增加延迟,为处理提供状态,使用微批模式代替逐项处理的纯粹流处理模式。

    为避免这些问题,通常建议Storm用户尽可能使用Core Storm。然而也要注意,Trident对内容严格的一次处理保证在某些情况下也比较有用,例如系统无法智能地处理重复消息时。如果需要在项之间维持状态,例如想要计算一个小时内有多少用户点击了某个链接,此时Trident将是你唯一的选择。尽管不能充分发挥框架与生俱来的优势,但Trident提高了Storm的灵活性。

    Trident拓扑包含:

    • 流批(Stream batch):这是指流数据的微批,可通过分块提供批处理语义。

    • 操作(Operation):是指可以对数据执行的批处理过程。

    优势和局限

    目前来说Storm可能是近实时处理领域的最佳解决方案。该技术可以用极低延迟处理数据,可用于希望获得最低延迟的工作负载。如果处理速度直接影响用户体验,例如需要将处理结果直接提供给访客打开的网站页面,此时Storm将会是一个很好的选择。

    Storm与Trident配合使得用户可以用微批代替纯粹的流处理。虽然借此用户可以获得更大灵活性打造更符合要求的工具,但同时这种做法会削弱该技术相比其他解决方案最大的优势。话虽如此,但多一种流处理方式总是好的。

    Core Storm无法保证消息的处理顺序。Core Storm为消息提供了“至少一次”的处理保证,这意味着可以保证每条消息都能被处理,但也可能发生重复。Trident提供了严格的一次处理保证,可以在不同批之间提供顺序处理,但无法在一个批内部实现顺序处理。

    在互操作性方面,Storm可与Hadoop的YARN资源管理器进行集成,因此可以很方便地融入现有Hadoop部署。除了支持大部分处理框架,Storm还可支持多种语言,为用户的拓扑定义提供了更多选择。

    总结

    对于延迟需求很高的纯粹的流处理工作负载,Storm可能是最适合的技术。该技术可以保证每条消息都被处理,可配合多种编程语言使用。由于Storm无法进行批处理,如果需要这些能力可能还需要使用其他软件。如果对严格的一次处理保证有比较高的要求,此时可考虑使用Trident。不过这种情况下其他流处理框架也许更适合。

    Apache Samza

    Apache Samza是一种与Apache Kafka消息系统紧密绑定的流处理框架。虽然Kafka可用于很多流处理系统,但按照设计,Samza可以更好地发挥Kafka独特的架构优势和保障。该技术可通过Kafka提供容错、缓冲,以及状态存储。

    Samza可使用YARN作为资源管理器。这意味着默认情况下需要具备Hadoop集群(至少具备HDFS和YARN),但同时也意味着Samza可以直接使用YARN丰富的内建功能。

    流处理模式

    Samza依赖Kafka的语义定义流的处理方式。Kafka在处理数据时涉及下列概念:

    • Topic(话题):进入Kafka系统的每个数据流可称之为一个话题。话题基本上是一种可供消耗方订阅的,由相关信息组成的数据流。

    • Partition(分区):为了将一个话题分散至多个节点,Kafka会将传入的消息划分为多个分区。分区的划分将基于键(Key)进行,这样可以保证包含同一个键的每条消息可以划分至同一个分区。分区的顺序可获得保证。

    • Broker(代理):组成Kafka集群的每个节点也叫做代理。

    • Producer(生成方):任何向Kafka话题写入数据的组件可以叫做生成方。生成方可提供将话题划分为分区所需的键。

    • Consumer(消耗方):任何从Kafka读取话题的组件可叫做消耗方。消耗方需要负责维持有关自己分支的信息,这样即可在失败后知道哪些记录已经被处理过了。

    由于Kafka相当于永恒不变的日志,Samza也需要处理永恒不变的数据流。这意味着任何转换创建的新数据流都可被其他组件所使用,而不会对最初的数据流产生影响。

    优势和局限

    乍看之下,Samza对Kafka类查询系统的依赖似乎是一种限制,然而这也可以为系统提供一些独特的保证和功能,这些内容也是其他流处理系统不具备的。

    例如Kafka已经提供了可以通过低延迟方式访问的数据存储副本,此外还可以为每个数据分区提供非常易用且低成本的多订阅者模型。所有输出内容,包括中间态的结果都可写入到Kafka,并可被下游步骤独立使用。

    这种对Kafka的紧密依赖在很多方面类似于MapReduce引擎对HDFS的依赖。虽然在批处理的每个计算之间对HDFS的依赖导致了一些严重的性能问题,但也避免了流处理遇到的很多其他问题。

    Samza与Kafka之间紧密的关系使得处理步骤本身可以非常松散地耦合在一起。无需事先协调,即可在输出的任何步骤中增加任意数量的订阅者,对于有多个团队需要访问类似数据的组织,这一特性非常有用。多个团队可以全部订阅进入系统的数据话题,或任意订阅其他团队对数据进行过某些处理后创建的话题。这一切并不会对数据库等负载密集型基础架构造成额外的压力。

    直接写入Kafka还可避免回压(Backpressure)问题。回压是指当负载峰值导致数据流入速度超过组件实时处理能力的情况,这种情况可能导致处理工作停顿并可能丢失数据。按照设计,Kafka可以将数据保存很长时间,这意味着组件可以在方便的时候继续进行处理,并可直接重启动而无需担心造成任何后果。

    Samza可以使用以本地键值存储方式实现的容错检查点系统存储数据。这样Samza即可获得“至少一次”的交付保障,但面对由于数据可能多次交付造成的失败,该技术无法对汇总后状态(例如计数)提供精确恢复。

    Samza提供的高级抽象使其在很多方面比Storm等系统提供的基元(Primitive)更易于配合使用。目前Samza只支持JVM语言,这意味着它在语言支持方面不如Storm灵活。

    总结

    对于已经具备或易于实现Hadoop和Kafka的环境,Apache Samza是流处理工作负载一个很好的选择。Samza本身很适合有多个团队需要使用(但相互之间并不一定紧密协调)不同处理阶段的多个数据流的组织。Samza可大幅简化很多流处理工作,可实现低延迟的性能。如果部署需求与当前系统不兼容,也许并不适合使用,但如果需要极低延迟的处理,或对严格的一次处理语义有较高需求,此时依然适合考虑。

    混合处理系统:批处理和流处理

    image

    一些处理框架可同时处理批处理和流处理工作负载。这些框架可以用相同或相关的组件和API处理两种类型的数据,借此让不同的处理需求得以简化。

    如你所见,这一特性主要是由Spark和Flink实现的,下文将介绍这两种框架。实现这样的功能重点在于两种不同处理模式如何进行统一,以及要对固定和不固定数据集之间的关系进行何种假设。

    虽然侧重于某一种处理类型的项目会更好地满足具体用例的要求,但混合框架意在提供一种数据处理的通用解决方案。这种框架不仅可以提供处理数据所需的方法,而且提供了自己的集成项、库、工具,可胜任图形分析、机器学习、交互式查询等多种任务。

    Apache Spark

    Apache Spark是一种包含流处理能力的下一代批处理框架。与Hadoop的MapReduce引擎基于各种相同原则开发而来的Spark主要侧重于通过完善的内存计算和处理优化机制加快批处理工作负载的运行速度。

    Spark可作为独立集群部署(需要相应存储层的配合),或可与Hadoop集成并取代MapReduce引擎。

    批处理模式

    与MapReduce不同,Spark的数据处理工作全部在内存中进行,只在一开始将数据读入内存,以及将最终结果持久存储时需要与存储层交互。所有中间态的处理结果均存储在内存中。

    虽然内存中处理方式可大幅改善性能,Spark在处理与磁盘有关的任务时速度也有很大提升,因为通过提前对整个任务集进行分析可以实现更完善的整体式优化。为此Spark可创建代表所需执行的全部操作,需要操作的数据,以及操作和数据之间关系的Directed Acyclic Graph(有向无环图),即DAG,借此处理器可以对任务进行更智能的协调。

    为了实现内存中批计算,Spark会使用一种名为Resilient Distributed Dataset(弹性分布式数据集),即RDD的模型来处理数据。这是一种代表数据集,只位于内存中,永恒不变的结构。针对RDD执行的操作可生成新的RDD。每个RDD可通过世系(Lineage)回溯至父级RDD,并最终回溯至磁盘上的数据。Spark可通过RDD在无需将每个操作的结果写回磁盘的前提下实现容错。

    流处理模式

    流处理能力是由Spark Streaming实现的。Spark本身在设计上主要面向批处理工作负载,为了弥补引擎设计和流处理工作负载特征方面的差异,Spark实现了一种叫做微批(Micro-batch)*的概念。在具体策略方面该技术可以将数据流视作一系列非常小的“批”,借此即可通过批处理引擎的原生语义进行处理。

    Spark Streaming会以亚秒级增量对流进行缓冲,随后这些缓冲会作为小规模的固定数据集进行批处理。这种方式的实际效果非常好,但相比真正的流处理框架在性能方面依然存在不足。

    优势和局限

    使用Spark而非Hadoop MapReduce的主要原因是速度。在内存计算策略和先进的DAG调度等机制的帮助下,Spark可以用更快速度处理相同的数据集。

    Spark的另一个重要优势在于多样性。该产品可作为独立集群部署,或与现有Hadoop集群集成。该产品可运行批处理和流处理,运行一个集群即可处理不同类型的任务。

    除了引擎自身的能力外,围绕Spark还建立了包含各种库的生态系统,可为机器学习、交互式查询等任务提供更好的支持。相比MapReduce,Spark任务更是“众所周知”地易于编写,因此可大幅提高生产力。

    为流处理系统采用批处理的方法,需要对进入系统的数据进行缓冲。缓冲机制使得该技术可以处理非常大量的传入数据,提高整体吞吐率,但等待缓冲区清空也会导致延迟增高。这意味着Spark Streaming可能不适合处理对延迟有较高要求的工作负载。

    由于内存通常比磁盘空间更贵,因此相比基于磁盘的系统,Spark成本更高。然而处理速度的提升意味着可以更快速完成任务,在需要按照小时数为资源付费的环境中,这一特性通常可以抵消增加的成本。

    Spark内存计算这一设计的另一个后果是,如果部署在共享的集群中可能会遇到资源不足的问题。相比Hadoop MapReduce,Spark的资源消耗更大,可能会对需要在同一时间使用集群的其他任务产生影响。从本质来看,Spark更不适合与Hadoop堆栈的其他组件共存一处。

    总结

    Spark是多样化工作负载处理任务的最佳选择。Spark批处理能力以更高内存占用为代价提供了无与伦比的速度优势。对于重视吞吐率而非延迟的工作负载,则比较适合使用Spark Streaming作为流处理解决方案。

    Apache Flink

    Apache Flink是一种可以处理批处理任务的流处理框架。该技术可将批处理数据视作具备有限边界的数据流,借此将批处理任务作为流处理的子集加以处理。为所有处理任务采取流处理为先的方法会产生一系列有趣的副作用。

    这种流处理为先的方法也叫做Kappa架构,与之相对的是更加被广为人知的Lambda架构(该架构中使用批处理作为主要处理方法,使用流作为补充并提供早期未经提炼的结果)。Kappa架构中会对一切进行流处理,借此对模型进行简化,而这一切是在最近流处理引擎逐渐成熟后才可行的。

    流处理模型

    Flink的流处理模型在处理传入数据时会将每一项视作真正的数据流。Flink提供的DataStream API可用于处理无尽的数据流。Flink可配合使用的基本组件包括:

    • Stream(流)是指在系统中流转的,永恒不变的无边界数据集

    • Operator(操作方)是指针对数据流执行操作以产生其他数据流的功能

    • Source(源)是指数据流进入系统的入口点

    • Sink(槽)是指数据流离开Flink系统后进入到的位置,槽可以是数据库或到其他系统的连接器

    为了在计算过程中遇到问题后能够恢复,流处理任务会在预定时间点创建快照。为了实现状态存储,Flink可配合多种状态后端系统使用,具体取决于所需实现的复杂度和持久性级别。

    此外Flink的流处理能力还可以理解“事件时间”这一概念,这是指事件实际发生的时间,此外该功能还可以处理会话。这意味着可以通过某种有趣的方式确保执行顺序和分组。

    批处理模型

    Flink的批处理模型在很大程度上仅仅是对流处理模型的扩展。此时模型不再从持续流中读取数据,而是从持久存储中以流的形式读取有边界的数据集。Flink会对这些处理模型使用完全相同的运行时。

    Flink可以对批处理工作负载实现一定的优化。例如由于批处理操作可通过持久存储加以支持,Flink可以不对批处理工作负载创建快照。数据依然可以恢复,但常规处理操作可以执行得更快。

    另一个优化是对批处理任务进行分解,这样即可在需要的时候调用不同阶段和组件。借此Flink可以与集群的其他用户更好地共存。对任务提前进行分析使得Flink可以查看需要执行的所有操作、数据集的大小,以及下游需要执行的操作步骤,借此实现进一步的优化。

    优势和局限

    Flink目前是处理框架领域一个独特的技术。虽然Spark也可以执行批处理和流处理,但Spark的流处理采取的微批架构使其无法适用于很多用例。Flink流处理为先的方法可提供低延迟,高吞吐率,近乎逐项处理的能力。

    Flink的很多组件是自行管理的。虽然这种做法较为罕见,但出于性能方面的原因,该技术可自行管理内存,无需依赖原生的Java垃圾回收机制。与Spark不同,待处理数据的特征发生变化后Flink无需手工优化和调整,并且该技术也可以自行处理数据分区和自动缓存等操作。

    Flink会通过多种方式对工作进行分许进而优化任务。这种分析在部分程度上类似于SQL查询规划器对关系型数据库所做的优化,可针对特定任务确定最高效的实现方法。该技术还支持多阶段并行执行,同时可将受阻任务的数据集合在一起。对于迭代式任务,出于性能方面的考虑,Flink会尝试在存储数据的节点上执行相应的计算任务。此外还可进行“增量迭代”,或仅对数据中有改动的部分进行迭代。

    在用户工具方面,Flink提供了基于Web的调度视图,借此可轻松管理任务并查看系统状态。用户也可以查看已提交任务的优化方案,借此了解任务最终是如何在集群中实现的。对于分析类任务,Flink提供了类似SQL的查询,图形化处理,以及机器学习库,此外还支持内存计算。

    Flink能很好地与其他组件配合使用。如果配合Hadoop 堆栈使用,该技术可以很好地融入整个环境,在任何时候都只占用必要的资源。该技术可轻松地与YARN、HDFS和Kafka 集成。在兼容包的帮助下,Flink还可以运行为其他处理框架,例如Hadoop和Storm编写的任务。

    目前Flink最大的局限之一在于这依然是一个非常“年幼”的项目。现实环境中该项目的大规模部署尚不如其他处理框架那么常见,对于Flink在缩放能力方面的局限目前也没有较为深入的研究。随着快速开发周期的推进和兼容包等功能的完善,当越来越多的组织开始尝试时,可能会出现越来越多的Flink部署。

    总结

    Flink提供了低延迟流处理,同时可支持传统的批处理任务。Flink也许最适合有极高流处理需求,并有少量批处理任务的组织。该技术可兼容原生Storm和Hadoop程序,可在YARN管理的集群上运行,因此可以很方便地进行评估。快速进展的开发工作使其值得被大家关注。

    展开全文
  • Flink学习之流处理架构

    千次阅读 2022-02-02 18:47:01
    ????在上一章的学习中,我们学习了...本篇博客主要讲解流处理框架与传统框架的比较,以及流处理框架的组成结构,让我们开始今日份的学习吧。 目录1. 引言2. 传统框架和流处理框架3. 消息传输层和流处理层3.1 消息传输层

    🐋在上一章的学习中,我们学习了docker安装flink环境,并搭配了一系列流处理框架的组建,在这一章我们将介绍一下流式处理框架的原理,对往期其内容感兴趣的同学可以参考如下内容👇:

    🐳本篇博客主要讲解流处理框架与传统框架的比较,以及流处理框架的组成结构,让我们开始今日份的学习吧。

    1. 引言

    数据架构设计领域正在发生一场变革,其影响不仅限于实时或近实时的项目。这场变革将基于流的数据处理流程视为整个架构设计的核心,而不是只作为某些专业化工作的基础。了解为何向流处理架构转变,可以帮助我们理解 Flink 和它在现代数据处理中所扮演的角色。
    作为新型系统,Flink 扩展了“流处理”这个概念的范围。有了它,流处理不仅指实时、低延迟的数据分析,还指各类数据应用程序。其中,有些应用程序基于流处理器实现,有些基于批处理器实现,有些甚至基于事务型数据库实现。

    2. 传统框架和流处理框架

    对于后端数据而言,传统架构是采用一个中心化的数据库系统,用于存储事务类型性数据,比如,mysql存储的业务数据,反应当前状况下的业务状态。需要新鲜数据的应用程序都依靠数据库实现。分布式文件系统则用来存储不需要经常更新的数据,它们也往往是大规模批量计算所依赖的数据存储方式。但随着时间的推移,这种传统的方式遇见如下的问题:

    • 在许多项目中,从数据到达到数据分析所需的工作流程太复杂、太缓慢。
    • 传统的数据架构太单一:数据库是唯一正确的数据源,每一个应用程序都需要通过访问数据库来获得所需的数据。
    • 采用这种架构的系统拥有非常复杂的异常问题处理方法。当出现异常问题时,很难保证系统还能很好地运行。

    除了这些,传统架构的另一个问题是,需要通过在大型分布式系统中不断地更新来维持一致的全局状态。随着系统规模扩大,维持实际数据与状态数据间的一致性变得越来越困难;流处理架构则少了对这方面的要求,只需要维持本地的数据一致性即可。

    作为一种新的选择,流处理架构解决了企业在大规模系统中遇到的诸多问题。以流为基础的架构设计让数据记录持续地从数据源流向应用程序,并在各个应用程序间持续流动。没有一个数据库来集中存储全局状态数据,取而代之的是共享且永不停止的流数据,它是唯一正确的数据源,记录了业务数据的历史。 在流处理架构中,每个应用程序都有自己的数据,这些数据采用本地数据库或分布式文件进行存储。

    3. 消息传输层和流处理层

    一个flink项目主要包含两个部分:消息传输层和流处理层
    在这里插入图片描述

    • 消息传输层从各种数据源(生产者)采集连续事件产生的数据,并传输给订阅了这些数据的应用和服务(消费者)。
    • 流处理层有 3 个用途:①持续地将数据在应用程序和系统间移动;②聚合并处理事件;③在本地维持应用程序的状态。

    在大家看来,都会把注意力放在流处理层上,这一层不止有flink还有像saprk streaming、strom等,但其实消息传输层也很关键,没有消息传递方式的改变,流处理框架也很难工作!

    3.1 消息传输层

    流处理框架下的消息传输层需要有哪些功能呢?

    1. 高性能和持久性

    消息传输层的一个作用是作为流处理层上游的安全队列——它相当于缓冲区,可以将事件数据作为短期数据保留起来,以防数据处理过程发生中断。直到最近几年,高性能和持久性不可兼得的困境才被打破。人们习惯上认为流数据从消息传输层到流处理层之后就被丢弃:用了就没了。

    为了设计新一代的流处理架构,高性能和持久性不可兼得是首先要改变的一个观念。兼具高性能和持久性对于消息传输系统来说至关重要;Kafka可以满足这个需求。

    具有持久性的好处之一是消息可以重播。这个功能使得像 Flink 这样的处理器能对事件流中的某一部分进行重播和再计算。正是由于消息传输层和流处理层相互作用,才使得像 Flink 这样的系统有了准确处理和重新处理数据的能力。

    1. 生产者和消费者解耦

    采用高效的消息传输技术,可以从多个源(生产者)收集数据,并使这些数据可供多个服务或应用程序(消费者)使用,如图 所示。Kafka 把从生产者获得的数据分配给既定的主题。数据源将数据推送给消息队列,消费者(或消费者群组)则拉取数据。事件数据只能基于给定的偏移量从消息队列中按顺序读出。生产者并不向所有消费者自动广播。这一点听起来微不足道,但是对整个架构的工作方式有着巨大的影响。
    在这里插入图片描述
    数据的生产者和消费者是解耦的。到达的消息既可以立刻被使用,也可以稍后被使用。消费者从队列中订阅消息,而不是由生产者向所有消费者广播。在消息到达的时候,消费者不必处于运行状态,而是可以根据自身需求在任何时间使用数据。这样一来,添加新的消费者和生产者也很容易。采用解耦的消息传输系统很有意义,因为它能支持微服务,也支持将处理步骤中的实现过程隐藏起来,从而允许自由地修改实现过程。

    4. 流数据在微服务架构下的应用

    微服务是软件设计中的概念,主要是指将一个大型的系统分解成一个一个具有单一目的子系统,比如:我们有一个单体架构的买卖东西的系统,初期用户不是很多,我们将买商品,进货,交易模块等放在一起,随着用户越来越多,这个系统的功能模块也在不断增加,库存管理、人员管理、售后服务等,这时我们可以考虑将这些服务一个一个拆解开,构建自己的系统,分别管理,这就是简单的微服务。

    流处理架构的核心是使各种应用程序互连在一起的消息队列。流处理器flink从消息队列中订阅数据并加以处理。处理后的数据可以流向另一个消息队列。这样一来,其他应用程序(包括其他 Flink 应用程序)都可以共享流数据。在一些情况下,处理后的数据会被存放在本地数据库中。

    在这里插入图片描述
    如图:在流处理架构中,消息队列(图中以水平圆柱体表示)连接应用程序,并作为新的共享数据源;它们取代了从前的大型集中式数据库。在本例中,Flink 被多个应用程序使用。本地化的数据能够根据微服务项目的需要被存储在文件或者数据库中。这种流处理架构的另一个好处是,流处理器Flink还可以保障数据一致性。

    5. 案例

    我们通过一个案例来了解一下:欺诈检测系统
    在这里插入图片描述

    有很多POS机通过请求欺诈检测器看看这一次刷卡是否具有欺诈行为。这些来自POS机的请求需要立即被应答。

    传统的欺诈检测器将刷卡的最后一次数据直接存储在数据库中,但这样的存储方式让其他需要数据的消费者不能轻易地使用刷卡数据,因为访问数据库可能会影响欺诈检测系统的正常工作;在没有经过认真仔细的审查之前,其他消费者绝不会被授权更改数据库。这将导致整个流程变慢,因为必须仔细执行各种检查,以避免核心的业务功能受到破坏或影响。

    与传统方法相比,如图所示的流处理架构设计将欺诈检测器的输出发送给外部的消息队列(Kafka),再由如 Flink 这样的流处理器更新数据库,而不是直接将输出发送给数据库。这使得刷卡行为的数据可以通过消息队列被其他服务使用,例如刷卡行为分析器。上一次刷卡行为的数据被存储在本地数据库中,不会被其他服务访问。这样的设计避免了因为增加新的服务而带来的过载风险。

    6. 参考资料

    《Flink的数据科学的实用指南》
    《Kafka权威指南》
    《Apache Flink 必知必会》
    《docker菜鸟教程》
    《Apache Flink 零基础入门》
    《Flink 基础教程》

    展开全文
  • 第1章 状态化流处理概述 传统数据处理 绝大多数企业所实现的传统架构都会将数据处理分为两类: 事务型处理 分析型处理 事务型处理 企业在日常业务运营过程中会用到各类应用,例如:客户管理管理软件、基于Web的...

    第1章 状态化流处理概述

    传统数据处理

    绝大多数企业所实现的传统架构都会将数据处理分为两类:

    • 事务型处理
    • 分析型处理

    事务型处理

    企业在日常业务运营过程中会用到各类应用,例如:客户管理管理软件、基于Web的应用等,这些应用系统通常都会设置独立的数据处理层(应用程序本身)和数据存储层(事务型数据库系统)。
    这些应用通常会连接外部服务或实际用户,并持续处理诸如订单、邮件、网站点击等传入的数据。期间每处理一条事件,应用都会通过执行远程数据库系统的事务来读取或者更新状态,多个应用会共享同一个数据库系统,有时候还会访问相同的数据库或表。
    在这里插入图片描述

    分析型处理

    存储于不同事务型数据库系统中的数据,可以为企业提供业务运营相关的分析见解。然而用于存储事务性数据的多个数据库系统通常都是相互隔离的,对于分析类查询,我们通常不会直接在事务型数据库上进行,而是将数据复制到一个撰文用来处理分析类查询的数据仓库为了填充数据仓库,需要将事务型数据库系统中数据拷贝过去。这个向数据仓库拷贝数据的过程被称为提取-转换-加载(Extract-Transform-Load,ETL)。
    ETL的基本流程是:

    1. 从事务型数据库中提取数据
    2. 将其转换为通用表示形式(可能包含数据验证、数据归一化、编码、去重、表模式转换等工作)
    3. 加载到数据分析数据库中
      为了保持数据仓库中的数据同步,ETL过程需要周期性的执行
      在这里插入图片描述

    状态化流处理

    几乎所有的数据都是以连续事件流的形式产生的。事实上,现实世界中很难找到那种瞬间就生成完整数据集的例子。
    任何一个处理事件流的应用,如果要支持跨多条记录的转换操作,都必须是有状态的,即能够存储和访问中间结果。应用收到事件后可以执行包括读写状态在内的任意计算。原则上,需要在应用中访问的状态有多种可选的存储位置,例如:程序变量、本地文件、嵌入式或外部数据库等。
    在这里插入图片描述

    有状态的流处理应用通常分为三类:

    1. 事件驱动型应用,通过接受事件流触发特定应用业务逻辑的有状态的流式应用,如实时推荐、异常检测等
    2. 数据管道型应用,以低延迟的方式从不同的外部系统获取、转换并插入数据,并在段时间内处理大批量数据的应用,提供多样化的数据源、数据汇连接器。Flink可以做到上述一切。
    3. 数据分析型应用,主要有周期性的批处理和持续性的流处理两类应用。

    Flink快览

    Apache Flink是一个集众多具有竞争力的特性于一身的第三代流处理引擎。它支持精确的流处理,能同事满足各种规模下对高吞吐和低延迟的要求,尤其是以下功能使其能在同类系统中脱颖而出:

    • 同时支持事件时间和处理时间语义
    • 提供精确一次的状态一致性保障
    • 在每秒处理数百万条事件的同时保持毫秒级延迟
    • 层次化的API
    • 常见的存储系统的连接器
    • 支持高可用配置
    • 允许在不丢失应用状态的前提下更新作业代码,或进行跨Flink集群的作业迁移
    • 提供详细、可定制的系统及应用指标(metrics)集合,用于提前定位和响应问题
    • Flink同时也是一个成熟的批处理引擎(批是流的特例,即有界流)

    第2章 流处理基础

    Dataflow编程概览

    Dataflow图

    Dataflow程序描述了数据如何在不同的操作之间流动。Dataflow程序通常表示为有向图。图中顶点称为算子(逻辑Dataflow图称为算子,物理Dataflow图称为任务),表示计算;而边表示数据依赖关系。算子是Dataflow程序的基本功能单元,他们从输入获取数据,对其进行计算,然后产生数据并发往输出供后续处理。没有输入端的算子成为数据源,没有输出端的算子成为数据汇。一个Dataflow图至少有一个数据源和一个数据汇。

    数据并行和任务并行

    数据并行:将输入数据分组,让同一操作的多个任务并行执行在不同数据子集上。将计算负载分配到多个节点上从而允许处理大规模的数据
    任务并行:让不同算子的任务(基于相同或不通的数据)并行计算,可以更好的利用集群的计算资源

    数据交换

    数据交换策略定义了如何将数据项分配给物理Dataflow图中的不同任务。常见有如下四种数据交换策略:

    • 转发策略:在发送端任务和接收端任务之间一对一的进行数据传输。如果两端的任务运行在同一物理机器上,可以避免网络通信
    • 广播策略:把每个数据项发往下游算子的全部任务
    • 基于键值的策略:根据魔衣键值属性对数据分区,并保证键值相同的数据项会交由同一任务处理
    • 随机策略:将数据均匀分配至算子的所有任务,以实现计算任务的负载均衡

    并行流处理

    数据流定义:一个可能无限的事件序列

    延迟和吞吐

    延迟:处理一个事件所需的时间。本质上,它是从接收事件到在输出中观察到事件处理效果的时间间隔。
    吞吐:用来衡量系统处理能力(处理速率)的指标,它告诉我们系统每单位时间可以处理多少事件。如果系统持续以力不能及的高速率接收数据,那么缓冲区可能会用尽,继而导致数据丢失,这种情形同城称为被压。
    延迟和吞吐并非相互独立的指标。如果事件在数据处理管道中传输时间太久,我们将难以保证高吞吐;同样,如果系统性能不足,事件很容易堆积缓冲,必须等待一段时间才能处理。

    数据流上的操作

    流处理引擎通常会提供一系列内置操作来实现数据流的获取、转换,以及输出。这些算子可以组合生成Dataflow处理图,从而时间流式应用所需的逻辑。常见有如下流式操作:

    数据接入和数据输出

    数据接入和数据输出操作允许流处理引擎和外部系统通信。
    数据接入操作是从外部数据源获取原始数据并将其转换成合适后续处理的格式,该类算子称为数据源。
    数据输出操作是将数据以合适外部系统使用的格式输出,该类算子称为数据汇。

    转换操作

    转换操作是一类”只过一次“的操作,它们会分别处理每个事件,对其应用某些转换并产生一条心的输出流。

    滚动聚合

    滚动聚合(如求和、求最值)会根据每个到来的事件持续更新结果。聚合操作都是有状态的,它们通过将新到来的事件合并到已有状态来生成更新后的聚合值。

    窗口操作

    有些操作必须收集并缓冲记录才能计算结果,例如流式join或像是求中位数的整体聚合。为了在无限数据流上高效的执行这些操作,必须对操作的数据加以限制。窗口操作会持续创建一些称为“桶”的有限事件合集,并允许我们基于这些有限集进行计算。
    常见有如下几种窗口类型:
    滚动窗口:将事件分配到长度固定且互不重叠的桶中。在窗口边界通过后,所有事件会发送给计算函数处理。可分为基于数量的滚动窗口和基于时间的滚动窗口。
    滑动窗口:将事件分配到大小固定且允许重叠的桶中,这意味着每个事件可能会同时属于多个桶。我们指定长度和滑动间隔连定义滑动窗口。
    会话窗口:将属于同一会话的事件分配到相同桶中。会话窗口根据会话间隔将事件分为不同的会话,该间隔值定义了会话在关闭前的非活动事件长度。

    时间语义

    处理时间

    处理时间是当前流处理算子所在机器上的本地时钟时间。

    时间事件

    事件时间是数据流中事件实际发生的时间,它以附加在数据流中事件的时间戳为依据。这些时间戳通常在事件数据进入流处理管道之前就存在。
    事件时间将处理速度和结果内容彻底解耦。基于事件时间的操作是可预测的,其结果具有确定性。无论数据流的处理速度如何、事件到达算子的顺序怎样,基于事件时间的窗口都会生成同样的结果。
    使用事件时间要克服的挑战之一是如何处理延迟事件。普遍存在的无序问题也可以借此解决。

    水位线

    水位线是一个全局进度指标,表示我们确信不会再有延迟事件到来的某个时间点。本质上,水位线提供了一个逻辑时钟,用来通知系统当前的事件时间。当一个算子收到事件为T的水位线,就可以认为不会再收到任何时间戳小于或等于T的事件了。

    状态和一致性模型

    状态在数据处理中无处不在,任何一个稍复杂的计算都要用它。不难想象,支持有状态算子将面临很多实现上的挑战:

    1. 状态管理:系统需要高效的管理状态并保证它们不受并发更新影响
    2. 状态划分:把状态按照键值划分,并独立管理每一部分
    3. 状态恢复:最后一个也是最大的挑战在于,有状态算子需要保证状态可以恢复,并且即使出现故障也要确保结果正确。

    结果保障

    结果保障指的是流处理引擎内部状态的一致性。结果保障可分为如下几种:

    • 至多一次:保证每个事件至多被处理一次,在故障时既不恢复丢失的状态,也不重放丢失的事件
    • 至少一次:所有的事件都会被处理,但有些可能会被处理多次。为了确保至少一次语义,需要从源头或者缓冲区中重放事件。
    • 精确一次:既不丢失事件,也不重复处理事件。

    第3章 Apache Flink架构

    系统架构

    Flink是一个用于状态化并行流处理的分布式系统。Flink在已有集群基础设施和服务至上专注于它的核心功能——分布式数据流处理。Flink和很多集群管理器(如Apache Mesos、YARN及Kubernets)都能很好的集成;同时它也可以通过配置,作为独立的集群来运行。Flink没有提供分布式持久化存储,而是利用了现有的分布式文件系统(如HDFS)或对象存储(如S3)。它依赖Apache Zookeeper来完成高可用性设置中的领导选举。

    搭建Flink所需组件

    • JobManager:作为主进程,JobManager控制着单个应用程序的执行。换句话说,每个应用都由一个不同的JobManager掌控。JobManager接收需要执行的应用,该应用会包含一个所谓的JobGraph,JobManager将其转化为ExecutionGraph,然后从ResourceManager申请执行任务的必要资源(处理槽),然后在将ExecutionGraph中的任务分发给TaskManager来执行。在执行的过程中JobManager还要负责所有需要集中协调的操作,如创建检查点。
    • ResourceManager:负责管理Flink的处理资源单元——TaskManager处理槽。当JobManager申请TaskManager处理槽时,ResourceManager会指示一个拥有空闲处理槽的TaskManager将其处理槽提供给JobManager。如果处理槽数无法满足JobManager的请求,ResourceManager可以和资源提供者通信,让它们提供额外容器来启动更多的TaskManager进程。同时,ResourceManager还负责终止空闲的TaskManager以释放计算资源。
    • TaskManager:工作进程。通常在Flink搭建过程中会启动多个TaskManager,每个TaskManager提供一定数量的处理槽,处理槽的数目限制了一个TaskManager可执行的任务数。
    • Dispatcher:跨多个作业运行。提供一个REST接口来让我们提交需要执行的应用。一旦某个应用提交执行,Dispatcher会启动一个JobManager并将应用转交给它。Dispatcher同时还会启动一个WebUI,用来提供有关作业执行的信息。
      在这里插入图片描述

    高可用设置

    TaskManager故障

    如果部分TaskManager故障,JobManager会向ResourceManager申请相应数量的处理槽。如果无法完成,JobManager将无法重启应用,直到有足够数量的可用处理槽。

    JobManager故障

    JobManager用于控制流式应用执行以及保存该过程中的源数据,如果JobManager进程消失,流式应用将无法继续处理数据。这就导致JobManager成为Flink应用中的一个单点失效组件。
    JobManager在高可用模式下工作时,会依赖Zookeeper完成作业管理及元数据的迁移。具体步骤如下:

    1. JobManager将JobGraph以及全部所需元数据(例如应用的JAR文件)写入一个远程持久化存储系统中
    2. 将存储位置的路径地址写入ZK
    3. JobManager故障时,新进程从ZK获取存储位置,并从远程持久化存储系统中获取相关数据,申请处理槽,重启应用并利用最近一次检查点重置任务状态

    Flink中的数据传输

    在运行过程中,应用的任务会持续进行数据交换。TaskManager负责将数据从发送任务传输至接收任务。记录并非逐个发送的,而是在缓冲区中以批次形式发送,该技术是有效利用网络资源、实现高吞吐的基础。
    发送端和接收端的任务运行在不同的TaskManager进程中时,数据交换需要利用操作系统的网络栈进行通信。在同一个TaskManager进程中时,数据会放在缓冲区和队列中,不涉及网络通信。

    基于信用值的流量控制

    通过网络连接逐条发送记录不但低效,还会导致很多额外开销。若想充分利用网络连接带宽,就要对数据进行缓冲。在流处理环境下,缓冲的一个明显缺点是会增加延迟,因为记录首先要收集到缓冲区而不会立即发送。Flink实现了一个基于信用值的流量控制机制,它的工作原理如下:接收任务会给发送任务授予一定信用值,其实就是保留一些用来接收它的数据的网络缓冲。一旦发送端收到信用通知,就会在信用值所限定的范围内尽可能多地传输缓冲数据,并会附带上积压量(已经填满准备传输的网络缓冲数目)大小。接收端使用保留的缓冲来处理收到的数据,同时依据各发送端的积压量信息来计算所有相连的发送端在下一轮的信用优先级。

    任务链接

    任务链接是Flink采用的一种用来降低某些情况下的本地通信开销的优化技术。任务链接的前提条件是,多个算子必须有相同的并行度且通过本地转发通道相连。
    在这里插入图片描述在这里插入图片描述

    事件时间处理

    时间戳

    在事件时间模式下,Flink流式应用处理的所有记录都必须包含时间戳。时间戳将记录和特定的时间点关关联,这些时间点通常是记录所对应事件的发生时间。但实际上应用可以自由的选择时间戳的含义,只要保证流记录的时间戳会随着数据流的前进大致递增即可。

    水位线

    除了记录的时间戳,Flink基于事件时间的应用还必须提供水位线。水位线用于在事件时间应用中推断每个任务当前的事件时间。基于时间的算子会使用这个时间来触发计算并推动进度前进。
    水位线本质上是一个包含时间戳信息的特殊记录。
    水位线拥有两个基本特征:

    1. 必须单调递增。这是为了确保任务中的事件时间时钟正确前进,不会倒退
    2. 和记录的时间戳存在联系。一个时间戳为T的水位线表示,接下来所有记录的时间戳一定都大于T

    状态管理

    在Flink中,状态都是和特定的算子相关联。根据作用域的不同,状态可以分为两类:算子状态和键值分区状态。

    算子状态

    算子状态的作用域是某个算子任务,这意味着所有在同一个并行任务之内的记录都能访问到相同的状态。

    键值分区状态

    键值分区状态会按照算子输入记录所定义的键值来进行维护或访问。Flink为每个键值都维护了一个状态,该状态总是位于处理对应键值记录的算子任务上。

    状态后端

    为了保证快速访问状态,每个并行任务都会把状态维护在本地。至于状态具体的存储、访问和维护,则是由一个成为状态后端的可拔插组件来决定。状态后端主要负责两件事:本地状态管理和将状态以检查点的方式写入远程持久化存储中。

    检查点、保存点及状态恢复

    一致性检查点

    Flink的故障恢复机制需要基于应用状态的一致性检查点。有状态的流式应用的一致性检查点是在所有任务处理完灯亮的原始输入后对全部任务状态进行的一个拷贝。
    在这里插入图片描述

    从一致性检查点中恢复

    应用恢复需要经过3个步骤:

    1. 重启整个应用
    2. 利用最新的检查点重置任务状态
    3. 恢复所有任务的运行

    Flink检查点算法

    • Flink 的检查点算法用到了一种称为分界线(barrier)的特殊数据形式,用来把一条流上数据按照不同的检查点分开
    • 分界线之前到来的数据导致的状态更改,都会被包含在当前分界线所属的检查点中;而基于分界线之后的数据导致的所有更改,就会被包含在之后的检查点中。

    算法操作解析 :

    1. 现在是一个有两个输入流的应用程序,用并行的两个 Source 任务来读取

    2. 两条自然数数据流,蓝色数据流已经输出完蓝3了,黄色数据流输出完黄4了

    3. 在Souce端 Source1 接收到了数据蓝3 正在往下游发向一个数据蓝2 和 蓝3; Source2 接受到了数据黄4,且往下游发送数据黄4

    4. 偶数流已经处理完黄2 所以后面显示为2, 奇数流处理完蓝1 和 黄1 黄3 所以为5 并分别往下游发送每次聚合后的结果给Sink
      在这里插入图片描述

    5. JobManager 会向每个 source 任务发送一条带有新检查点 ID 的消息,通过这种方式来启动检查点,这个带有新检查点ID的东西为barrier,图中三角型表示,2只是ID
      在这里插入图片描述

    6. 在Source端接受到barrier后,将自己此身的3 和 4 的数据,将它们的状态写入检查点,且向JobManager发送checkpoint成功的消息(状态后端在状态存入检查点之后,会返回通知给 source 任务,source 任务就会向 JobManager 确认检查点完),然后向下游分别发出一个检查点 barrier

    7. 可以看出在Source接受barrier时,数据流也在不断的处理,不会进行中断,

    8. 此时的偶数流已经处理完蓝2变成了4,但是还没处理到黄4,只是下游发送了一个次数的数据4,而奇数流已经处理完蓝3变成了8,并向下游发送了8

    9. 此时barrier都还未到奇数流和偶数流
      在这里插入图片描述

    10. 此时蓝色流的barrier先一步抵达了偶数流,黄色的barrier还未到,但是因为数据的不中断一直处理,此时的先到的蓝色的barrier会将此时的偶数流的数据4进行缓存处理,流接着处理接下来的数据等待着黄色的barrier的到来,而黄色barrier之前的数据将会对缓存的数据相加

    11. 这次处理的总结:分界线对齐,barrier 向下游传递,sum 任务会等待所有输入分区的 barrier 到达,对于barrier已经到达的分区,继续到达的数据会被缓存。而barrier尚未到达的分区,数据会被正常处理
      在这里插入图片描述

    12. 当蓝色的barrier和黄色的barrier(所有分区的)都到达后,进行状态保存到远程仓库,然后对JobManager发送消息,说自己的检查点保存完毕了

    13. 此时的偶数流和奇数流都为8

    14. 当收到所有输入分区的 barrier 时,任务就将其状态保存到状态后端的检查点中,然后将 barrier 继续向下游转发
      在这里插入图片描述

    15. 向下游转发检查点 barrier 后,任务继续正常的数据处理
      在这里插入图片描述

    16. Sink 任务向 JobManager 确认状态保存到 checkpoint 完毕

    17. 当所有任务都确认已成功将状态保存到检查点时,检查点就真正完成了
      在这里插入图片描述

    保存点

    原则上,保存点的生成算法和检查点完全一样,因此可以把保存点看做包含一些额外元数据的检查点。保存点的生成不是由Flink自动完成,而是需要由用户(外部调度器)显式触发。同时,Flink也不会自动清理保存点。

    第4章 Apache Flink开发环境

    主要介绍如何搭建一个用于开发、运行和调试Flink的应用环境。
    略~

    第5章 DataStream API

    基本流程

    1. 设置执行环境:决定应用是在本地机器还是在集群上运行
    2. 读取输入流:数据流的来源可以是消息队列或文件,也可以是实时生成的
    3. 应用转换:对输入流进行处理,应用转换,如使用keyBy()转换,将输入流按照指定信息(ID等)进行分区
    4. 输出结果:将结果发送到某些外部系统
    5. 执行:完成上述应用定义后即可执行应用。Flink程序都是通过延迟计算的方式执行。只有在调用execute()方法时,系统才会触发程序执行。
      本章主要介绍Flink DataStream API的基础知识,具体用法可参见配套示例

    第6章 基于时间和窗口的算子

    时间特性分类

    处理时间ProcessingTime

    指定算子根据处理机器的系统时钟决定数据流当时的时间。处理时间窗口基于机器时间触发,通常情况下会导致不确定的结果发生,这是因为窗口内容取决于元素到达的速率。在该配置下,由于无需依赖水位线来驱动事件时间的前进,可以提供极低的延迟。

    事件时间EventTime

    指定算子根据数据自身包含的信息决定当前时间。每个事件时间都带有时间戳,而系统的逻辑时间是由水位线来定义。在该配置下,即使事件乱序到达,事件时间窗口也会计算出确定的结果。窗口结果不会取决于数据流的读取或者处理速度。

    摄入时间IngestionTime

    指定每个接受的记录都把在数据源算子的处理时间作为事件时间的时间戳,并自动生成水位线。摄入时间是处理时间和事件时间的混合体,它表示事件进入流处理引擎的时间。

    本章主要介绍Flink DataStream API用于处理时间的方法和基于时间的算子,具体用法可参见配套示例

    第7章 有状态算子和应用

    本章主要介绍如何实现有状态的用户自定义函数,如如何实现带有键值分区状态及算子状态的函数。
    略~

    第8章 读写外部系统

    应用的一致性保障

    Flink的检查点和恢复机制会周期性的为应用黄台创建一致性检查点。一旦发生故障,应用会从最近一次完成的检查点中恢复状态并继续处理数据。虽然如此,但像这样把应用状态重置到某个一致性检查点所提供的应用处理保障还无法令人满意。我们需要应用的数据源和数据汇连接器能和Flink的检查点及恢复策略集成,并提供某些特定的属性以及支持各类有意义的保障。

    为了在应用中实现精确一次的的状态一致性保障,应用的每个数据源连接器都需要支持将数据读取位置重置为某个已有检查点中的值。如果应用使用的数据源连接器无法存储和重置读取位置,那么在它出现故障时就可能要丢失部分数据,从而只能提供最多一次的保障。

    Flink的检查点和恢复机制结合可重置的数据源连接器能够确保应用不会丢失数据。但由于在前一次成功的检查点后发出的数据会被再次发送,所以应用可能会发出两次结果。因此,可重置的数据源以及Flink的恢复机制虽然可以为应用状态提供精确一次的一致性保障,但无法提供端到端的精确一次保障。

    应用若现提供端到端的精确一次保障,需要一些特殊的数据汇连接器。根据情况的不通个,这些连接器可以使用两张技术来实现精确一次保障:幂等性写和事务型写。

    幂等性写

    幂等操作可以多次执行,但只会引起一次改变。幂等性写操作对于流式应用而言具有重要意义,因为它们可以在不改变结果的前提下多次执行。因此,幂等性写操作可以再一定程度上减轻Flink检查点机制所带来的重复结果的影响。

    事务性写

    实现端到端精确一次一致性的第二个途径是事务性写。它的基本思路是只有在上次成功的检查点之前计算的结果才会被写入外部数据汇系统。该行为可以提供端到端的精确一次保障。因为在发生故障后,应用会被重置到上一个检查点,而接受系统不会收到任何在该检查点之后生成的结果。

    事务性写不会出现重放过程中的不一致现象,但会增加一定延迟,因为结果只有在检查点完成之后才对外可见。

    Flink提供了两个构建来实现事务性的数据汇链接器:一个通用的WAL数据汇和一个2PC数据汇。

    WAL数据汇会将所有结果记录写入应用状态,并在收到检查点完成通知后将他们发送到数据汇系统。由于该数据会利用状态后端缓冲记录,所以它使用于任何数据汇系统。然而,事务性写会导致应用状态大小增加以及接收系统需要处理一次次的波峰式写入。

    与WAL不同的是,2PC数据汇需要数据汇系统提供事务支持,或者提供模拟事务的支持。对于每个检查点,数据汇首先启动一个事务,将所有接收到的记录添加到事务中,并将它们写入数据汇系统,但是不提交。当它收到一个“检查点完成”的通知后,它提交事务,并将结果落盘。

    2PC协议集成在Flink的检查点机制中。检查点分隔符便是启动一个新事务的通知,所有算子中对于它“自身检查点完成”的通知,即是它们的提交投票。JobManager的对于“整个检查点完成”的消息,即为提交事务的指示。

    相对于WAL数据汇,2PC数据汇是基于数据汇系统以及数据汇的实现方式,达到精确一次的输出保障。而相对于WAL数据汇的突增写入模式,2PC数据汇为持续向sink 系统写入记录。

    不同数据源和数据汇组合所能实现的端到端的一致性保障:

    不可重置数据源可重置数据源
    任意数据汇至多一次至少一次
    幂等性数据汇至多一次精确一次(故障恢复过程中会有临时性不一致)
    WAL数据汇至多一次至少一次
    2PC数据汇至多一次精确一次

    内置连接器

    Flink为很多外部存储系统都提供了相应的数据读写连接器。消息队列是一类常见的数据流消息来源。在以批处理为主的环境中,我们还经常通过监视文件系统目录并读取其中新增文件的方式来获取数据流。

    在数据汇一段,数据流中的事件经常会写入消息队列中,以支撑后续流式应用;或者是写入文件系统,实现归档或支撑后续离线分析及批处理应用;也可以插入到键值存储或数据库系统中,以供查询、搜索或仪表盘应用使用。

    Flink为Apache Kafka、Kinesis、RabbitMQ、Apache Cassandra、ElasticSearch、多种文件系统以及JDBC等都提供了相应的连接器。
    除了内置的连接器,Flink也支持自定义数据源和数据汇链接器。

    • 实现SourceFunction接口和RichSourceFunction抽象类可以自定义非并行的数据源连接器,即只能以单任务云心
    • 实现ParallelSourceFunction接口和RichParallelSourceFunction抽象类可用于定义能够同时运行多个任务实例的数据源连接器
    • 实现SinkFunction接口和RichSinkFunction抽象类可用于定义数据汇连接器。

    异步访问外部系统

    除了淡出的手法数据之外,我们还经常需要利用从远程数据库获取的信息来丰富数据流,此时也会涉及和外部存储系统的交互。

    Flink提供的AsyncFunction可以有效降低I/O调用所带来的延迟。该函数能够同时发出多个查询并对其结果进行异步处理。它可以通过配置选择对记录进行保存,也可以为了追求更低的延迟按照请求结果的返回顺序处理记录。

    为了充分利用AsyncFunction,外部系统最好能够提供一个支持异步调用的客户端,很多现有系统都可以做到这点。而如果外部系统只提供了同步客户端,你可以通过多线程的方式来发送请求并对其进行处理。

    第9章 搭建Flink运行流式应用

    本章主要介绍Flink集群的多种部署方式以及如何对它进行安全和高可用配置。可参见搭建Flink运行流式应用。略~

    第10章 Flink和流式应用运维

    运行并管理流式应用

    保存点

    保存点和检查点的本质相同,二者都是应用状态的一致性完整快照。但他们的声明周期有所差异。检查点会自动创建,在发生故障时自动加载并由Flink自动删除(取决于应用具体配置)。此外,除非应用显式指定要保留检查点,否则它们会在应用取消时自动删除。而保存点则与之相反,它们需要由用户或外部服务手动触发,且永远不会被Flink自动删除。

    每个保存点都对应一个持久化数据存储上的目录。它由一个包含了所有任务状态数据文件的子目录和一个包含了全部数据文件绝对路径的二进制元数据文件组成。

    通过命令行客户端管理应用

    Flink命令行客户端提供了启动、停止和管理Flink应用的功能。它会从./conf/flink-conf.ymal文件中读取配置。

    通过REST API管理应用

    REST API可供用户或脚本直接访问,它可以对外公开有关Flink集群和应用的信息,包括指标数据及用于提交和控制应用程序的服务端点等。Flink使用一个Web服务器来同事支持REST API和Web UI,该服务会作为Dispatcher进程的一部分来运行。

    控制任务进度

    为了实现并行执行,Flink应用会将算子划分为不同的任务,并将这些任务分配到集群中的不同工作进程上。任务分配的目标工作进程,任务的共存情况以及工作进程中的任务数都会对应用性能产生显著影响。

    控制任务链接

    任务链接指的是将两个或多个算子的并行任务融合在一起,从而可以从它们在同一线程中执行。融合的任务只需通过方法调用就可以进行记录交换,因此几乎没有通信成本。由于任务链接可以提高大多数应用的性能,所以Flink默认会启用它。

    然而,也有特定的应用可能无法从中受益。其中一种情况是我们希望将一连串负载较重的函数拆开,让它们在不通的处理槽内执行。Flink支持禁用应用内的任务链接,也可以控制单个算子的链接行为。

    定义处理共享槽

    Flink默认任务调度策略会将一个完整的程序分片分配到一个处理槽中。根据应用的复杂度以及算子的计算成本,Flink提供了处理槽共享组机制,允许用户手动将任务分配到处理槽中。

    调整检查点及恢复

    在启用容错功能的情况下,Flink会周期性的将应用状态存储到检查点中。由于在生成检查点时可能需要将大量数据写入持久化存储中,所以其代价可能非常昂贵。增大检查点的生成间隔可以降低常规处理过程中的容错开销,但它同时会使作业在故障恢复过程中需要重新处理更多的数据。

    配置检查点

    Flink提供了一系列用于调整检查点和状态后端的参数。包括但不限于:指定生成间隔、启用检查点压缩、应用停止后保留检查点等。

    配置状态后端

    应用状态后端负责维护本地状态,生成检查点和保存点以及在故障时恢复应用状态。因此,应用状态后端的选择和配置对检查点相关操作的性能有很大影响。

    Flink默认状态后端是MemorStateBackend。由于它将所有状态保存在内存中,而且检查点全部位于易失且受JVM大小约束的JobManager堆存储内,所以不建议将其用于生产环境。

    Flink还支持配置FsStateBackend和RocksDBStateBackend状态后端。

    配置故障恢复

    当一个拥有检查点的应用发生故障时,它会经过一系列步骤重启,具体包括启动任务、恢复状态(包括数据源任务的读取偏移)和继续处理。为了能够赶得上数据流的进度,应用处理积累数据的速率必须要高于新数据到来的速率。它在追赶进度期间的处理延迟会有所增加。因此,从重启到成功恢复常规处理的进度追赶期间,应用需要足够多的备用资源。

    恢复过程除了资源因素,还有两个两个值得关注的主题:重启策略和本地恢复。

    重启策略

    Flink提供了三种重启策略:

    • fixed-delay:已配置的固定时间间隔重试将应用重启某个固定的次数
    • failture-rate:允许在未超过故障率的前提下不断重启应用。故障率的定义为某个时间间隔内的最大故障次数
    • no-restart:不重启应用,直接失败

    本地恢复

    Flink支持一种称为本地恢复的特性,能够在应用从相同机器重启时显著提高恢复速度。在启用该功能后状态后端除了将数据写入远程存储系统外,还会将检查点数据在工作进程所在的节点的本地磁盘复制一份。当应用需要重启时,Flink会尝试将相同的任务调度到和之前相同的工作节点执行。如果成功,则任务会优先尝试从本地磁盘加载检查点数据。如果出现任何问题,则将退回到使用远程存储进行处理。

    监控Flink集群和应用

    Flink Web UI

    Flink提供的了解集群和内部作业情况概要最为简单的方式。可以通过http://<jobmanager-hostname>:8081地址来访问它。

    详细分析可参见Flink Web UI分析

    指标系统

    Flink在默认情况下会收集很多系统和应用指标。指标的手机是按照每个算子、每个TaskManager或JobManager来进行的。

    配置日志行为

    日志是调试和理解应用行为的另一个重要工具。默认情况下,Flink使用SLF4J日志抽象和log4j日志框架。要修改log4j记录器的属性,可以通过修改conf/目录中的log4j.properties文件来实现。

    第11章还有什么?

    Flink生态的其他组成部分

    用于批处理的DataSet API

    Flink可用于实现有界数据的一次性或定期查询。DataSet程序和DataStream程序一样,都是有一系列转换操作组成。二者的不同在于前者是一个有界数据集。

    用于关系型分析的Table API及SQL

    虽然Flink底层DataStream和DataSet的API是分开的,但你可以使用高层次的关系型API——Table API和SQL,实现流批一体的分析。

    用于复杂事件处理和模式匹配的FlinkCEP

    FlinkCEP是一个用于复杂事件模式检测的高层次API库。它基于DataStream API实现,允许你指定期望在数据流中检测到的模式。常见的CEP应用场景包括金融应用,欺诈检测,复杂系统中的监控和报警,以及检测网络入侵。

    用于图计算的Gelly

    Gelly是Flink的图计算API库。它建立在DataSet API和Flink的高效批量迭代之上。它包含了一组常见的图算法,方便日常使用。

    展开全文
  • 什么是流处理

    千次阅读 2020-07-07 08:34:24
    流处理正变得像数据处理一样流行。流处理已经超出了其原来的实时数据处理的范畴,它正在成为一种提供数据处理(包括批处理),实时应用乃至分布式事务的新方法的技术。1、什么是流处理流处理是不断...
  • 流处理和批处理框架的异同

    千次阅读 2019-01-23 19:00:00
    实现流处理系统有两种完全不同的方式:一种是称作原生流处理,意味着所有输入的记录一旦到达即会一个接着一个进行处理。  第二种称为微批处理。把输入的数据按照某种预先定义的时间间隔(典型的是几秒钟)...
  • Flink流处理过程的部分原理分析

    万次阅读 2018-12-19 23:20:07
    文章目录前言 前言 ...笔者做为一个研究存储模块出身的人,最近在研读Flink流处理的部分原理,小小作番总结。很多时候,以存储的眼光来看待计算过程中的处理过程,还是有很多不一样的地方的。 ...
  • 大数据篇:如何区分流处理和批处理 今天我们来讲讲大数据的处理模式:批处理(Batching Processing)和流处理(Streaming Processing)。 这几年大规模的物联网(IoT)数据监控系统和视频流系统等的大数据系统出现,...
  • Kafka基础-流处理

    千次阅读 2018-10-26 17:10:20
    1. 什么是流处理? 首先,让我们说一下什么是数据流(也称为事件流)?它是无边界数据集的抽象说法,无边界意味着无限且不断增长,因为随着时间的推移,新数据会不断地到来。 除了无边界的特性之外,事件流模型...
  • 什么是数据实时处理? • 数据从生成->实时采集->实时缓存存储->实时计算->实时落地->实时展示->实时分析。这一个流程线下来,处理数据的速度在秒级甚至毫秒级。 • 某电子商务网站双十一大屏,...
  • 大数据之实时流处理常用框架

    万次阅读 2018-05-07 10:53:59
    实时流处理简单概述:实时是说整个流处理相应时间较短,流式技算是说数据是源源不断的,没有尽头的。实时流处理一般是将业务系统产生的数据进行实时收集,交由流处理框架进行数据清洗,统计,入库,并可以通过可视化...
  • 静态数据 很多企业为了支持决策分析而构建的数据仓库...近年来,在Web应用、网络监控、传感监测等领域,兴起了一种新的数据密集型应用——数据,即数据以大量、快速、时变的形式持续到达。实例:PM2.5检测、电子...
  • 基于apache flink 流处理 pdf 下载

    千次阅读 2021-09-15 14:47:02
    链接:百度网盘 请输入提取码 密码:vcni
  • [Flink基础]--什么是流处理

    千次阅读 2018-09-29 12:56:46
    什么是流处理? Data Artisans由ApacheFlink®的原始创建者创建,我们花了很长时间来解决流处理领域的问题。在这篇介绍性文章中,我们将提供有关流处理和Apache Flink适合的视角。要了解更多信息,您可以下载有关...
  • 如何区分批处理和流处理

    千次阅读 2019-05-12 22:43:58
    数据可以抽象成两种类型:无边界数据 和 有边界数据 无边界数据,是一种不断增长可以说是无限的数据...在处理大数据时,通常还关心时域问题:事件时间 和 处理时间 事件时间,数据实际产生的时间 处理时间,处理数据...
  • 流处理基本介绍

    万次阅读 多人点赞 2017-01-23 10:14:56
    1. 什么是流处理 一种被设计来处理无穷数据集的数据处理系统引擎 2. 流处理的几个概念 1. 无穷数据(Unbounded data):一种持续生成,本质上是无穷尽的数据集。它经常会被称为“流数据”。然而,用流和批次来...
  • flink的批处理和流处理

    千次阅读 2019-04-17 10:40:28
    1.流处理系统 2.批处理系统 3.flink的流处理和批处理 4.flink的流处理和批处理代码的区别 流处理系统与批处理系统最大不同在于节点间的数据传输方式 1.流处理系统 流处理系统,其节点间数据传输的标准模型...
  • Stream流处理分隔字符串

    千次阅读 2021-03-23 17:26:45
    Stream 流处理字符串—分隔字符串 逗号分割字符串至list String string = "a,b,c"; System.out.println("--------字符串以“,”切分(流处理)---------"); List<String> collect = Stream.of(string.split(...
  • 首先看看 【java】高并发之限 RateLimiter使用 这个去看看限怎么使用。 然后看看扩展的kafka是如何限的,95-10-040-启动-限额管理。 然后下面是FLink如何做限的。 2.案例 2.1 案例1 public void ...
  • 写在前面 本文隶属于专栏《100个问题搞定大数据理论体系》,该专栏为笔者... 流处理 数据的流处理可以理解为系统需要接收并处理一系列连续不断变化的数据。例如,旅行预订系统,处理社交媒体更新信息的有关系统等等。
  • 以新的数据仓库平台为基础,结合行内的通用文件传输平台、统一调度平台,规范了源数据系统的数据报送,梳理构建了新的数据模型,大数据平台解决了传统数仓在批量数据处理能力的不足,在相关任务上体验到了从数小时到...
  • Stream流处理list分组方法

    万次阅读 2019-05-25 17:36:06
    工作中经常碰到list去重的问题,现在我简单分享一下我的处理方式。 @Data @Accessors(chain = true) @NoArgsConstructor @AllArgsConstructor class Student { /** * 姓名 */ private String name; /** * ...
  • 基础 Flink系列:无界和有界数据流定义与区别 批处理 适合有边界数据 使用DataSet 流处理 适合无边界数据 使用DataStream
  • java 8 流处理字符串

    千次阅读 2018-09-24 12:11:21
    java 8 流处理字符串 java 8 引入新的Stream api,方便我们使用声明方式处理数据。本文我们将说明如何使用Stream api分割逗号分割字符串至list,以及如何连接字符串数组至逗号分割字符串,也会介绍如何使用Stream api...
  • stream流处理List对象集合去重

    千次阅读 2020-07-02 14:58:08
    stream流处理List对象集合去重 public class TestStream { //创建一个list对象包含student对象 根据id去重 private static List<Student> list = new ArrayList<>(); static { Student s1 = new ...
  • 1.Flink是一个针对数据和批数据的分布式处理引擎,主要用Java代码实现。 2.Apache Flink作为Apache的顶级项目,Flink集众多优点于一身,包括快速、可靠可扩展、完全兼容Hadoop、使用简便、表现卓越。 通过以上的...
  • java8 流处理字符串---分隔字符串

    万次阅读 2019-03-12 16:46:44
    java 8 引入新的Stream api,方便我们使用声明方式处理数据。本文我们将说明如何使用Stream api分割逗号分割字符串至list,以及如何连接字符串数组、list至逗号分割字符串; 下面大体写了下实验代码,有点简单,但是...
  • 实时处理与流处理

    万次阅读 2014-11-15 09:52:28
    前言:作为一个程序员,总是能不时地听到各种新技术名词,大数据、云计算、实时处理、流式处理、内存计算… 但当我们听到这些时髦的名词时他们到底是在说什么?偶然搜到一个不错的帖子,就总结一下实时处理和流式...
  • 本文翻译自DataBricks官方博客,主要描述了Apache Spark 2.0中推出的新功能Structured Streaming(结构化流处理)从Kafka中读取消息,实时处理后再写入不同的下游系统的使用示例。 结构化流处理API使得以一种兼具一.....
  • Kettle与Kafka流处理的整合

    千次阅读 2020-10-26 10:40:43
    Kettle与Kafka流处理的整合一. 环境准备二. Kettle中连接Kafka2.1 生产者介绍2.2 消费者介绍三. 测试结果 一. 环境准备 在虚拟机的Docker中搭建Kafka单机测试环境。 docker pull wurstmeister/zookeeper docker pull...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,715,269
精华内容 686,107
关键字:

流处理