开发者学堂课程【开源 Flink 极客训练营:走进 Apache Flink】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/760/detail/13337
走进 Apache Flink
二、唯快不破–流批的本质
讨论流批本质时可以借助数据库辅助理解流与批的区别与联系。
可以用 insert 、update 、delete 来管理数据库,然后用 select 来查询。查询本身就是一种计算,同时还可以利用 trigger 来监控表数据的一些变化。
1.假如有一个需求,要实时显示某种表中的全部数据,应该用什么方式满足该需求?
如果用 insert 传入一个数据,然后用 update 更新一些信息。很容易想到用 select 可以查询表里面的一些数据,然后进行一些可视化的显示和监控。这里需要考虑一个问题,当执行了这一次查询之后,其实是一个手动触发,那么下次如何触发是不可预知的。可能10分钟,可能1小时,可能1天,甚至想起来再查一次,总而言之,无论什么时间去查询一次,不能做到只要数据表有变化就显示出来。如果要达到这样一个效果,可以利用孵化器。
比如定义一个 insert 的触发器,再定义一个 update 的触发器,这里以 insert 的触发器为例。定义完成后其逻辑是只要表里有 insert 数据,就立即触发查询并将结果写入到一个文件中。update 的触发器也同样触发查询并写入一个结果文件中。
对应的触发器及语句来说,就会生成两个结果文件,当执行 insert into 时,生成 trigger1,执行 update 时,再生产一个 trigger2.结果如下:
上图中的 insert 语句是将 clicks 更新为2,第一次查询时只有一个 Mary 1,第二次查询时本质上插入了一个 insert into Bob 1,所以第二次查询时出现了 Bob 1。
注意:该截图显示的是 insert 的触发器,所以两次查询中只有 insert 生效,update 的生效需要真正的去定义 update 的查询后再去进行才会生效。
2.流批计算的背后是在说什么?
既然数据库本身就可以完成流批的计算,为什么还需要很多的大数据批计算流计算的计算框架?
本质上,不管是流还是批,都是对数据的处理,尤其是对大数据的计算处理能力。
随着云计算、物联网、人工智能等信息的到来,人们步入了一个信息的时代。目前全球的数据量呈现几何的增长,下图是预测数据:
全球10年的时间,数据量从16.1ZB 增长到163ZB,该数据量已经远远超过单台计算机的存储和处理能力。(ZB 是一个更难想象的数据)
3.这些数据从哪里来?
目前的数据的确在非常快速的增长,比如 Facebook 的社交平台有几百亿、几千亿的照片信息,一些证券交易市场每天有几TB或十几TB 的交易数据量。
举例阿里巴巴:
10年来,阿里巴巴每年双十一的交易额增长了几千倍。在19年时,Flink 流计算的处理能力创造了25.5亿条每秒的处理记录。从种种事实来看,这些数据都是存在的(不知道不代表不发生),数据量的惊人是存在的,在某种程度上推动了技术的发展。
用户对技术的核心诉求?
首先是能够处理已有的数据,在能够处理已有数据的前提下,要求计算准确、迅速。
4.海量数据的技术支撑?
由谷歌发展的三大理论(三大马车):
解决了分布式存储和分布式计算,解决了这两个问题解决了当前的海量数据的增长,对该数据价值的挖掘提供了技术手段。
谷歌的三大马车描述了如何进行海量数据的分析的计算,但是其真正实现的落地是在谷歌内部。对于谷歌之外的公司完成分布式存储和分布式计算是通过 Apache Hadoop 生态。
对于该开源的生态,其体系是一个分布式的批计算框架,一般是若干小时或者若干天的计算延时。在实际的生产业务中,大多数在 T+1 的场景应用会应用 Hadoop 分布式计算(今天看到的结果是为昨天数据的统计分析),所以其很好的完成了在大数据环境中用户对海量数据支撑和计算准确性的需求。
本质是该需求得到满足,但是数小时的延时并不能认为是计算速度快,用户需要的快速是秒或毫秒级别,所以这种批计算没有很好的达到计算的快速问题。
一般来说,数据计算的多个处理环节叫 stage,批计算的逻辑是 stage by stage(当前的 stage 没有完成之前不能启用下一个 stage)。如果 n 个数据转换逻辑,从第一个 stage 的启动处理直到第 n 个 stage 处理完成后,才能有真正的具体结果。在数据量相同的情况下,业务逻辑还是同样的处理逻辑的情况下,降低业务的延时要通过流计算。
5.流计算的方式为什么能够解决该问题?
因为数据的处理就像流水一般,同时启动所有环节和逻辑,哪怕刚流第一滴水,就将这一滴水的处理逻辑都处理完成并输出这一滴水的处理结果留到下一步。这样不用等到所有数据到齐,将所有数据都执行完再输出结果,这种及时的计算模式就是流计算。因为该缘故,促使其在业务延时方面和批计算有天壤之别。
如果不看技术的实现,单从用户视角看流与批的本质区别,那就是“快”。也就是说流与批的本质区别是业务延时上的不同。
其本质上的快是相对的,不同的业务有不同的需求。当前所说的秒、毫秒和数天的延时是两个极端,在实际业务上还有分钟的延时、小时的延时等等小时间间隔的延时。针对这样的需求,在小时和分钟的业务上,无论是批计算还是流计算,都是可能满足的,所以流计算和批计算对用户来说并没有很大的关系,用户更注重计算结果的准确性。
基于现在的分析和判断,对于计算引擎计算从实现的角度看,所谓的触发(秒、小时、天)是引擎内部的触发机制的设计。比如可以每条记录都触发一次并计算输出结果,那么自然而然是最低的延时,如果将数据结果在所有数据结束后再触发一次计算并输出结果,那么延时显示是最高的。如果在触发机制上支持按业务需求指定时间的范围或记录触发计算,对用户而言已经足够。所以流和批本质上的选择,更多的是计算引擎自己的优化。(满足用户的需求即可)
一个流批统一的系统,其本质上是一个计算的模式。
触发批计算是数据结构之后的孵化,对流计算而言,计算引擎的设计会根据流批认知的不同。
6.两种主流的设计方案
目前有两种主流的设计方案,一种是说批是流的一个特点。既然可以每条数据都触发一条计算,那么也可以3条或者5条甚至一个小时后再触发一次,所以流计算引擎自然而然的会支持批计算,所以批计算依赖是流计算的一个特点。另一种说法是流是批的特例,既然能够瓒一批数据,如果每一批的数据只有一条,相对于每一天数据都触发了计算,意味着延时是最低的 ,也就是我们所说的流计算。
针对这两种认知的不同,计算引擎设计方案一种是 Native Streaming 模式,另一种是 Micro-Batching 模式。
Native Streaming 模式就是认为批是流的特例,该概念本质上更贴切流的概念,流监控的一些消息等都是一条一条处理的。Native Streaming 模式每条数据都触发计算这种机制会最大程度的降低计算延时,Native Streaming 模式占据了流计算第一个核心能力。
Micro-Batching 模式是认为流是批的特例,流计算就是将连续不断的批计算、批数据进行持续的计算,如果批足够小,那么延时就足够小,在一定程度上,这种设计满足了百分之九十九的实时计算场景。另外百分之一是架构的原因,因为 Micro-Batching 模式在设计上就有一个瓒批的过程(对批数据进行调用计算的过程),会增加一定的延时。
Apache Flink 是 Native Streaming 模式的一个流批统一的计算模式。
总结:
从数据集和计算过程两个维度看,批计算一定是有限的数据集,一次计算一次数据结果,流计算本身的数据集可以是无限的,有限的数据集合也可以以流的方式计算,同时流计算要进行结果的不断输出,如果结果有更新也要不断的进行历史结果的更新。
具体实例:
假设有一张用户点击实现表,表中有时间戳和用户姓名,需求是进行页面的 pv 统计(进行简单的 select count(*)的一个table),对于批查询,手动执行输入即可,执行一次立即输出一个查询结果。
对于目前的 select count(*)FROM user_clicks 会输出6,因为在执行查询的手动孵化有6个点击事件,如果后面还有用户点击事件发生,该结果不会更改,如果想知道最新的结果必须再次手动触发。
如果目前该查询需求用流计算的查询模式,当第一条事件到达时就会触发一次计算,触发计算时该 count 为1,第二条事件到达时又会触发一次计算,count 为2,依此类推,每条数据到达都会触发一次计算,最终第六条数据到达时,和批的计算结果数据集一样,计算逻辑也一样时,则查询的结果和批是一样的。虽然两种计算模式不一样,但是计算结果一样。所以对用户而言,批和流他们能感知的一个是计算结果,一个是计算结果速度的延时。
对于初学者来说,直观的认识到流和批是两种计算方式和计算结果输出方式的不同以及他们最终结果一致性的相同就可以继续后面的内容。