Apache 下流处理项目巡览
我们的产品需要对来自不同数据源的大数据进行采集,从数据源的多样化以及处理数据的低延迟与可伸缩角度考虑,需要选择适合项目的大数据流处理平台。我最初列出的候选平台包括 Flume、Flink、Kafka Streaming 以及 Spark Streaming。然而对产品架构而言,这个技术选型的决策可谓举足轻重,倘若选择不当,可能会导致较大的修改成本,须得慎之又慎。
我除了在项目中曾经使用过 Flume、Kafka 以及 Spark Streaming 之外,对其余平台并不甚了解。即便是用过的这几个平台,也了解得比较肤浅。因此我查阅了这些平台的官方文档以及相关文章,偶然发现有 Janakiram 在 2016 年 7 月 8 日发表在 The New Stack 网站上的这篇文章 All the Apache Streaming Projects: An Exploratory Guid ,全(jian)面(dan)介绍了目前在 Apache 下主流的流处理项目,具有一定参考价值。因此摘译过来,以飧读者。
最近几年,数据的生成、消费、处理以及分析的速度惊人地增长,社交媒体、物联网、游戏等领域产生的数据都需要以接近实时的速度处理和分析数据。这直接催生了流数据的处理范式。从 Kafka 到 Beam,即使是在 Apache 基金下,已有多个流处理项目运用于不同的业务场景。
Apache Flume
Apache Flume 或许是 Apache 众多项目中用于流数据处理的最古老项目了,其设计目的是针对诸如日志之类的数据进行采集、聚合和迁移。Flume 基于agent-driven architecture,客户端生成的事件会以流的形式直接写入到 Hive、HBase 或者其他数据存储。
Flume 由 Source、Channel 和 Sink 组成。Source 可以是系统日志、Twitter 流或者 Avro。Channel 定义了如何将流传输到目的地。Channel 的可用选项包括 Memory、JDBC、Kafka、文件等。Sink 则决定了流传输的目的地。Flume 支持如 HDFS、Hive、HBase、ElasticSearch、Kafka 等 Sink。
使用 Flume 的最常见场景是从多个源头采集流日志汇总并持久化到数据中心,以便于进一步地处理与分析。
典型用例:对来自于多个可以运行在 JVM 上的 Source 的日志进行流处理。
Apache Spark
Apache Spark 为开发者提供了基于 RDD 的 API,RDD 被称为弹性分布式数据集,是一个只读的数据集,可以分布于多个机器集群,具有容错性。Spark 的诞生本身是为了解决 MapReduce 的性能限制,它以内存模型对数据进行处理和分析,从而提高了处理的性能。
Spark 使用 Scala 进行开发,但它也支持 Java、Python 和 R 语言,支持的数据源包括 HDFS、Cassandra、HBase 与 Amazon S3 等。
Spark Streaming 是 Spark 其中的一个组件,用于高容错的流处理应用。由于它运行在 Spark 之上,因而允许开发人员重用批处理的相同代码,针对历史数据进行 join 流操作,或者针对流状态进行即刻查询。Spark Streaming 采用了micro-batching 模式,即本质上还是批处理,但处理的单元可以非常微小。
Spark 还可以运行在已有的 Hadoop 与 Mesos 集群上,并为探索数据提供了声明式的 shell 编写能力。
Apache Spark 可以与 Apache Kafka 配套,提供强大的流处理环境。
典型用例:实时处理社交媒体的 feed,以进行情感分析。
Apache Storm
Apache Storm 最初由 Twitter 旗下的 BackType 公司员工 Nathan Marz 使用 Clojure 开发。在获得授权后,Twitter 将 Storm 开源。它一诞生就几乎成为分布式的实时数据处理平台的标准。
Storm 常常被认为是 Hadoop 下的实时处理平台,官方文档则宣称:它能够像 Hadoop 进行批处理那样对数据进行实时处理。
Apache Storm 的主要设计目的是为了追求系统的可伸缩性与高容错性。它能够保证每条 tuple 数据至少能够被处理一次。虽然系统是由 Clojure 编写,但应用的编写却可以支持各种语言,只要这种语言能够读写标准的输入和输出流。
Storm 连接的输入流称之为“spouts”和“bolts”,对应处理和输出模块。spouts 和 bolts 的集合组成了有向无环图(DAG),在 Storm 中称之为拓扑(topology)。基于预先定义的配置,拓扑可以运行在集群上,根据 scheduler 对工作进行跨节点的分发。
Storm 的拓扑常常与 Hadoop MapReduce 的 Job 对比。但是不同于 Hadoop Job,拓扑可以持续不断地执行,直到它被终止。在拓扑中,Spouts 获取数据并通过一系列的 bolts 进行传递。每个 bolt 会负责对数据的转换与处理。一些 bolt 还可以将数据写入到持久化的数据库或文件中,也可以调用第三方 API 对数据进行转换。
基于适配器的概念,Storm 可以与 HDFS 文件系统协作,并作为 Hadoop Job 参与。
通常会将 Storm 与 Apache Kafka 和 Apache Spark 混合使用。Storm 提供了可靠的、可伸缩的高容错分布式计算框架。
典型用例:实时转换和处理社交媒体/物联网传感器流。
Apache NiFi
和其他流处理方案相比,Apache NiFi 相对较新,在 2015 年 7 月才成为 Apache 的顶级项目。它基于企业集成模式(Enterprise Integration Patterns, EIP),将数据流分为多个阶段和转换,最后到达目的地。
Apache NiFi 提供了直观的图形界面,使得用户可以非常方便地设计数据流与转换。业务分析师和决策者可以使用这个工具来定义数据流。它还支持各种输入源包括静态和流的数据集。数据源可以是文件系统、社交媒体流、Kafka、FTP、HTTP、JMS,流向的目的地则包括 ElasticSearch、Amazon S3、AWS Lambda、Splunk、Solr、SQL 和 NoSQL 数据库。
在物联网领域,Apache NiFi 有可能成为处理传感器数据的首选编排引擎。它提供了具有大数据处理能力的 Node-Red 简化,所谓 Node-Red 是面向物联网的基于流的编程模型。NiFi 内建支持 Kafka、JMS 以及其他通道。
Apache NiFi 的一个经典场景是用于对 Hot Path 与 Cold Path 的创建。数据集通常可以流经高速度的处理引擎,如 Apache Kafka、Amazon Kinesis 和 Azure Event Hubs。Apache NiFi 可以将相同的数据集分为两个独立的路径,一个用于近实时的处理(hot path),一个用于批处理(code path)。
典型用例:一个交互式的规则引擎,用于定义物联网传感器数据流。
Apache Apex
Apache Apex 由一家硅谷公司 DataTorrent 捐赠给 Apache 基金会,之前是实时流处理的商业产品。这是一个年轻的项目,刚刚(相对这篇文章的写作日期 2016 年)从孵化版本升级为顶级项目。它的定位就是在实时流处理上取代 Storm 与 Spark,号称处理速度是 Spark 的 10 到 100 倍。
相较于 Spark,Apex 提供了一些企业特性,如事件处理、事件传递的顺序保证与高容错性。与 Spark 需要熟练的 Scala 技能不同,Apex 更适合 Java 开发者。它可以运行在已有的 Hadoop 生态环境中,使用 YARN 用于扩容,使用 HDFS 用于容错。
Apache Apex 的目标是打造企业级别的开源数据处理引擎,可以处理批量数据和流数据。使用时可以根据具体的业务场景选择所谓 unbounded data 的实时流处理或者传统文件形式的 bounded data 处理,且这两种处理方式在 Apex 下是统一的。
Apache Apex 的架构可以读/写消息总线、文件系统、数据库或其他类型的源。只要这些源的客户端代码可以运行在 JVM 上,就可以无缝集成。
Apex 使用了一个操作子(operators)库,称之为 Malhar ,它为读写消息总线、文件系统和数据库提供了预先构建的操作子。这些操作子使得开发者能够快速构建业务逻辑,用于处理各种数据源。Apex 的整体目标就是为了简化企业应用中大数据项目的复杂度。
典型用例:运行在高容错基础设施之上的应用,需要以实时和批模式处理异构数据。
Apache Kafka Streams
Kafka Streams 仅仅是构建在 Apache Kafka 之上的一个库,由 Confluent 贡献,这是一家由 LinkedIn 参与 Kafka 项目的早期开发者创建的初创公司。
在过去的几年内,Apache Kafka 以实时与大规模消息系统著称,并变得越来越普及,快速成为了大数据平台的核心基础构件。它被广泛应用于各行各业的上千家公司,包括 Netflix、Cisco、PayPal 与 Twitter。公有云的提供商在其提供的大数据分析平台之上,都将 Kafka 作为一个托管的服务。
Kafka Streams 是一个用于构建流应用的库,特别用于处理将 Kafka topics 转换为输出的 Kafka topics。它的设计初衷并不是为了大量分析任务,而是用于微服务架构,进行高效而精简的流处理。这意味着 Kafka Streams 库用于应用程序的核心业务逻辑集成,而非用于大量的分析 Job。
Kafka Streams 将用户从繁杂的安装、配置以及管理复杂 Spark 集群中解放出来。它简化了流处理,使其作为一个独立运行的应用编程模型,用于响应异步服务。开发者可以引入 Kafka Streams 满足其流处理的功能,却无需流处理的集群(因为 Kafka 已经提供)。除了 Apache Kafka,在架构上并没有其他外部依赖。Kafka Streams 提供的处理模型可以完全与 Kafka 的核心抽象整合。
在讨论 Kafka Streams 时,往往会谈及 Kafka Connect。后者用于可靠地将 Kafka 与外部系统如数据库、Key-Value 存储、检索索引与文件系统连接。
Kafka Streams 最棒的一点是它可以作为容器打包到 Docker 中。DevOps 团队也可以使用 Ansible、Puppet、Chef、Salt 甚或 shell 脚本部署和管理它的应用。一旦被打包为容器,它就可以与一些编排引擎集成,如 Docker Swarm、Kubernetes、DC/OS、Yarn 等。
典型用例:需要进行流处理,但又不希望依赖复杂集群的微服务与独立部署的应用。
Apache Samza
Apache Samza 由 LinkedIn 开发,目的是为了避免 Hadoop 批处理引入的长时运转时间(large turn-around times)问题。它构建于 Kafka 之上。Samza 提供了持续数据处理的轻量级框架。
Kafka 与 Samza 的搭配就好比 HDFS 与 MapReduce 的搭配。当数据到达时,Samza 可以持续计算结果,并能达到亚秒级的响应时间。
在从流获得输入后,Samza 会执行 Job。可以通过编码实现 Job 对一系列输入流的消费与处理。编写 Job 可以使用 Java、Scala 或其他 JVM 下的编程语言。为了支持可伸缩性,Job 也可以被分解为多个小的并行执行单元,称之为 Task。每个 Task 可以消费其中一个分区传递的流数据。一个任务会顺序地处理来自其输入分区的数据,并保证消息的顺序。分区之间并没有定义顺序,因此允许每个任务独立对其进行操作。
Samza 会在一个或多个容器(container)中将多个任务组合起来执行。在 Samza 中,容器是单个线程,负责管理任务的生命周期。
Samza 与其他流处理技术的不同之处在于它的有状态流处理能力。Samza 任务具有专门的 key/value 存储并作为任务放在相同的机器中。这一架构使得它比其他流处理平台具有更好的读/写性能。
当使用 Kafka 进行数据采集时,架构上 Samza 会是一个自然的选择。
Apache Samza 与 Kafka Streams 解决的问题类似,在将来可能会被合并为一个项目。
典型用例:使用 Kafka 进行数据采集的更优化流处理框架。
Apache Flink
Apache Flink 在 2014 年 12 月成为 Apache 顶级项目。它的概念以及使用场景看起来与 Spark 相似,其目的在于提供运行批数据、流、交互式、图处理以及机器学习应用的一体化平台,但是二者在实现上存在差别。
Spark Streaming 是以处理迷你批数据的方式实现准实时处理能力。Apache Flink 则提供了实时处理能力,这源于其细粒度的事件级别处理架构(fine-grained event level processing architecture)。
Flink 提供了消息处理恰好一次(exactly-once)的保证,这就使得开发者不用再处理冗余消息。它提供了高吞吐量的引擎,在事件发送到分布式网络之前提供了 buffer 功能。同时,它还具有灵活的 windowing scheme,以支持强大的流编程模型。
Flink 提供 DataStream API 用于流数据的分析,DataSet API 用于批数据的分析,二者皆建立在底层的流处理引擎之上。
Apache Flink 支持 Java 或 Scala 编程。它没有提供数据存储系统。输入数据可以来自于分布式存储系统如 HDFS 或 HBase。针对流处理场景,Flink 可以消费来自诸如 Kafka 之类的消息队列的数据。
典型用例:实时处理信用卡交易。
Apache Beam
Apache Beam 同样支持批处理和流处理模型,它基于一套定义和执行并行数据处理管道的统一模型。Beam 提供了一套特定语言的 SDK,用于构建管道和执行管道的特定运行时的运行器(Runner)。
Beam 演化于 Google 的几个内部项目,包括 MapReduce、FlumeJava 和 Millwheel。在 Beam 中,管道运行器(Pipeline Runners)会将数据处理管道翻译为与多个分布式处理后端兼容的 API。管道是工作在数据集上的处理单元的链条。取决于管道执行的位置,每个 Beam 程序在后端都有一个运行器。当前的平台支持包括 Google Cloud Dataflow、Apache Flink 与 Apache Spark 的运行器。Storm 和 MapReduce 的运行器孩还在开发中(译注:指撰写该文章的 2016 年。我通过查看 Beam 的官方网站,看到目前支持的 runner 还包含了 Apex 和 Gearpump,似乎对 Storm 与 MapReduce 的支持仍然在研发中)。
Dataflow 试图在代码与执行运行时之间建立一个抽象层。当代码在 Dataflow SDK 中被实现后,就可以运行在多个后端,如 Flink 和 Spark。Beam 支持 Java 和 Python,其目的是将多语言、框架和 SDK 融合在一个统一的编程模型中。
典型用例:依赖与多个框架如 Spark 和 Flink 的应用程序。
Apache Ignite
Apache Ignite 是搭建于分布式内存运算平台之上的内存层,它能够对实时处理大数据集进行性能优化。内存模型的架构比传统的基于磁盘或闪存的技术要快。
Apache Ignite 于 2015 年 9 月从孵化版升级为 Apache 顶级项目。
虽然 Spark 与 Ignite 都是基于分布式的内存处理架构,但二者却存在差别。Spark 主要用于交互式分析(interactive analytics)以及机器学习,而 Ignite 则提供编程式的实时分析、机器对机器的通信以及高性能的事务处理。
对于交易处理系统例如股票交易、反欺诈、实时建模与分析而言,Ignite 可能会成为首选。它既支持通过添加硬件的方式进行水平伸缩,也支持在工作站以及专用服务器上的垂直伸缩。
Ignite 的流处理特性能够支持持续不断地没有终止的数据流,并具有可伸缩和高容错的能力。
典型用例:高度依赖于编程形式的实时分析应用,机器对机器的通信以及高性能的事务处理。
这篇文章并没有为大数据流处理技术选型提供充分的证据支持,对这些项目的介绍仅仅是泛泛而谈,但它为选型提供了相对完整的列表,让我们知道了到底有多少主流的且较为成熟的流处理平台,因而仍然具有一定的参考价值。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论