1.5.1 数据处理架构
我们已经知道,数据处理的基本方式可以分为批处理和流处理两种。
批处理针对的是有界数据集,非常适合必须访问海量的全部数据才能完成的计算工作,一般用于离线统计。
流处理主要针对的是数据流,特点是无界、实时,对系统传输的每个数据依次执行操作,一般用于实时统计。
从根本上来说,Spark和Flink采用了完全不同的数据处理方式。
Spark以批处理为根本,并尝试在批处理之上支持流计算;在Spark的世界中,“万物皆批次”,离线数据是一个大批次,而实时数据则是由无限个小批次组成的。因此,对流处理框架Spark Streaming而言,其实并不是真正意义上的流处理,而是“微批次”(micro-batching)处理,如图1-12所示。
图1-12 Spark Streaming流处理示意图
Flink则认为流处理才是最基本的操作,批处理也可以统一为流处理。在Flink的世界中,“万物皆流”,实时数据是标准的、没有界限的流,而离线数据则是有界限的流。图1-13就是所谓的无界数据流和有界数据流。
图1-13 无界数据流和有界数据流
1.无界数据流
无界数据流有头没尾,数据的生成和传递会开始,但永远不会结束。我们无法等待所有数据都到达,因为输入是无界的,数据没有“都到达”的时候。因此,对于无界数据流,必须连续处理,即必须在获取数据后立即处理。在处理无界数据流时,为了保证结果的正确性,必须做到按照顺序处理数据。
2.有界数据流
相应地,有界数据流有明确定义的开始和结束,因此,我们可以通过获取所有数据来处理有界数据流。处理有界数据流就不需要严格保证数据的顺序了,因为总可以对有界数据集进行排序。有界数据流的处理也就是批处理。
正因为这种架构上的不同,Spark和Flink在不同应用领域中的表现会有差别。一般来说,Spark基于微批处理的方式做同步,总有一个攒批的过程,所以会有额外开销,故无法在流处理的低延迟上做到极致。在低延迟流处理场景,Flink已经有明显的优势;而在海量数据的批处理领域,Spark能够处理的吞吐量更高,加上其完善的生态和成熟易用的API,目前同样优势比较明显。