00:00
刚才我们给大家把这个stream的有状态无状态的操作呢,我们分别的演示了一下,嗯,咱们之前讲的什么map呀,Fla map就是就是一些无状态操作,那个update就是有状态操作,对不对?那么有状态操作需要设定的这个我相信大家应该没有什么问题了,那接下来呢,我们再把一些具体的方法呢给大家介绍一下,比方说无状态操作,它就有这么一个方法,咱们叫什么呢?叫transform,这个transform翻译过来呢,就叫转换,那它转换什么呢?我们这里比较特殊了,它表述的是我们可以呢,拿到它最底层的那个RDD来做操作。咱们之前学Spark的时候,不就学过RDD吗?而我这里呢,诶,如果发现呢,我们用那个啊,有些功能不好实现,我们恰恰就可以干嘛呢,用我们底层的RDD来实现这些功能啊好了,那我们现在呢,给大家来看一看,把这个咱们关掉,来咱们拷贝,拷贝以后呢,我们写上一个我们的零六啊,然后呢,放过来,咱们叫做什么呢?叫transform,咱们叫transform。
01:06
好拿过来,拿过来以后放到这边,然后呢,这边我们暂时都不要了啊,咱们都不要了,把这个去掉好去掉以后呢,我们叫SSC啊,咱们点咱们叫socket,它然后呢,我们这边写上一个叫local host,嗯,Local host,然后呢写上四个九,然后呢,接下来我们这边就写上啊,咱们叫做lines,然后接下来我们其实这个比较简单了,咱们直接这个lines点我们叫transform,这个transform你提示一下,你会发现它就是给你一个RDD,再变成一个RDD就行了,对吧,就这么个意思,所以呢,我就写上啊,咱们叫RDD,然后呢,直接变成RDD就可以,所以啊,这个方法的作用就很简单,对吧?来来,咱们叫transform啊这个方法啊方法它可以呢,将我们底层的RDD获取到啊,获取到后啊进行操作。
02:03
呃,我们说了为什么要这么做呀,是因为有的时候啊,咱们这个stream啊,它的功能啊,没有那么想象的那么强大,有些功能呢,不好实现,那么你如果能够拿到它底层RTD的话,你实现起来会更加轻松啊,是这样的。哎,老师,那我们这个transform是一种转换,把底层的RDD变成另外一个,那它返回的是什么呀,所以点点了之后咱们来VR回车,你会发现呢,有问题了,什么有问题了呢?咱们叫做new,咱们叫DS,你就等同于用了底层的RDD,但你返回的还是streamam,那你好像跟我们的这个叫做什么的点map没有什么太大区别呀,大家想想。你给我的是什么?比方说你给我的是个字符串,对吧,咱们它然后呢,我返回一个字符串,这有啥太大区别呢,你这么写完了以后VR回车对不对,你看你会发现new,咱们叫stream给他放过来。好像没什么区别吧,你的这个map可以将里面的数据元素呢,给它变成我们的什么某一个类型,比方说字符串啊,整形啊,布尔类型啊都可以,那你这难道不能变吗?你这是不是也可以变,比方说我们的RDD.map这个map s tr,然后呢,变成str,有没有问题,没有任何问题,那这个方法就感觉啊,很奇怪了,为什么呢?因为它也能实现,你的也能实现,那咱们到底用哪一个呢?按理说是应该哪个方便用哪个吧,那肯定是用它嘛,你这个感觉没有那么方便,对不对?所以啊,咱们这个transform呀,它不能够在任何地方都能使用,所以它一一定会有一个应用场景的问题。
03:37
那它会有什么样的应用场景呢?这个我们给大家介绍一下,首先呀,咱把代码补全它,你看看它有什么区别啊来。我们现在呢,拿到的就是我们一行数据,咱们就叫date吧,或者说我们这里啊,同看啊,我们这里呢,给它折个行,折行以后我们叫做date,然后呢放过来,然后干嘛呢?我们就叫做date,就这么写就可以了,好,那咱们把这个呢,再给它拿过来啊,把这个呢去掉,去掉以后呢,给它换个行,咱们叫RDDRDD,然后呢,放过来,放过来以后RDD点我们的map,然后括号,括号以后呢,我们写上G,然后呢给它来一个咱们拿过来叫string,所以啊,你会发现我们的代码就这么写的,这个用的是transform,这个用的是map,好像感觉这个更简单一些,而这个更复杂一些,对不对?那我们说了他们的区别在哪?区别啊,给大家说一下,其实就在于他写代码的位置。
04:35
这句话怎么理解呢?比方说,同学们来。我在这儿写上一个code代码,你们觉得它在哪执行,那如果我的这个代码啊,哎,在这儿,那好,那我问同学们,咱们的这个地方如果写代码的话,会在哪执行,如果在这样写代码的话,它会在哪执行?OK,我们再回过头来,咱们到这边,我们现在这个地方写代码在哪执行,我在这儿写代码在哪执行?你从这个位置你就发现了,我们的map好像只有两个地方能写代码,而我们的transform有三个地方能写代码,对不对?
05:13
诶,那么有什么区别呢?咱们对比一下,首先第一个咱们的map,它这个东西啊,在我们的方法之外,那这个不用说了,肯定是在driver端,为什么呢?因为你都没有在我们的方法逻辑里面去使用,所以它肯定是在我们的driver端,对不对,哎,就是这样。好,那我们再来往下看,那这样写代码到底在哪儿呢?其实呀,我们点这个map点一下点点完以后你会发现你的这个逻辑操作被他传到了这个位置,对不对?那好,我们点这个叫map的STEM,咱们点点完以后你会发现这个叫map function,这个map function会在计算的时候干嘛呀,用起来,而这个计算的时候用起来大家会发现怎么了,它是有个RDD的。所以它的底层啊,这个方法其实是被RDD执行的,所以那就意味着我们的这段逻辑是在RDD里面执行的,那么RDD里面执行的话,大家就应该知道它真正执行的位置是叫execuor啊,咱们叫execuor端,所以这个如果你能明白就好办了,为什么呢?因为driver端是要向e qor端传东西的吧,好,那我们回过头来,那不用说了,那这个肯定也是我们的driver端,对不对,它也是我们的driver端。
06:29
而我们的这个那不用说了,RDD,那这个肯定就是我们的excute端嘛,所以我们的excute端啊,就是这样的,好,那么就剩下一个地方了,这个地方它是在哪一块执行的。有driver,有execcuor,它在哪执行啊,我们讲过了,在我们算子之外的逻辑都是在哪执行的,在driver端对不对,哎,就是这样,所以啊,他是在driver端执行的,但是我们有的同学可能就会有疑问,说老师你看诶,这也能写driver端的代码,这也能写driver端呢,那我直接合在一块儿来写不就完了吗?诶不一样,它哪不一样呢?咱们这个RDD,它可不是说一直都有。
07:12
它是一个采集周期产生一个,一个采集周期产生一个,就意味着这个RDD是源源不断的过来的。那么这地方的代码就会什么周期性的执行,所以啊,它这里面该干嘛呢?写上咱们叫做周期性执行,你像咱们这个地方叫做driver,它其实只会走一遍,当我们论方法执行的时候,它会走一遍对不对?而我们这个代码呢,它由于分布式的计算,它要看你的计算节点,它的任务的数量对不对,所以啊,这个会执行多变,而我们这个地方就是,诶,一个采集周期,一个RDD,一个RDB就会执行一遍,所以啊,它是周期性的执行,而我们下面的这个driver和exor呢,它其实啊,他们就跟我们那个之前学RTD是一样的,它就不涉及到这个周期性执行的概念。
08:02
那为什么要周期性执行啊,是因为有些数据呢,我们需要周期性的更新呢,或者说做一些判断呢,诶必须要去用它,所以这个时候用这个transform是一个好的选择,所以啊,咱们这个transform呢,其实它会有两种情况我们用的比较多,第一种是什么呢?就是我们的stream啊,Stream它的功能啊,不完善的时候,不完善就是有些功能啊没有,还有呢,什么呢,功能不完善啊来,然后呢,再来我们写上二,第二什么呢,就是我们需要。我们的这个啊,需要RDD啊,或者说需要我们的代码,它周期性啊的执行,哎,所以基于这两个原因,我们会用这个transform,如果你说了我这个功能啊,你也有,我也有,那就不需要用它了,比方说咱们这个map吧,这个map你能做到,我也能做到,对不对?那何必再写一遍这样的RDD的操作呢?没有必要啊,它的底层都帮你封装好了,所以啊,我们需要考虑这样的事情啊,所以它的位置非常的重要啊,同学们,好了,这个咱们说到这儿。
我来说两句