随着新设备,传感器和技术的出现,数据增长率在不断加速,根据IBM最近的一份报告(https://www.mediapost.com/publications/article/291358/90-of-todays-data-created-in-two-years.html),当今全球90%的数据仅在过去两年内创建,每天创建2.5亿个字节的数据。

从技术上讲,这意味着我们的大数据处理世界将变得更加复杂和具有挑战性。许多用例(例如移动应用广告,欺诈检测,出租车预订,患者监控等)需要在数据到达时实时进行数据处理,以便做出快速可行的决策。这就是分布式流处理在大数据世界中变得非常流行的原因。

目前我们所接触的比较流程的开源流式处理框架:Flink、SparkStreaming、Storm、KafkaStreams、Smaza。之后的章节中我们会对以上几个框架的应用场景、优势、劣势、局限性一一做说明。

什么是流式处理,能解决什么问题?

目前对信息高时效性、可操作性的需求不断增长,这要求软件系统在更少的时间内能处理更多的数据。传统的大数据处理模型将在线事务处理和离线分析从时序上将两者完全分割开来,但显然该架构目前已经越来越落后于人们对于大数据实时处理的需求。

实时计算的产生即来源于对于上述数据加工时效性的严苛需求。数据的业务价值随着时间的流失而迅速降低,因此在数据发生后必须尽快对其进行计算和处理。而传统的大数据处理模式对于数据加工均遵循传统日清日毕模式,即以小时甚至以天为计算周期对当前数据进行累计并处理,显然这类处理方式无法满足数据实时计算的需求。在诸如实时大数据分析、风控预警、实时预测、金融交易等诸多业务场景领域,批量(或者说离线)处理对于上述对于数据处理时延要求苛刻的应用领域而言是完全无法胜任其业务需求的。而实时计算作为一类针对流数据的实时计算模型,可有效地缩短全链路数据流时延、实时化计算逻辑、平摊计算成本,最终有效满足实时处理大数据的业务需求。

流式处理的重点有哪些?

为了理解任何Streaming框架的优点和局限性,我们应该注意与Stream处理相关的一些重要特征和术语:

交付保障

  • Atleast-once(即使在出现故障时也至少会被处理一次)

  • Atmost-once(在发生故障时可能不会被处理)

  • Exactly-once(即使出现故障,数据也将被处理一次且恰好一次)
    从数据一致性的角度上看,完全一次是我们所希望的。但是在分布式系统中是比较难实现的,处于对性能以及数据安全一致性的考虑,都会从中权衡利弊作出响应的选择。

故障容错

分布式系统中,包含任务故障、节点故障、网络故障等,框架应该能够恢复,并且应该从它离线的位置再次开始处理,一般通过不时地检查流式传输到某个持久存储的状态来实现。

例如,在处理来自Kafka的数据时,检查点kafka在获得记录处理后会将offset存储到zookeeper。如果失败,请从检查点offset处重新开始。

状态管理

在状态处理要求的情况下,我们需要维护某些状态(例如记录中看到的每个不同单词的计数),框架应该能够提供一些机制来保存和更新状态信息。

性能

性能上我们考虑的有几个点:延迟、吞吐量和可伸缩性。理想的情况下,我们希望延迟尽可能小、吞吐量尽可能高,而实际上两者很难同时实现,只能努力做到两者之间的平衡。

高级功能(Event Time Processing, Watermarks, Windowing)

主要是应对复杂流处理的场景。

成熟

从企业技术应用的角度来看,这一点是非常重要的。记得起大公司的大规模验证和测试,框架的稳定性、可靠性也有一定的保障。成熟的框架,更有可能获得良好的社区支持和stackoverflow的帮助。

流式处理的两种类型

Native流

指每个传入的记录一到达就会被处理,而不必等待其他记录。

小批量处理

也称为快速批处理。这意味着每隔几秒就会将传入记录一起批处理,然后在一个小批量中处理,延迟几秒钟。

两种类型都有一些优点和缺点。
Native流:每个记录在到达时都会被处理,从而允许框架实现最小的延迟。但这也意味着很难在不影响每个记录的吞吐量的情况下实现容错,我们需要在处理后跟踪和检查点。此外,状态管理很容易,因为有长时间运行的过程可以轻松地维持所需的状态。

微批处理:与Native流恰恰相反,容错是与生俱来的,因为它本质上是一个批处理,吞吐量也很高,因为处理和检查点将一次性完成一组记录。但它不像Native流一样,它有一定的延迟成本。此外,有效的国家管理也将是一项难以维持的挑战。

现有流处理框架介绍

Storm


Storm是最老的流媒体框架,技术成熟可靠。社区也很活跃。ali还开发了jstorm,对storm进行了拓展完善。后续jstorm也融入到storm中,对于storm也是一个质的提升。比较适合于基于事件的一些简单用例场景。
优点:

  • 极低的延迟,真正的流媒体,成熟和高吞吐量

  • 非常适合非复杂的流媒体用例
    缺点:

  • 不支持状态管理

  • 没有事件时间处理,聚合,窗口,会话,水印等高级功能

  • 至少保证一次

Spark Streaming


Spark已经成为批处理中hadoop的真正继承者,也是第一个完全支持Lambda架构的框架。受到各大企业欢迎,并被广泛采用。2.0版本之后,spark除了Structured Streaming之外,还配备了许多优秀的功能,如定制内存管理(与flink类似)tungsten、watermarks, event time processing支持等。结构化流也更抽象,并且可以选择在微批处理之间切换2.3.0版本中的连续流模式。连续流模式有望像Storm和Flink那样提供低延迟,但它仍处于初始阶段,需要在操作中进行测试。
优点:

  • 支持Lambda架构

  • 高吞吐量,适用于不需要低延迟的应用场景

  • 由于微批次性质,默认情况下容错

  • 简单易用的高级API

  • 社区活跃,且积极的改进

  • 数据处理有且只有一次
    缺点:

  • 不是真正的流媒体,不适合低延迟要求

  • 要调整的参数太多。很难做到最好

  • 在许多高级功能中落后于Flink

Flink


和spark一样,flink也支持lambda架构。但是这种方法和实现与Spark的方法和实现完全不同。虽然Spark实际上是Spark-Streaming作为微批处理和Spark Batch特殊情况的批处理,但Flink本质上是一个真正的流引擎,将批处理作为带有限数据的流的特殊情况。虽然两个框架中的API从开发人员的角度来看都很相似,但它们在实现中没有任何相似之处。在Flink中,map,filter,reduce等各个函数实现为长时间运行的运算符(类似于Storm中的Bolt)
Flink看起来像是Storm的真正继承者,就像Spark成功批量使用hadoop一样。
优点:

  • 开源流媒体领域的创新领导者

  • 第一个真正的流媒体框架,具有Event Time Processing, Watermarksd等所有高级功能

  • 低延迟,高吞吐量,可根据要求进行配置

  • 自动调整,需要调整的参数较少,调优方便

  • 数据处理有且只有一次。

  • 得到像阿里巴巴等大公司的广泛接受
    缺点:

  • 社区没有spark那么大,但是正在快速增长

  • 目前还没有采用Flink Batch,仅适用于流媒体。

Kafka Steams


与其他流式框架不同,Kafka Streams是一个轻量级的库。它对于来自Kafka的流数据,进行转换然后发送回kafka非常有用。我们可以将它看作类似于Java Executor服务线程池的库,却内置了对Kafka的支持。它可以与任何应用程序很好地集成,并且可以开箱即用。

由于其重量轻,可用于微服务类型的架构。在与Flink的性能方面没有匹配,但同时不需要单独的集群运行,非常方便,非常快速,易于部署和开始工作。根据相关应用程序的性质,无论是分布式节点还是单个节点,Kafka Streams都能支持。
优点:

  • 非常轻量级的库,适用于微服务,物联网应用

  • 完全一次(kafka 0.11起)

  • 具备kafka所有的优良特性

  • 支持Stream连接,内部使用rocksDb来维护状态
    缺点:

  • 与卡夫卡紧密相连,不能在没有卡夫卡的情况下使用

  • 技术较新,尚未得到广泛使用

  • 不适用于较为复杂,繁重的任务

Samza


Samza和Kafka Steams非常类似,有很多相似之处。不管是Smaza还是Kafka Streams都与kafka紧密结合。从Kafka获取原始数据,然后将处理后的数据放回Kafka。Samza是Kafka Streams的缩放版本。虽然Kafka Streams是一个用于微服务的库,而Smaza则是运行与yarn之上。Samza需要Kafka用于源/接收器和Yarn用于流处理,就像MapReduce需要hdfs用于源/接收器和yarn用于批处理一样。

优点:

  • 具备KAFKA的容错和高性能

  • 如处理流程上已经使用了yarn和kafka,可以考虑选择Samza

  • Yarn公民

  • 低延迟,高吞吐量,成熟和大规模测试

缺点:

  • 与yarn和kafka结合紧密。缺一不可

  • 至少一次处理保证。也就是说存在数据重复的问题。

  • 缺少高级流媒体功能。如Watermarks, Sessions, triggers等等

流式框架比较

我们只能将技术与同类产品进行比较。虽然Storm,Kafka Streams和Samza对于更简单的用例看起来很棒,但真正的竞争显然是具有高级功能的重量级框架之间的比较:Spark vs Flink

当我们在对两个框架做比较时,通常会用数据说话。而基准测试是比较两个框架的常用方法。spark在2.0版本之前流式处理做的并不是很好,2.0之后提出了结构化流媒体功能,也在不断的提升。

既然是用数据说话,那么就需要得到相同场景下两者的测试数据,而获取测试数据,没有比做一个poc更好的方法了。

截至今天,看起来Flink正在引领Streaming Analytics领域,首先拥有大部分流处理所需的功能,如完全一次,吞吐量,延迟,状态管理,容错,高级功能等。flink仍在不断创新,如轻量级快照和堆外定制内存管理。

直到某些时候,Flink的一个重要问题是成熟度和采用水平,但现在像优步,阿里巴巴,CapitalOne这样的大公司正在大规模使用Flink流媒体来证明Flink Streaming的潜力。 最近,优步开放了他们最新的流媒体分析框架,名为AthenaX,它建立在Flink引擎之上。

如何选择最好的/最适合的流失处理框架?

作为开发人员,我们不能偏向于任何框架。我们应该记住,没有一个处理框架可以成为所有应用场景的灵丹妙药。每个框架都会有一些优势和一些限制。下面将分享一些可能有助于做出决定的关键点。

使用场景

如果用例很简单,而学习和实现起来很复杂,就不需要使用最新的和最好的框架。很大程度上取决于我们愿意为我们想要的回报付出多少投资。

未来的考虑

在系统调研阶段,我们很多时候都会考虑未来可能的用例都有哪些?未来可能会出现Event Time Processing,aggregation,stream joins等高级功能的需求吗?如果答案是肯定的或可能的话,那么值得考虑具有Spark Streaming或Flink等高级功能的框架。一旦投资并在一种技术中实施,以后切换框架并不容易,因为它涉及大量的工作和时间。

现有的技术堆栈

考虑现有技术堆栈可以说是一个比较重要的一点,毕竟结合已有技术框架在实现难度以及效率上会提升不少。如果现有的管道已经利用了Kafka,那么Kafka Streams或Samza可能更容易适应。类似地,如果处理管道基于Lambda架构并且Spark或Flink已经用于批处理,则考虑Spark Streaming或Flink Streaming是有意义的。

总结

以上对什么是流处理/流媒体、流处理的分类、流处理框架以及如何选择一一做了介绍。
总结出来有几个点:

  • 延迟要求高
    毫秒级:storm、kafka steams、flink
    秒级:flink、spark streaming

  • 功能复杂度:
    高级功能需求:flink、spark streaming
    功能简单:storm、kafka streams

  • 现有技术堆栈
    以上几个框架对kafka的支持都已经做的很好了。这点其实暂时可以忽略
    如果已经使用了flink或者spark做批处理,那么可以考虑直接用spark streaming或者flink streaming

  • 未来的考虑
    这点还是要具体问题具体分析,很多情况下,一个框架是无法解决所有的应用场景的。有时候拆分处理也不失为一个好的选择。

  • 社区热度
    目前社区热度最火的应该是spark,其次是flink和storm,kafka streams是比较新的框架,大公司的使用案例较少,但值得关注,samza个人用的比较少,所以这里也不做评价。

参考链接:
https://www.linkedin.com/pulse/spark-streaming-vs-flink-storm-kafka-streams-samza-choose-prakash/