Hadoop、Storm、Samza、Spark和Flink:大数据框架比较
介绍
大数据 是对从大型数据集中收集、组织、处理和收集见解所需的非传统策略和技术的总称。 虽然处理超过单台计算机的计算能力或存储的数据的问题并不新鲜,但近年来这种计算的普遍性、规模和价值已经大大扩展。
在之前的指南中,我们讨论了一些 大数据系统中使用的一般概念、处理阶段和术语 。 在本文中,我们将了解大数据系统中最重要的组件之一:处理框架。 处理框架通过从非易失性存储中读取数据或将其引入系统来计算系统中的数据。 数据计算是从大量单个数据点中提取信息和洞察力的过程。
我们将介绍以下框架:
什么是大数据处理框架?
处理框架和处理引擎负责对数据系统中的数据进行计算。 虽然没有将“引擎”与“框架”区分开来的权威定义,但有时将前者定义为负责对数据进行操作的实际组件,而将后者定义为一组旨在执行相同操作的组件。
例如,Apache Hadoop可以被认为是一个处理框架,MapReduce作为其默认的处理引擎。 引擎和框架通常可以互换或串联使用。 例如,另一个框架 Apache Spark 可以挂接到 Hadoop 以取代 MapReduce。 组件之间的这种互操作性是大数据系统具有极大灵活性的原因之一。
虽然处理数据生命周期这一阶段的系统可能很复杂,但广义上的目标非常相似:对数据进行操作以增加理解、表面模式并深入了解复杂的交互。
为了简化对这些组件的讨论,我们将按照设计处理的数据状态对这些处理框架进行分组。 一些系统分批处理数据,而另一些系统在数据流入系统时以连续流的形式处理数据。 还有一些人可以通过这两种方式中的任何一种来处理数据。
在深入探讨各种实现的细节和后果之前,我们将介绍每种类型的处理作为一个概念。
批处理系统
批处理在大数据领域有着悠久的历史。 批处理涉及对大型静态数据集进行操作,并在计算完成后返回结果。
批处理中的数据集通常是……
- 有界的:批处理数据集表示有限的数据集合
- 持久性:数据几乎总是由某种类型的永久存储支持
- large:批处理操作通常是处理超大数据集的唯一选择
批处理非常适合需要访问完整记录集的计算。 例如,在计算总数和平均值时,必须从整体上处理数据集,而不是作为单个记录的集合。 这些操作要求在计算期间保持该状态。
需要大量数据的任务通常最好通过批处理操作来处理。 无论数据集是直接从永久存储中处理还是加载到内存中,批处理系统都是在构建时考虑到大量数据并拥有处理它们的资源。 因为批处理擅长处理大量持久数据,所以它经常与历史数据一起使用。
处理大量数据的代价是计算时间更长。 因此,批处理不适合处理时间特别重要的情况。
阿帕奇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)
- 将中间结果重新分配到按键分组
- 通过汇总和组合各个节点计算的结果来“减少”每个键的值
- 将计算的最终结果写回 HDFS
优点和局限性
因为这种方法大量利用了永久存储,每个任务多次读写,所以它往往相当慢。 另一方面,由于磁盘空间通常是最丰富的服务器资源之一,这意味着 MapReduce 可以处理海量数据集。 这也意味着 Hadoop 的 MapReduce 通常可以在比某些替代方案更便宜的硬件上运行,因为它不会尝试将所有内容都存储在内存中。 MapReduce 具有令人难以置信的可扩展性潜力,并已在数万个节点上用于生产。
作为开发目标,MapReduce 以具有相当陡峭的学习曲线而闻名。 Hadoop 生态系统的其他添加可以在不同程度上减少这种影响,但它仍然可以成为在 Hadoop 集群上快速实施想法的一个因素。
Hadoop 拥有广泛的生态系统,Hadoop 集群本身经常用作其他软件的构建块。 许多其他处理框架和引擎具有 Hadoop 集成以利用 HDFS 和 YARN 资源管理器。
概括
Apache Hadoop 及其 MapReduce 处理引擎提供了一个经过良好测试的批处理模型,最适合处理时间不是重要因素的非常大的数据集。 运行良好的 Hadoop 集群所需的低成本组件使得这种处理对许多用例来说既便宜又有效。 与其他框架和引擎的兼容性和集成意味着 Hadoop 通常可以作为使用不同技术的多个处理工作负载的基础。
流处理系统
流处理系统在数据进入系统时对其进行计算。 这需要与批处理范例不同的处理模型。 流处理器不是定义应用于整个数据集的操作,而是定义将在每个单独的数据项通过系统时应用于它的操作。
流处理中的数据集被认为是“无界的”。 这有几个重要的含义:
- total 数据集仅定义为到目前为止已进入系统的数据量。
- working 数据集可能更相关,并且一次仅限于一个项目。
- 处理是基于事件的,在明确停止之前不会“结束”。 结果立即可用,并将随着新数据的到来而不断更新。
流处理系统可以处理几乎无限量的数据,但它们一次只处理一个(真正的流处理)或很少的(微批处理)项目,在记录之间保持最少的状态。 虽然大多数系统都提供了保持某些状态的方法,但蒸汽处理针对更多 功能处理 进行了高度优化,并且几乎没有副作用。
功能操作专注于具有有限状态或副作用的离散步骤。 对同一条数据执行相同的操作将产生与其他因素无关的相同输出。 这种处理非常适合流,因为项目之间的状态通常是困难的、有限的、有时是不受欢迎的组合。 因此,虽然某些类型的状态管理通常是可能的,但这些框架在没有它们的情况下更加简单和高效。
这种类型的处理适用于某些类型的工作负载。 流模型很好地满足了具有近实时要求的处理。 分析、服务器或应用程序错误日志记录以及其他基于时间的指标非常适合,因为对这些领域的变化做出反应对业务功能至关重要。 流处理非常适合您必须响应变化或峰值以及您对随时间变化的趋势感兴趣的数据。
阿帕奇风暴
Apache Storm 是一个专注于极低延迟的流处理框架,对于需要近乎实时处理的工作负载来说,它可能是最佳选择。 与其他解决方案相比,它可以处理大量数据并以更少的延迟交付结果。
流处理模型
风暴流处理通过在称为 拓扑 的框架中编排 DAG(有向无环图)来工作。 这些拓扑描述了当每个传入数据进入系统时将对其进行的各种转换或步骤。
拓扑结构包括:
- Streams:常规数据流。 这是不断到达系统的无限数据。
- Spouts:拓扑边缘的数据流来源。 这些可以是 API、队列等。 产生要操作的数据。
- Bolts:Bolts 表示一个处理步骤,它消耗流,对其应用操作,并将结果作为流输出。 螺栓连接到每个喷口,然后相互连接以安排所有必要的处理。 在拓扑结束时,最终螺栓输出可用作连接系统的输入。
Storm 背后的想法是使用上述组件定义小的离散操作,然后将它们组合成拓扑。 默认情况下,Storm 提供 at-least-once 处理保证,这意味着它可以保证每条消息至少被处理一次,但在某些失败场景中可能存在重复。 Storm 不保证消息会按顺序处理。
为了实现精确一次的有状态处理,还可以使用一个称为 Trident 的抽象。 明确地说,没有 Trident 的 Storm 通常被称为 Core Storm。 Trident 显着改变了 Storm 的处理动态,增加了延迟,为处理添加了状态,并实现了微批处理模型而不是逐项的纯流系统。
Storm 用户通常建议尽可能使用 Core Storm 来避免这些惩罚。 考虑到这一点,在系统无法智能地处理重复消息的情况下,Trident 保证只处理一次项目很有用。 当您需要维护项目之间的状态时,Trident 也是 Storm 中的唯一选择,例如在计算一小时内有多少用户点击链接时。 Trident 为 Storm 提供了灵活性,尽管它没有发挥框架的天然优势。
三叉戟拓扑由以下部分组成:
- 流批处理:这些是流数据的微批处理,它们被分块以提供批处理语义。
- Operations:这些是可以对数据执行的批处理过程。
优点和局限性
Storm 可能是目前可用于近实时处理的最佳解决方案。 对于必须以最小延迟处理的工作负载,它能够以极低的延迟处理数据。 当处理时间直接影响用户体验时,Storm 通常是一个不错的选择,例如,当处理的反馈直接反馈到网站上的访问者页面时。
Storm with Trident 让您可以选择使用微批处理而不是纯流处理。 虽然这为用户提供了更大的灵活性来将工具塑造成预期用途,但它也倾向于否定该软件相对于其他解决方案的一些最大优势。 话虽如此,选择流处理风格仍然很有帮助。
Core Storm 不提供消息的排序保证。 Core Storm 提供至少一次处理保证,这意味着可以保证每条消息的处理,但可能会发生重复。 Trident 提供一次性保证,并且可以提供批次之间的订购,但不能在批次内订购。
在互操作性方面,Storm 可以与 Hadoop 的 YARN 资源协商器集成,从而轻松连接到现有的 Hadoop 部署。 与大多数处理框架相比,Storm 具有非常广泛的语言支持,为用户提供了许多定义拓扑的选项。
概括
对于延迟要求非常严格的纯流处理工作负载,Storm 可能是最好的成熟选择。 它可以保证消息处理,并且可以与大量的编程语言一起使用。 因为 Storm 不做批处理,如果你需要这些功能,你将不得不使用额外的软件。 如果您强烈需要一次性处理保证,Trident 可以提供。 但是,此时其他流处理框架也可能更适合。
阿帕奇萨姆扎
Apache Samza 是一个流处理框架,与 Apache Kafka 消息系统紧密相关。 虽然 Kafka 可以被许多流处理系统使用,但 Samza 是专门为利用 Kafka 独特的架构和保证而设计的。 它使用 Kafka 来提供容错、缓冲和状态存储。
Samza 使用 YARN 进行资源协商。 这意味着默认情况下需要 Hadoop 集群(至少 HDFS 和 YARN),但这也意味着 Samza 可以依赖 YARN 内置的丰富功能。
流处理模型
Samza 依靠 Kafka 的语义来定义处理流的方式。 Kafka 在处理数据时使用以下概念:
- Topics:每个进入Kafka系统的数据流称为一个主题。 主题基本上是消费者可以订阅的相关信息流。
- Partitions:为了在节点之间分配主题,Kafka 将传入的消息划分为分区。 分区划分是基于一个键的,这样具有相同键的每条消息都可以保证发送到同一个分区。 分区有保证的顺序。
- Brokers:组成Kafka集群的各个节点称为brokers。
- Producer:任何写入Kafka主题的组件都称为生产者。 生产者提供用于划分主题的密钥。
- Consumers:消费者是从 Kafka 主题读取的任何组件。 消费者负责维护有关他们自己的偏移量的信息,以便在发生故障时知道哪些记录已被处理。
因为 Kafka 代表不可变日志,所以 Samza 处理不可变流。 这意味着任何转换都会创建由其他组件使用的新流,而不会影响初始流。
优点和局限性
乍一看,Samza 对类似 Kafka 的排队系统的依赖似乎具有限制性。 但是,它为系统提供了一些其他流处理系统中不常见的独特保证和功能。
例如,Kafka 已经提供了可以以低延迟访问的数据的复制存储。 它还为每个单独的数据分区提供了一个非常简单且廉价的多订阅者模型。 所有输出,包括中间结果,也被写入 Kafka,并且可以被下游阶段独立使用。
在许多方面,这种对 Kafka 的紧密依赖反映了 MapReduce 引擎经常引用 HDFS 的方式。 虽然在每次计算之间引用 HDFS 会导致批处理时出现一些严重的性能问题,但它解决了流处理时的许多问题。
Samza 与 Kafka 的密切关系允许处理步骤本身非常松散地捆绑在一起。 可以将任意数量的订阅者添加到任何步骤的输出中,而无需事先协调。 这对于多个团队可能需要访问类似数据的组织非常有用。 团队都可以订阅数据进入系统的主题,也可以轻松订阅其他团队创建的经过一些处理的主题。 这可以在不对负载敏感的基础架构(如数据库)增加额外压力的情况下完成。
直接写入 Kafka 也消除了 背压 的问题。 背压是指负载峰值导致数据流入的速度超过组件实时处理的速度,从而导致处理停滞和潜在的数据丢失。 Kafka 旨在长时间保存数据,这意味着组件可以在方便时进行处理,并且可以在没有任何后果的情况下重新启动。
Samza 能够使用作为本地键值存储实现的容错检查点系统来存储状态。 这允许 Samza 提供至少一次交付保证,但它不提供在发生故障时准确恢复聚合状态(如计数),因为数据可能会多次交付。
Samza 提供了高级抽象,在许多方面比 Storm 等系统提供的原语更易于使用。 Samza 目前只支持 JVM 语言,这意味着它没有 Storm 一样的语言灵活性。
概括
对于 Hadoop 和 Kafka 已经可用或可以实施的流式工作负载,Apache Samza 是一个不错的选择。 Samza 本身非常适合在不同处理阶段使用(但不一定紧密协调)数据流的多个团队的组织。 Samza 极大地简化了流处理的许多部分并提供低延迟性能。 如果部署要求与您当前的系统不兼容,如果您需要极低的延迟处理,或者如果您对一次性语义有强烈的需求,那么它可能不适合。
混合处理系统:批处理和流处理器
一些处理框架可以同时处理批处理和流式工作负载。 这些框架允许将相同或相关的组件和 API 用于两种类型的数据,从而简化了各种处理要求。
正如您将看到的,在我们将讨论的两个框架 Spark 和 Flink 之间,实现这一点的方式有很大的不同。 这在很大程度上取决于两种处理范式如何结合在一起,以及对固定数据集和非固定数据集之间的关系做出了哪些假设。
虽然专注于一种处理类型的项目可能非常适合特定用例,但混合框架试图为数据处理提供通用解决方案。 它们不仅提供处理数据的方法,还拥有自己的集成、库和工具,用于执行图形分析、机器学习和交互式查询等操作。
阿帕奇星火
Apache Spark 是具有流处理能力的下一代批处理框架。 Spark 使用 Hadoop 的 MapReduce 引擎的许多相同原理构建,主要侧重于通过提供完整的内存计算和处理优化来加速批处理工作负载。
Spark 可以部署为独立集群(如果与功能强大的存储层配对),也可以连接到 Hadoop 作为 MapReduce 引擎的替代方案。
批处理模型
与 MapReduce 不同,Spark 在内存中处理所有数据,仅与存储层交互以将数据初始加载到内存中,最后将最终结果持久化。 所有中间结果都在内存中管理。
虽然内存处理对速度有很大贡献,但 Spark 在与磁盘相关的任务上也更快,因为可以通过提前分析完整的任务集来实现整体优化。 它通过创建有向无环图或 DAGs 来实现这一点,它表示必须执行的所有操作、要操作的数据以及它们之间的关系,从而使处理器具有更大的能力智能协调工作。
为了实现内存中的批处理计算,Spark 使用称为弹性分布式数据集或 RDDs 的模型来处理数据。 这些是存在于内存中的不可变结构,代表数据的集合。 RDD 上的操作会产生新的 RDD。 每个 RDD 都可以通过其父 RDD 追溯其血统,并最终追溯到磁盘上的数据。 本质上,RDD 是 Spark 保持容错的一种方式,无需在每次操作后回写到磁盘。
流处理模型
流处理功能由 Spark Streaming 提供。 Spark 本身的设计考虑了面向批处理的工作负载。 为了处理引擎设计和流式工作负载特性之间的差异,Spark 实现了一个名为 micro-batches* 的概念。 该策略旨在将数据流视为可以使用批处理引擎的本机语义处理的一系列非常小的批处理。
Spark Streaming 通过以亚秒为增量缓冲流来工作。 这些作为小型固定数据集发送以进行批处理。 在实践中,这工作得相当好,但它确实导致了与真正的流处理框架不同的性能配置文件。
优点和局限性
在 Hadoop MapReduce 上使用 Spark 的明显原因是速度。 由于其内存计算策略和先进的 DAG 调度,Spark 可以显着更快地处理相同的数据集。
Spark 的另一个主要优势是它的多功能性。 它可以部署为独立集群或与现有 Hadoop 集群集成。 它可以执行批处理和流处理,让您操作单个集群来处理多种处理方式。
除了引擎本身的功能之外,Spark 还有一个库生态系统,可用于机器学习、交互式查询等。 Spark 任务几乎被普遍认为比 MapReduce 更容易编写,这可能对生产力产生重大影响。
为流处理调整批处理方法涉及在数据进入系统时对其进行缓冲。 缓冲区允许它处理大量传入数据,从而提高整体吞吐量,但等待刷新缓冲区也会导致延迟显着增加。 这意味着 Spark Streaming 可能不适合需要低延迟的处理。
由于 RAM 通常比磁盘空间更昂贵,因此 Spark 的运行成本可能高于基于磁盘的系统。 但是,处理速度的提高意味着任务可以更快地完成,这可以完全抵消在您按小时为资源付费的环境中运行时的成本。
Spark 内存设计的另一个后果是,当部署在共享集群上时,资源稀缺可能是一个问题。 与 Hadoop 的 MapReduce 相比,Spark 使用的资源要多得多,这可能会干扰当时可能尝试使用集群的其他任务。 从本质上讲,与其他可以在 Hadoop 堆栈上运行的组件相比,Spark 可能是一个不太体贴的邻居。
概括
对于具有不同处理工作负载的人来说,Spark 是一个很好的选择。 Spark 批处理提供了令人难以置信的速度优势,并以高内存使用为代价。 对于重视吞吐量而不是延迟的工作负载,Spark Streaming 是一个很好的流处理解决方案。
阿帕奇弗林克
Apache Flink 是一个流处理框架,也可以处理批处理任务。 它认为批处理只是具有有限边界的数据流,因此将批处理视为流处理的子集。 这种所有处理的流优先方法有许多有趣的副作用。
这种流优先方法被称为 Kappa 架构,与更广为人知的 Lambda 架构(其中批处理用作主要处理方法,流用于补充和提供早期但未完善的结果)形成对比。 Kappa 架构,其中流用于一切,简化了模型,并且直到最近随着流处理引擎变得更加复杂而成为可能。
流处理模型
Flink 的流处理模型将传入的数据逐项处理为真正的流。 Flink 提供了它的 DataStream API 来处理无限的数据流。 Flink 使用的基本组件是:
- Streams 是流经系统的不可变的、无界的数据集
- Operators 是对数据流进行操作以产生其他流的函数
- Sources 是流进入系统的入口点
- Sinks 是流从 Flink 系统流出的地方。 它们可能代表一个数据库或另一个系统的连接器
流处理任务在计算期间在设定点拍摄快照,以便在出现问题时用于恢复。 对于存储状态,Flink 可以使用多个状态后端,具体取决于不同级别的复杂性和持久性。
此外,Flink 的流处理能够理解“事件时间”的概念,即事件实际发生的时间,也可以处理会话。 这意味着它可以保证以一些有趣的方式进行排序和分组。
批处理模型
Flink 的批处理模型在很多方面只是流处理模型的扩展。 它不是从连续流中读取,而是从持久存储中读取有界数据集作为流。 Flink 对这两种处理模型使用完全相同的运行时。
Flink 为批处理工作负载提供了一些优化。 例如,由于批处理操作由持久存储支持,Flink 将快照从批处理加载中移除。 数据仍可恢复,但正常处理完成得更快。
另一项优化涉及分解批处理任务,以便仅在需要时涉及阶段和组件。 这有助于 Flink 与集群的其他用户很好地配合。 对任务的先发制人分析使 Flink 能够通过查看整个操作集、数据集的大小以及后续步骤的要求来进行优化。
优点和局限性
Flink 目前是处理框架领域的独特选择。 虽然 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 提供真正的流处理和批处理支持。 它经过高度优化,可以运行为其他平台编写的任务,并提供低延迟处理,但仍处于早期采用阶段。
最适合您的情况将在很大程度上取决于要处理的数据的状态、您的要求的时间限制以及您感兴趣的结果类型。 在实施一体化解决方案和处理重点突出的项目之间需要权衡取舍,在评估新的和创新的解决方案而不是成熟且经过良好测试的解决方案时,也会有类似的考虑。