Streaming流式数据处理是大数据领域的一个大问题:
- 企业希望更及时地了解他们的数据
- 现代商业中越来越常见的大规模、无限制的数据集
- 在数据到达时对其进行处理,使工作负载在一段时间内更均匀地分布,产生更一致和可预测的资源消耗
什么是Streaming?
Streaming流式计算这个词被用来表示各种不同的东西。这种缺乏精确性的术语模糊了流式计算的真正含义。设计良好的流式计算系统与任何现有的批处理引擎一样,能够产生正确的、一致的、可重复的结果(技术上更胜一筹)。
流式计算 一种设计上考虑到了无限的数据集数据处理引擎
一个数据集的状态由两个重要的(也是正交的)维度来定义:cardinality基数和constitution结构。
数据集的cardinality决定了它的大小,cardinality最突出的方面是一个特定的数据集是有限的还是无限的:
- 有边界数据:大小有限的数据集
- 无边界数据:大小(至少在理论上)无限的数据集
Cardinality很重要,因为无边界数据集的无边界性给处理它们的数据处理框架带来了额外的负担。
另一方面,数据集的构成决定了它的physical manifestation 物理表现形式。因此,constitution结构定义了人们与数据交互的方式。一个直观的感受是,存在两个重要的主要结构:
- Table表:给定时间点上的数据集的整体视角。传统上,SQL系统是以Table为单位进行处理的。
- Stream流:随时间演变,针对数据集逐个元素的视角。传统上,MapReduce一系的数据处理系统都是以流的形式处理数据。
流式计算的局限性
流式计算系统一直被归入一个小众场景:提供低延迟、不准确或带有推测的结果,通常需要与能力更强的批处理系统一起合作提供最终的正确结果;即所谓的Lambda架构。
对于那些还不熟悉Lambda架构的人来说,其基本思想是,运行批处理系统时并行启动一个流式系统,两者执行基本相同的计算。流式系统给出低延迟、不准确的结果(因为使用了近似算法,或者是因为流式系统本身不提供正确性),一段时间后,批处理系统逐步提供正确的输出。最初是由Twitter的Nathan Marz(Storm的创造者)提出的,并且相当成功。这在当时是一个绝妙的想法。流式引擎在正确性方面有点缺陷,而批处理引擎比较笨重,所以Lambda给了一个折中方法。不幸的是,维护Lambda系统是一件很麻烦的事:需要建立、提供和维护两个独立的pipeline版本,然后以某种方式合并两个pipeline的结果。
作为一个在强一致性Streaming引擎上工作多年的人,我也发现Lambda架构的整个原理有点恶心。当Jay Kreps发表"Questioning the Lambda Architecture 质疑Lambda架构"一文时,我当场点赞。这是最早高声反对双模式执行必要性的声明之一。Kreps通过使用像Kafka这样的可重放系统作为Streaming连接器解决了可重复性问题,甚至提出了Kappa架构。这表明设计一个的系统来运行单一管道执行任务是可行的。
更进一步,设计良好的Streaming系统实际上提供了batch功能的严格超集。除了效率上的差异外,Batch系统其实是没有必要的。这里我们要表扬Apache Flink的开发者,构建出这种all-streaming-all-the-time系统。
Batch和Streaming的效率差异
我认为效率差异不是流式计算系统本身的缺陷,而大多数流式计算系统的设计选择。批处理和流式计算之间的效率差异主要得益于批处理系统中额外的捆绑(increased bundling)和更高效的shuffle传输。现代批处理系统实施了复杂的优化,允许用户使用不多的计算资源来实现到极高的吞吐量水平。我们可以把批处理系统经验迁移到为无界数据设计的系统上,让用户灵活地选择高延迟、高效率的batch处理和低延迟、低效率的streaming处理。我们在谷歌的Cloud Dataflow已经实践了这种方式,在一个统一的模型下提供批处理和流处理的运行器。在我们的案例中,我们使用独立的运行器,因为我们刚好有两个独立设计、针对性优化的系统。从长远来看,从工程的角度,我很希望看到我们把这两个系统合并成一个单一的系统,在保留选择效率水平的灵活性的同时,将两者的最佳部分融合在一起。但这不是我们今天的主题。而且说实话,由于统一的数据流模型,它甚至没有严格的必要;所以它很可能永远不会发生。
为了把Lambda架构扫入垃圾堆,我们需要两样东西:
Correctness 正确性
正确性可以让streaming与batch处理对标。本质上,正确性可以归结为一致的存储。流式计算系统需要一种方法来效验随着时间推移的持久状态(这一点Kreps在"Why local state is a fundamental primitive in stream processing"一文中谈到过),而且在机器故障时这种方法依然要能保持一致性。几年前,当Spark Streaming首次出现在公开大数据领域时,它就像是黑暗的streaming世界中一致性的灯塔。
重申一下--因为这一点很重要:strong consistency 强一致性是exactly-once 完全一次性处理的要求,exactly-once是Correctness 正确性的要求,正确性是任何试图超越batch批处理系统的系统能力要求。批处理系统不需要额外花时间验证答案的正确性;不要把时间浪费在不能满足正确性标准的流式计算系统上。
如果你想了解更多关于在流式系统中达成强一致性所需要的东西,我建议你看看MillWheel、Spark Streaming和Flink snapshotting的论文。这三篇论文都花了大量的时间来讨论一致性问题。
Tools for reasoning about time 推理时间的手段
推理时间使streaming超越batch处理。好的时间推理方式对于处理不同事件时间偏差的无边界、无序的数据至关重要。越来越多的现代数据集表现出这些特征,而现有的批处理系统缺乏必要的工具来处理它们带来的问题。
我们要先对time domains时间域这个重要的概念有一个基本的了解,之后我们要深入研究我所说的不同事件时间偏差的无边界、无序的数据是什么意思。然后本章的其余部分,我们使用批处理和流式系统来研究有边界和无边界数据处理的常见方法。