柳州网站建设之流计算引擎数据一致性的本质 二维码
33
发表时间:2021-10-15 10:48 流计算的应用与实践在大数据领域越来越常见,其重要性不言而喻,常见的流计算引擎有 Google DataFlow、Apache Flink,Apache Kafka Streams,Apache Spark Streaming 等。流计算系统中的数据一致性一般是用消息处理语义来定义的,如某引擎声称可以提供「恰好一次(Exactly-once Processing Semantics)流处理语义,表示(或暗示)引擎具备保证数据一致性的能力。事实上,「恰好一次(Exactly-Once)」并不等价于流计算的输出数据就符合一致性的要求,该术语存在很多理解和使用上的误区。 本篇文章从流计算的本质出发,重点分析流计算领域中数据处理的一致性问题,同时对一致性问题进行简单的形式化定义,提供一个一窥当下流计算引擎发展脉络的视角,让大家对流计算引擎的认识更为深入,为可能的流计算技术选型提供一些参考。文章主要分为三个部分:**部分,会介绍流计算系统和一致性难题的本质;第二部分,会介绍一致性难题的通用解法以及各种方案间的取舍;第三部分,会介绍主流的流计算引擎是如何对通用解法进行泛化以实现一致性。 一 流计算中的一致性 在认识流计算系统一致性之前,我们需要精确定义流计算。流(Streaming)计算是一种在无边界数据(unbounded data)上进行低延迟计算的数据处理过程。相应的,批计算更准确的说法是有界数据(bounded data)的处理,亦即有明确边界的数据处理,流和批只是两种不同数据集的传统数据计算方法,它们并不是泾渭分明的,譬如也可以通过批量的方式(e.g. Spark Streaming 中的 micro-batch)来实现无界数据上的流处理过程。 1 一致性定义及挑战 如果我们将流计算的过程(获取输入数据、处理数据、输出计算结果)视为数据库的主从同步过程,抑或视为一种从流数据生成衍生数据集(表)的过程,则流计算中的数据一致性同关系型数据库事务 ACID 理论中的 Consistency 有异曲同工之妙,后者指的是在事务开始或结束时,数据库中的记录应该在一致状态,相应地,流计算中的一致性可以定义为:流计算系统在计算过程中,或是出现故障恢复计算后,流系统的内部状态和外部输出的数据应该处在一致的状态。譬如,当故障恢复后开始重新计算,计算的结果是否满足数据的一致性(即用户无法区分恢复前和恢复后的数据)?记录是否会重复/丢失,第三方系统对同一条计算结果的多次获取,是否会存在值上的不一致?对一致性有了清晰的认知和定义后,我们来看看为什么实现一致性这么难。
在定义一中我们可以看到,流计算输入的数据是无边界的,所以系统中会存在消息抵达流计算系统延迟、顺序错乱、数量/规模未知等不确定因素,这也是流计算系统一致性复杂性远远大于批处理系统的原因:批处理系统中的输入是确定的,计算过程中可以通过计算的原子性来保证数据的一致性(如 Spark 中的 RDD 血缘)。此外,同其他分布式应用一样,流计算系统经常也会受到各类意外因素的影响而发生故障,比如流量激增、网络抖动、云服务资源分配出现问题等,发生故障后重新执行计算,在存在不确定输入的前提下设计健壮的容错机制难度很大。 除了数据输入带来的挑战,流计算输出的数据会被实时消费,类似这样不同于批处理的应用场景,也给数据的一致性带来的诸多挑战,如出现 FO 后,是撤回之前发出的数据,还是是同下游进行协商实现一致性,都是需要考虑的。 2 一致性相关概念祛魅 正确认识流计算系统一致性的内在含义和其能力范畴,对我们构建正确且健壮的流计算任务至关重要。下面我会介绍几组概念,以便于大家更好地理解流计算系统的一致性。 恰好一次≠恰好一致 今天大多数流计算引擎用「Exactly-Once」去暗示用户:既然输入的数据不是静态集合而是会连续变化的,那对每一条消息「恰好处理」了一次,输出的数据肯定是一致的。上述逻辑的推导过程是没问题的,但并不严谨,因为 Exactly-Once 作为一个形容词,后面所连接的动词或者宾语被故意抹去了,不同的表达含义也会大相径庭。 例子1,后接不同的动(名)词:Exactly-once Delivery 和 Exactly-once Process 。前者是对消息传输层面的语义表达,和流计算的一致性关系不是很大,后者是从流计算的应用层面去描述数据处理过程。 例子2,后接不同的名词:Exactly-once State Consistency 和 Exactly-once Process Consistency。前者是 Flink 在官网中对其一致性的叙述,后者是 Kafka Streaming 的一致性保证,前者的语义约束弱于后者。Exactly-once State Consistency 只是表达了:流计算要求对状态的更新只提交一次到持久后端存储,但这里的状态一般不包括「输出到下游结果」,而仅指引擎内部的状态,譬如各个算子的状态、实时流的消费偏移等,流计算引擎内部状态变更的保证,并不能等价于从输入到输出的一致性,端到端一致性需要你自己关心。 总之,如何我们后面再看到 Exactly-once XXX,一定要警惕引擎想要透露出什么信息。 端到端的数据一致性 端到端一致性(End-To-Ene Consistency),即将数据的输出也作为流计算引擎的一致性设计的一部分,正确的结果贯穿着这整个流计算应用的始终:从输入、处理过程、输出,每一个环节都需要保证其自身的数据一致性,同时在整个流计算流程中,作为整体实现了端到端的一致性。 下面叙述中,如果不是特意说明,一致性指的是引擎自身状态的一致性,端到端一致指的是包含了输出的一致性。 来源:阿里技术 |