geekyouth / geekyouth.github.io

👣极客青年博客😘,基于github pages+issues + VUE 2.0 框架构建的轻量级静态博客系统💎[速度慢请翻墙]
https://java666.cn
39 stars 6 forks source link

Hadoop、Storm、Samza、Spark 和 Flink 大数据框架分析 #18

Closed geekyouth closed 2 years ago

geekyouth commented 4 years ago

本文由 简悦 SimpRead 转码, 原文地址 https://zh.twgreatdaily.com/nZt-Hm0BJleJMoPMB_cX.html

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

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

下文将介绍这些框架:

大数据处理框架是什么?

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

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

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

Apache Storm

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

流处理模式

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

拓扑包含:

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

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

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

Trident 拓扑包含:

优势和局限

目前来说 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 在处理数据时涉及下列概念:

由于 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 可配合使用的基本组件包括:

为了在计算过程中遇到问题后能够恢复,流处理任务会在预定时间点创建快照。为了实现状态存储,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 提供了真正的流处理并具备批处理能力,通过深度优化可运行针对其他平台编写的任务,提供低延迟的处理,但实际应用方面还为时过早。

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