这是分布式数据处理系统系列的第一篇,也是当下实时流计算引擎实现的奠基石,为了帮助大家从理论到实现形成一个完整的知识体系,计划分为理论篇(剖析分布式数据处理系统的核心思想)和实现篇(详解当下实时流计算引擎如何实现核心思想);大数据的核心是分布式数据处理,建议大家关注[大数据达摩院],后期更精彩哦。
先来一睹理论篇系列:
- 通俗易懂,揭秘分布式数据处理系统的核心思想(一)
- 通俗易懂,揭秘分布式数据处理系统的窗口模型(二)
- 通俗易懂,揭秘分布式数据处理系统的触发器模型(三)
- 通俗易懂,揭秘分布式数据处理系统的增量处理模型(四)
- 敬请期待...
为了分享对大规模、无边界、乱序数据流的处理经验 ,2015年谷歌发表了《The Dataflow Model》论文,剖析了流式(实时)和批量(历史)数据处理模式的本质,即分布式数据处理系统,并抽象出了一套先进的、革新式的通用数据处理模型。在处理大规模、无边界、乱序数据集时,可以灵活地根据需求,很好地平衡数据处理正确性、延迟程度、处理成本之间的相互关系,从而可以满足任何现代数据处理场景,如:游戏行业个性化用户体验、自媒体平台视频流变现、销售行业的用户行为分析、互联网行业实时业务流处理、金融行业的实时欺诈检测等。
目标
- 抽象出一个具有足够普遍性,灵活性的通用数据处理模型,统一 批量处理和流式处理,从而简化大规模数据处理管道的构建。
- 允许用户根据使用场景配置进行适应,数据处理引擎自动平衡数据的准确性、延迟程度和处理成本。
核心的设计原则
从数据类型角度,数据处理系统要处理的数据只有两种:有限数据集和无限数据集流,故应该使用有边界/无边界等词汇来描述数据源,而不是批/流;同时,为了统一数据处理类型,应该将有限数据集视为无限数据流的特例,故永远不知道数据流何时终结,新的数据只会源源不断地来,源源不断地被处理,然后源源不断地修正老的数据处理结果,而不是像传统批处理系统需要等待一个批次的数据到达完整后才处理,把关注点从等待数据完整性转变为自动适应持续变化的数据源。
Refocusing the approach from one of finding completeness in data to one of adapting to the ever present changes manifest in realworld datasets.
话外音1:不用再为了等待数据而担心失去数据的实效性,过时的计算结果可能一文不值。
话外音2:核心设计原则就是谷歌提出的一种新的数据处理思维模式。
基于这样的原则而设计出的数据处理系统,既可以处理无限数据流,也可以处理有限数据集。从数据处理逻辑角度来看,区分流/批毫无意义,因此仅保留这组词汇(流、批)用来区分数据处理引擎。
话外音1:这就是分布式数据处理系统的通用解决方案,即实时流式处理系统。
话外音2:看完这篇你就知道当下实时流计算系统(如:flink)是如何处理乱序数据了。
通用的数据处理流程
基于上面提出的核心设计原则,从数据处理逻辑上提出了通用的数据处理流程,如下:
-
What results are being computed.
计算什么结果?
-
Where in event time they are being computed.
在哪里计算?
-
When in processing time they are materialized.
何时计算?
-
How earlier results relate to later refinements.
旧的计算结果如何在后期被修正?
从四个维度上归纳了实时流式计算的所有问题,完全实现了数据处理逻辑与底层物理实现的解耦,将对数据处理引擎(批、微批、流)的选择转变为简单的对数据准确性、延迟程度和处理成本之间的选择,不仅解决了当前大数据处理引擎选型难,学习成本高的问题,也解放了高层用户的大脑,即用户只需根据实际的数据和资源情况对准确性、延迟、处理成本的要求进行评估,而无需了解底层系统,这些都是大数据工作者的事情。
话外音1:中文不是字面翻译,而是精髓哦,直接翻译英文原语大家感受不到抽象而通用的魅力,嘿嘿。
话外音2:任何底层实现(数据处理引擎)只管实现上面的处理流程,并说明擅长的特点,高层用户都能很好地选型,不仅促进了整个大数据领域朝着良性的方向持续地发展,也更切合实际。
切合实际的解决方案
再温习一遍核心的设计原则:
假设永远不知道数据流何时终结,唯一确信的是新的数据会源源不断地来,源源不断地被处理,然后源源不断地修正老的数据处理结果,而不是等待一个批次的数据完整后再处理,把关注点从等待数据完整性转变为自动适应持续变化的数据源。
流式系统中的时间语义
1、事件发生时间
事件发生时,该事件所在系统的时间戳。
2、事件处理时间
处理事件时,该事件所在系统的时间戳。
一个事件的发生时间是永远不变的,但是处理时间会随着它在数据处理管道中一步步被处理时持续变化。也就是说基于事件时间的处理为确定性计算,即每次计算结果都一样;而基于处理时间的处理为非确定性计算,即每次的计算结果可能不同。
一、计算什么结果?
计算,即加工数据, 结果,即输出数据,翻译过来就是:如何将输入数据加工成下游所需的输出数据。从数据处理的角度,Dataflow将加工过程定义数据转换,即Transformation,同时归纳出了两大类的数据转换操作,如下:
1、非聚合操作
针对每个输入元素,直接转换输出0或多个输出元素,如:Map(),FlatMap(),Reduce()函数。
对于非聚合函数,每条数据都是独立的,计算引擎只需将它转换为下游需求的格式即可,天生适用于处理无边界数据流。
话外音1:非聚合操作,Dataflow叫ParDo操作。
2、聚合操作
先按键分组聚合数据,等数据到齐后计算结果,如:Sum()、Max()、Min()函数。
对于聚合函数,在把数据发送到下游进行汇总前,为了聚合,需要先收集到指定的键对应的所有数据。如果输入源是无边界的,不知道何时才能收集到所有的数据,故Dataflow提出了窗口模型(The Window Model)来解决在哪里计算的问题。
话外音1:聚合操作,Dataflow叫GroupByKey操作。
二、在哪里计算?
从上一个步骤可以看到,聚合操作只能作用于有限数据集,故需要一种将无限数据流切分成一段段有限数据集的机制,解决计算位置的问题,于是窗口模型(windowing model)应运而生。
为了能够平衡数据准确性,必须按照数据本身的特征进行计算,即基于事件的发生时间顺序计算出的结果才是准确的,故必须按照事件时间来确定计算位置,即在哪段事件发生时间范围内计算,请看原文,如下:
Where in event time they are being computed.
话外音:为了以简洁明了的方式讲明白分布式数据处理系统的核心思想,这里不做过多阐述,感兴趣的同学,可以继续阅读《通俗易懂,揭秘分布式数据处理系统的窗口模型(二)》。
三、何时计算?
解决了在哪里计算的问题,只是向前迈了一大步,何时关闭窗口并计算出结果发往下游呢?
话外音:这是分布式数据处理的难题之一,呵呵。
方案一:水位线
为了解决窗口数据完整性的问题,那么就需要一种描述全局事件处理进度指标的机制,来等待数据完全到达,这就是水位线(watermark),可以简单理解为一个可