「有状态的流式解决」概念解析
流式解决
流式解决简略地说就是一个无穷尽的数据源在继续的收数据,以代码作为数据处理的根底逻辑,而后输入,这就是流式解决的基本原理。
分布式流式解决
Stream 须要做分区,设置雷同的 Key,并让同样的 Key 流到一个 computition instance 做雷同的运算。
有状态分布式流式解决
代码中定义了变量 X,X 在数据处理过程会进行读写操作,变量 X 会影响最初的后果输入。比方计算每个使用者呈现的次数,次数即所谓的状态。
Apache Flink 的劣势
状态容错
作为有状态分布式流式解决引擎,咱们会思考到容灾问题,而且心愿是准确一次的状态容错保障,因为如果批改超过了一次就意味着数据引擎产生的后果是不牢靠的。于是咱们开始思考以下几点问题:
- 怎么确保状态领有准确一次(Exactly-once guarantee)的容错保障?
- 在分布式场景下怎么为领有多个本地状态的 operator 产生 grobal consistent snapshot?
- 最重要的是,怎么在不中断的前提下继续一直地产生快照呢?
简略场景的准确一次容错办法
咱们能够思考最简略的应用场景,比方是在繁多的 Flink Process 中进行运算,咱们想到能够用“笨办法”,每解决完一笔计算就累计一次状态,进行一次快照,就能确保准确一次。
分布式状态容错
假如在分布式场景下,进行多个本地状态的运算。当初咱们引入一个 Checkpoint 的概念,将每个 Opeartor 的状态保留在 Checkpoint 中,并且将 Checkpoint 传入共享的 DFS 中。如果任何一个 Process 挂掉,就能够从三个残缺的 Checkpoint 将所有运算值得状态复原。Checkpoint 的存在使整个 Process 可能实现在分布式环境中的 Exactly-once。
分散式快照(Distributed Snapshots)办法
对于 Flink 如何在不中断运算的情况下继续产生 Global consistent snapshot?引入 Checkpoint barrier N 的概念,Flink 首先会在 job manager 触发 Checkpoint,Checkpoint 触发后会在 Datastream 中会安插 Checkpoint barrier N。
当数据源收到 Checkpoint barrier N 后会将自已的状态保留好,Checkpoint barrier N 跟着数据流动到 Opeartor1 之后,Opeartor1 将数据记录在状态中,同样当 Checkpoint barrier N 流到 Opeartor2,Opeartor2 也会将数据反映到状态上。以上能够看到 Checkpoint barrier N 实现了一个残缺的表格,这个表格叫做 Distributed Snapshots,即分布式快照。
Flink job manager 能够触发其余的 Checkpoint,比方 Checkpoint N + 1,Checkpoint N + 2, 等也能够同步进行。正是利用这种机制,能够在不阻挡运算的情况下继续的产生 Checkpoint。
状态保护
JVM Heap 状态后端:适宜数量较小的状态,JVM Heap 状态后端每一次运算时都要读取状态,用 Java object read/writes 进行读写,不会产生较大代价,但当 Checkpoint 须要将运算值的状态放入 Distributed Snapshots 时就须要进行序列化了。
RocksDB 状态后端:这是一种 out of core 的状态后端,使用者去读取状态的时候会通过磁盘,相当于将状态保护在磁盘里,与之对应的代价可能就是每次读取状态时,都须要通过序列化和反序列化的过程。
Event Time
咱们要思考一个很重要的问题,Event Time 怎么能力确定曾经收到残缺运算所须要的数据,并输入运算后果?这个工夫点就是 Event Time 解决问题的精华。
Flink 实际上是用 watermarks 来实现 Event Time 的性能。Watermarks 其精华在于,当某个运算值收到带有工夫戳“T”的 watermarks 时,就意味着它不会接管到新的数据了。应用 watermarks 的益处在于能够精确预估收到数据的截止工夫。
状态保留与迁徙
流式解决利用无时无刻不在运行,所以在运维上有几个考量:变更底层代码逻辑、修 bug 或是降级 Flink 版本,从新定义利用、计算的平行化水平等,咱们该怎么保留状态进行数据迁徙。
Checkpoint 完满合乎以上需要,不过 Flink 中还有另外一个名词叫做 Savepoint。Savepoint 产生的原理是在 Checkpoint barrier 流动到所有的 Pipeline 中 手动插入 从而产生分布式快照,这些分布式快照点即 Savepoint。Savepoint 跟 Checkpoint 的差异在于,检查点是 Flink 在运行中利用分布式快照继续周期性的产生 Checkpoint,而 Savepoint 则是手动产生的 Checkpoint。
当实现变更时,能够间接从 Savepoint 复原、执行。当执行复原时须要留神:在变更利用的过程中流仍在继续运行,如 Kafka 在继续收集材料,所以当从 Savepoint 复原时,Savepoint 保留着那一时刻 Checkpoint 产生的工夫以及 Kafka 过后所对应的地位。所以它须要复原到最新的数据,但无论是任何运算,Event Time 都能够确保最初产生的后果完全一致。