开发者学堂课程【Apache Flink 入门到实战 - Flink 开源社区出品 :Apache Flink 概念介绍:有状态流式处理引擎的基石(一)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/632/detail/10037
Apache Flink 概念介绍:有状态流式处理引擎的基石(一)
内容介绍
一.何谓“有状态流式处理”
二.流式处理
三.分散式处理
四.有状态流式处理
五.有状态流式处理的挑战
六.总结
首先需要注意 Flink 为什么如此强大,为什么要使用 Flink 以及他与其他大数据引擎有何差别。
其次要注意 Apache Flink 有哪些优点与功能。
本节课程将会让大家了解为什么数据生态为什么会出现有状态流式的处理需求,以及状态流式与其他处理方式的差别,还会学习到状态流式处理的挑战以及如何应对这些挑战。
一.何谓“有状态流式处理”
首先观察传统批次数据处理的方式通常如何操作。
无论搜索什么资料,资料的信息都是持续传输进来的,客户端也会通过一些手段持续收取这些数据。在这种传统状态下,Flink 会以时间划分,把收到的数据划分成一个个批次档案,例如将3点到4点收到的数据划分为一个批次档案,4点到5 点的数据划分成一个批次档案,以此类推。划分完批次档案后,利用其他的批次引擎对批次档案进行运算。
若现在需要计算每个小时出现的特定事件次数,如上图,就是计算一小时内从事件A到事件B一共出现了几次。假设理想状态是A到B的转换都发生在同一个时间区间,如都在3-4点内发生。
但A发生在3:55,B发生在4:02,这个事件的发生时间跨越了理想区间,此时批次数据引擎的处理方式是先处理3:55-4:00的数据,得到这一时间段A的数据状态后,将这一状态带入4-5点的状态,对应到他所转换的B事件,由此得出A到B的运算次数。
严谨来说,若接收到事件的顺序是颠倒的,这种情况也是非常常见的,比如先发送A再发送B,而收到的顺序是先B后A,这种情况比较复杂,因此批次处理方法对于这一特质并不太符合。
上图的累积状态代表 Flink 收集着过去所传送出的所有状态,同时也代表着发生过的所有事件。
累积状态简单来说可以代表 counters,复杂的也可以代表 ML model。各种各样的东西都有可能是状态,重点是累积的状态会影响最后所产生的输出。
第二个重点是理想方法,理想方法必须有能力开始累积状态,并维护这个状态。
第三个重点是时间,如果没有时间是没有办法完整代表的,时间的用意是这套引擎,必须有能力或者有机制去判断引擎是否已经接收到他所有所需要的数据,进而产生结果。
观察传统批次示意图可以看到,把区间划分成三点到四点,四点到五点,五点到六点的是这个批次资料处理的方式在做的,但实际上一直以来很混淆的一个点在于理想区间定义三点到四点是一个批次产生的结果,然后要用批次运算去对数据做运算。而在做运算的时候,实际上我们如果直接划分的这个答案,是不是就代表,我们所认为四点该收到的资料都已经收到了呢?
实际上不是,因为四点是在 server 端所划分的四点,但实际希望定义的四点,应该是事件发生在四点之前的都收到后才去计算三点到四点的结果,后续会有更详细的解释,现在的重点是时间与资料是有相关性的。
此处有两个大重点,第一个大重点是刚刚所提的必须要有办法累积状态和维护大量的状态。
第二个重点就是时间,必须要依据时间去决定是否将该收的数据都收完后才产生结果。
二.流式处理
流式处理简单的说就是有一个无穷无尽的数据源,一直在收取资料,然后会产生一段程序码,这段程序码代表着要处理的 base subject,这个 base subject 会一笔一笔地从数据源拿资料,一笔笔处理后产生出的结果,最后输出,就是Long running computation,on an endless stream of input。
三.分散式处理
分散流式处理从整体来说就是若 input stream 是有很多个使用者,每一个使用者都有自己的 ID,希望计算出每一个使用者出现的次数,那一定要让同一个使用者拜访的事件都必须要到同一个运算的 instance 吗?
其实这个与其他批次要做的一样,需要做一些 protection,设定一个 key,然后让同样的 key 回到同一个 competition instance 运算。
四.有状态分散式流式处理
有状态分散式流式处理如上图程序码,用一个小片段去代表定义了一个变速 X,X 可能会做一些读写等,最后输出结果时,可以依据这个变速 X 决定要输出什么,如何输出,相当于 X 的状态会影响输出。
这里有一个重点,若假设先做了一个 key,同样的 key 都会流到同一个 competition instance,用刚刚的例子解释就是每一个使用者出现的次数,这个次数就是所谓的状态,这个状态一定会跟同样的 key 的事件都累积在同一个 competition instance,就是 State co-partiltioned with the input stream by key。
第二个重点是 embedded local state backend,意为一个有状态分散式流式处理的引擎,状态在一定可能性下会累积巨大,当 key 非常多的时候,状态可能会超出单一节点的负荷量,这时状态X必须要采取办法,设立一个状态后端去维护引擎。状态后端在正常状况下可以用 memory 去维护,可是在很多 production 的 use case,很多公司里面用 think use case,它的状态会非常大,当 memory 没有办法容纳下的时候,think 也没有办法去支援这样的使用场景。