gydtep 发表于 2021-11-29 12:09:06
后者指的是在事务开始或结束时,数据库中的记录应该在一致状态,相应地,流计算中的一致性可以定义为:流计算系统在计算过程中,或是出现故障恢复计算后,gydtep 发表于 2021-11-29 14:13:08
除了数据输入带来的挑战,流计算输出的数据会被实时消费,类似这样不同于批处理的应用场景,也给数据的一致性带来的诸多挑战,如出现 FO 后,是撤回之前发出的数据,还是是同下游进行协商实现一致性,都是需要考虑的。gydtep 发表于 2021-11-29 16:57:14
Exactly-once State Consistency 只是表达了:流计算要求对状态的更新只提交一次到持久后端存储,但这里的状态一般不包括「输出到下游结果」,而仅指引擎内部的状态,譬如各个算子的状态、实时流的消费偏移等,流计算引擎内部状态变更的保证,并不能等价于从输入到输出的一致性,端到端一致性需要你自己关心。gydtep 发表于 2021-11-29 21:57:22
流计算中的确定性指的是,给定相同的一组数据,重复运行多次或者打乱数据进入引擎的顺序,计算完成后将会输出相同的结果,否则就是非确定性计算。常见的非确定性计算包括使用了随机数、使用系统时间、字符串拼接等。如果流计算中存在非确定性的计算,则会给端到端一致性的实现造成很多困难,部分引擎并不能很好地支持此类场景。gydtep 发表于 2021-11-30 09:49:13
当在 t ~ t + 1 时刻发生故障,恢复函数 R 可以屏蔽此次故障产生的副作用,让使用方认为没有故障发生,可以得到正确的 O(t+1),显然,解决的思路是:将 E(t) 和 O(t) 作为输入,重新执行计算 F,则可以得到正确的 O(t+1)gydtep 发表于 2021-11-30 14:04:46
在实际的流计算引擎实现中,对于结果内容的定义大都是一致的,主要包括输入源的消费偏移 SourceState(t),e.g. Kafka Offset,算子状态 OperatorState(t),e.g. Spark RDD 血缘,输出的结果 Sink(t),e.g. Kafka 事务消息,但是在结果的存储方式上各有所不同,下面我们来看一看目前业界主流的几个流计算引擎的设计考量。gydtep 发表于 2021-11-30 20:51:40
Kafka Streams 是 Apache Kafka 0.10.0版本中包含的一个Java库,严格来讲并不算一个完整的流处理引擎,利用这个库,用户可以基于 Kafka 构建有状态的实时数据处理应用,更进一步地,Kafka Streams 需要数据输入源和输出均为 Kafka 消息队列。gydtep 发表于 2021-12-1 11:19:46
这里提到的 Spark Streaming 指的是原始的基于「Micro-batch,微批」的 Spark 流处理引擎,后面 Spark 又提出了Structured Streaming,使用 Continuous Processing mode 来替代「微批」解决延迟的问题,容错机制上和 Flink 一样也使用了Chandy-Lamport 算法,Structured Stream 目前还不成熟,暂时还不能完全支持 Exactly-Once-Processing,因此这里着重对比 Spark Streaming。gydtep 发表于 2021-12-1 11:38:24
考虑一种比较简单的场景:不存在非确定计算的流计算应用。如果不存在非确定计算,根据端到端的一致性语义的充分必要条件,只需要接受端实现幂等,则 Spark Streaming 就可以实现端到端的一致性。gydtep 发表于 2021-12-1 15:43:53
上面我们简述了目前主流的几种流计算引擎的一致性实现机制。从整体来看,如果实现端到端的一致性,则均需要满足我们上面从形式化定义推导出来的充分必要条件:实时存储每一条中间和最终计算结果,如果考虑吞吐率不能存储每一条,