00:00
到目前为止,我们已经了解了一段flink代码当中主要要做的几个步骤,首先我们应该要创建一个执行环境,然后呢,基于这个执行环境,我们就可以去source,然后读取数据源,得到一个data stream。接下来呢,基于data stream就可以去调用各种方法进行转换处理计算,最终我们就可以得到自己想要的计算结果。啊,那其实我们知道flink是一个大数据的处理引擎,它处理得到的结果其实最后肯定是要为外部应用提供支持的,你不管是直接拿来看也好,还是说作为别的处理计算的进一步提供数据基础也好,我们都应该把它要落盘存放到某个存储系统里边,这样的话才能够被外部系统调用。所以接下来我们就到了最后一步,那就是输出这一步操作啊,那输出这一步任务呢,在flink里边是整体把它叫做think啊,这个单词我们知道它有下沉的意思,这个其实非常的直观,因为我们说当前处理的是数据流嘛,那就像水流一样,它是从高处流到低处,那高处这里呢。
01:14
那就是有一个源头,这个叫做S。读取进来之后,哎,那接下来我们做一系列的转换处理计算。这些我们都可以把它看成是中间的流动的管道,那最后呢,当然就要下沉到某一个池子里边,或者某一个槽里面去啊,那这个下沉到的地方,我们就把它叫做sink啊,所以有些资料里边,我们说是管最后这一步操作叫做数据会啊,对应的数据源,这个叫做数据会,这个也是可以理解的,我们在这里呢,就统一把它叫做输出算子或者叫think算子就可以了,这就是我们要把处理的结果向外部进行输出的一步任务。其实如果我们自己去构思的话,我们会想到啊,朝外部系统某个文件,或者说某个数据库里边去写入数据,这个很复杂吗?
02:08
其实不复杂,非常简单,只要我们比方说啊,建立一个到数据库的连接,然后接下来我们得到结果不就可以直接往里边写入了吗?调用接口就可以了吧,所以在很多大数据框架里面,其实对于这一步操作是没有单独的定义的,诶都是你做完处理结果之后,你自己去定义啊,想建立连接啊,想写写到哪儿就写到哪儿就完了,但是弗link不太一样啊,弗link其实也可以做到这一点啊,就像之前我们说的啊,在自定义。函数类里边我们可以去实现一个负函数类reach方式,那么在这个reach方式里边,它有运行上下文,还可以有open和close生命周期方法,我们当时说过一个比较好的最佳实践就是可以在open生命周期里边去做一些创建到数据库的连接操作,啊,直接建立连接,然后呢,诶,那我们就可以在后边的处理map或者Fla map这一步操作,数据来了之后,做完转换计算之后,直接向数据库进行一个写入了,那最后在close里边去关闭连接,做一些清理工作就可以了,所以这种操作其实是完全没有问题的,我们完全可以实现处理结果向外部系统的写入。
03:22
但是对于flink来说呢,它其实能做到这一点,但是不推荐我们这么做,为什么呢?啊,那就是因为当前我们是一个实时的流处理系统,在这个处理的过程当中,对于整个系统的稳定性和容错性要求是非常非常高的,诶那我们想啊,我们这里在源源不断的处理数据,那中间假如说某一个时刻出然出现故障挂掉怎么办呢?诶,那我们知道啊,我们可以去保存一些当前的临时状态,给它存盘,然后再把它恢复出来不就可以了吗?诶,那这里就涉及到另外一个问题,那假如说你之前已经有写入到外部的数据,或者说正有写了一半的数据,那又应该怎么办呢?
04:05
所以我们会发现啊,假如说我们不去系统性的考虑这些问题的话,那所有的这些事情就要我们自己去实现,自己去处理了。啊,Flink考虑到了这一点,所以在flink的架构当中,他专门在程序的最后一步加入了一步thinkink操作,他在整个架构上帮我们把向外部系统的输出这步操作管理起来了,给我们提供了结果正确性、一致性的保障。如果在代码里边去实现的话,其实也非常简单啊,你像我们这里得到了一个data stream之后。我们这里可以调用一个ADD的sin方法,诶我们看到之前基于enna可以调用一个a source,那就是创建一个原算子,那现在呢,可以调用at think,就可以创建一个输出算子,那ADD source里边通用的传入的是一个s function式,那现在呢,At think当然传入的就是一个think function了,那think function我们看到这里也是一个Java接口,里边它最关键的一个抽象方法叫做invoke。
05:11
啊入我们知道有唤醒的意思,所以它主要的作用就是什么呢?啊,就是唤醒我们当前数据跟外部系统的连接,我们要去写入数据了啊,那当前的输入的参数当然就是我们要写入的数据,它不需要有任何的返回,只要输出写入就可以了。当然我们会看到invoke还有一个重载的方法啊,它里边可以传入一个当前的上下文啊,一个context,这里边就可以有更多的信息,我们可以获取到时间相关的信息。好,这就是关于think function的一个基本的用法。那其实前面我们看到的这个print最后打印,它其实也是一个特殊的输出,我们看到啊当前的print,它最后什么呢?返回的也是一个data stream s,但它本质上调用的是什么呢?调用了stream的点print方法,我们可以继续追进去看看源码里面的实现。
06:07
我们看到他其实就是自己去new创建了一个print think function,然后去做了一个ADD think操作,把当前的这个function直接作为参数传进来了,那自然我们就想到了这个print think function是什么呢?它就是一个rich think function啊,那这个rich think function当然就是一般的think function的一个复函数的版本了啊,复函数类的版本,Rich版本,所以在这个rich think function里边不光有invo方法,还有open和close生命周期方法,还可以调用运行时的上下文,可以得到更多的东西,那所以这就是关于我们当前think在代码当中使用的一个基本架构啊,那当然了,我们可能会想到啊,那要这么说的话,我们想要向外部系统写入的时候,是不是就得自己ADD think,然后去实现对应的think方式了呢?啊,原则上是这样的,但是其实没有那么麻烦。因为既然link框。
07:08
框架里边给我们构建了这样一个接口,那自然弗link就会帮我们实现很多预定一好的一些连接工具啊,那所以我们可以看到啊,这是flink官网上面列出来的,目前这个01:13版本已经支持的第三方系统的连接器,这里边有很多各种各样的外部数据存储工具,或者是大数据组件啊,都可以跟flink连接起来啊,这里整体来讲呢,可以分成两大类啊,一大类呢,就是像卡夫卡啊,还有像这个rabbit MQ啊这样的一些流式通信的组件。流式系统跟flink我们知道啊,本来就是都是处理数据流嘛,那显然就是非常的匹配啊,他们可以实现完美的对接,所以后边我们看到SS这是表示卡夫卡可以作为当前flink的数据源啊,可以ADDS的时候连接到卡夫卡去读取数据,也可以ADD think的时候连接到卡夫卡去向卡夫卡写入数据啊,所以就是既可以作为数据源,又可以作为输出。
08:14
同样rabbit MQ也是这样,那另外还有一大类,比方说啊,像我们比较熟悉的file system啊,这是文件系统啊,啊,那比方说是包含了这个哈豆腐就是hfs啊,这样分布式文件系统都是包含在里边的,那另外像这个elastic search ES啊,非常著名的这个大数据组件,那像这些存储系统,他们就不是一个常规的流逝系统了,他们只是作为一个数据存储的空间来使用啊,或者说查询的一个工具来使用的话,我们就只能往里边写入,不能去直接读取数据流,所以我们看到他们的支持就是只有think,只有往里边写入数据的时候可以去提供啊。另外还有JDBC啊,那就是我们知道啊,像这个MYQ啊,Post graq Oracle这些常规的业务数据库啊,都可以进行写入操作了啊,当然了,像有一些比较特殊,就是你像这个Twitter的stream API,它本身就是一个流式的API接口,所以呢,它是只能作为。
09:14
数据源去读取,它是不能去写入的啊啊啊,那所以这就是官方给我们列出来目前已经支持的一些连接器。那我们会发现这也不是所有的常用的工具都能够连得上啊,那假如说没有了怎么办呢?啊,另外还有一个备选,那就是。阿帕奇hi这个项目,它主要就是用来给sparklink这样的大数据处理框架提供扩展支持的,那么它呢,里边就实现了一些其他的第三方系统跟flink的连接器,比如说像flu阿卡等等等等。所以整体来讲,想要把flink处理好的数据写入到外部系统的时候,那第一选择当然是使用flink官方给我们提供的连接器,假如说没有官方连接器的话,那么啊,就使用。
10:05
把here给我们提供了连接器,那如果所有的连接器都没有现成的提供怎么办呢?当然我们也可以到网上去找一些别人实现好的资源啊,那如果都没有的话,那就只好去自定义实现了啊,就是我们说的啊,ADD think,然后自己去写那个think function自己去实现一个。这就是我们所说的连接到外部系统的流程和方法。
我来说两句