00:00
刚才给同学们嗯,演示了个小例子啊,就是跟序列相关的啊,那咱们接下来呢,就来看一看RD序列化相关的内容,第一个叫包检测啊,从计算的角度来讲啊,算子以外的代码呢,都是在driver端执行的啊,咱们刚才看到了算子里面的代码呢,都是在我们的exte端执行的,那么在我们S盖LA的函数式编程当中,就会导致算子内经常会用到算子外的数据,这样的话就形成了一种B包的效果啊,那么如果使用的算子外的数据无法序列化,就意味着无法传值给excu端执行就会发生错误,所以需要在执行任务计算之前检测B包内的对象是否可以进行序列化,这个操作我们称之为叫B包检测啊。盖LA2.12版本后,B包编译的方式发生了改变,所以它的那个代码呢,其实也有变化,咱们Spark的3.0是我们当前学习的版本,它跟之。
01:00
前的版本啊,其实源码中已经有了很大的变化了啊,包括B包检测呀,包括他的作业执行啊,其实都会有一定的变化啊,这个咱们在后面的内核的学习当中,咱们可以呃碰见了跟大家说一说啊,咱们接着往下啊,嗯。下面呢说了啊,我们序列化的方法和属性啊,那么下面呢,他举了一个例子,这个例子呢,我们可以给大家呢去看一看,他想给大家说明什么事情啊来,那这样的话跟序列化相关,那我觉得这个咱们就别放在这个operator里面了啊,咱们在这里呢,我们来创建一个包啊,咱们写上嗯,来,咱们叫序列化相关的内容啊,嗯,好,这里呢,我们写上new,创建一个skyla啊,我们的一个类,咱们写上它,咱们叫RDD,再来我们的一个序列化好了,然后点击OK,然后这里面写上一个面。行,把这些东西呢,我们参考一下,咱们拷贝过来。
02:00
好了啊,然后呢,我们再来写上一个SC点啊,我们的这个stop,嗯,行,那我们接下来咱们看一下我们的课件啊,咱们课件当中啊,他准备了一个什么呢?我们的R准备了一个R,诶好了,什么hello呀,什么Spark呀,啊他把这些呢准备了一下啊来找一下,嗯,好,他准备好了以后,他做了什么事情呢?这样的他在我们的处理过程当中啊,他构建了一个奢的对象,所以啊,咱们往下走,往下走,往下走当中啊同学们看来拷贝拷贝以后,它在这边它构建了一个我们的search的对象,这个呢,我们叫查询对象啊,咱们称之为叫查询对象,那么这个查询对象什么意思呢?就是我们想从数据源当中查询指定规则的数据,诶咱们想干这个事情用,所以说我们回过头来,咱们看课件,它里面就会有一些方法来帮助我们来查询。
03:00
数据,所以我们把这个方法呢,我们拷贝一下,拷贝拷贝以后拿过来在我们的这些地方啊,同学们看我们现在呢,把这些东西啊,都给它拿过来,把这个都去掉啊,去掉OK,保留简单一点吧,我太多的话看有点乱啊,然后呢,这个也是一样的啊,这也是一样的,诶把这个拿过来,然后呢,我们看看他想干什么啊,咱们看它里面有两个方法,一个叫get ma1,一个叫get ma2,都是要传一个RDD进来,然后呢,这个RDD呢会调用fielder,这个fielder呢,它一个采用的是匿名函数,一个采用的是外置函数,对不对,外部声明的函数,所以这个其实目的很简单,就是筛选数据嘛,看看我们RDD数据源当中的数据,有没有满足我们的查询条件的这个数据,它叫包含对吧,如果你的数据源中的数据包含了咱们指定查询的数据,那么这样的话就满足条件,数据就保留了,如果不满足,OK。
04:00
这个就不保留,对不对,所以啊,它用了两种不同的方式来实现这个功能啊,那好,我们来给大家看一看,那我们这个search侈对象啊,在咱们这里就来了,嗯,咱们写上,嗯,咱们叫做就叫search吧,等于new啊,咱们叫search,然后呢,我们写上一个小写的H吧,如果你的数据源中的数据它包含了我们的小写的H,这个数据给我留下来啊,如果你不包含我就不要了,比方说艾特硅谷,这就不包含嘛,那不包含我就不要,对不对,所以啊,咱们的search呢就有了,有了以后咱们来,咱们写上一个点,点了以后有个叫get ma1,然后呢,把RDD传进去,传进去以后大家会发现它就是调用了它的field,然后返回一个新的RDD,好,那咱们别的不说了,那我们就直接点叫collect。好,然后呢,点我们叫for it,给它来一个print,哎,就这么简单啊,只是说他做了一个封装,封装成了一个叫search的对象,好,那我们现在运行。
05:04
运行,看看我们的结果啊,看一看我们的运行结果,是不是我们预想的这个at硅谷没有出现啊,123能够出现就够了,嗯。诶,你会发现怎么了,同学们好像没过去啊,他报错了,报了一个什么错误呢?你看看熟不熟悉task not so liable对不对,叫做任务没有序列化,诶,那我们接着往下,那你这个肯定看不出来嘛,还得往下看,具体的他就说了,我们not legable exception是那个search对象,它没有序列化,诶我这里看看啊,咱们的这个地方大家看一下,咱们这里是RDD传进来有个叫field,这个field就是算子吧,这个算子的外部,我们这没有外部代码,对不对,然后呢,我们的这个叫it met是我们的内部操作就在这了。那这个操作就是把个query拿过来。
06:00
这个query是个字符串啊。对不对,那所以我就感觉好像这里没有用到这个search呀,这是一个我们的类的构造参数吧,构造参数它这个参数它这个string啊,那我这个地方问你是否包含,那包含它的情况下这个。周串,那本身就序列化了的呀,那你的这地方怎么会提示我说我们的这个search没有序列化呢,那我就不明白了,所以啊,我先不管那么多,我先按照他的这种说法呢,我先给他来序列化一下,我们试一试啊看看如果我加上了以后他就成功了,那就说明问题他就在这儿,我们来看看什么原因,嗯。所以啊,我现在不知道发生什么事情,在我看来呢,咱们的get ma1你的,那这个就是我算子的内部嘛,那么你的算子内部确实用到了个query,但这个query好像跟这个search没什么关系啊,对不对,它就是个参数,而且是字串类型的,跟它有啥关系?
07:01
所以啊,我们觉得应该不会有问题,可是你发现当我们增加了这句话之后,代码就执行通过了,说明啊,确实就跟它有关,那么原因在哪呢?原因告诉大家很简单,就在我们史该了语法当中,我们类啊,咱们说一下类的构造参数,它其实它是什么呢?它是我们类的属性。所以啊,你会发现啊,咱们类的构造参数这个query其实是类的属性。这个事儿你能不能明白?如果你不明白这个事情,那你肯定就不知道他为什么会出错了啊,你只能说哎,我加一句话就解决了,那你不知道为什么啊,那为什么是类的属性呢?我们回过头来大家看啊,我们现在打开,诶咱们现在咱们打开这个叫target,这个target我们去找一找啊,咱们点一下点一下嗯,打开打开打开以后咱们的Spark,然后呢,这边有一个叫做RDD,有一个叫做它,然后把这个呢,我们给它反编译啊来反编译,反编译以后大家看一下咱们刚才的那个search。
08:12
咱们这里面不有个叫做search吗?我们找一下,在这儿呢,你会发现那个query是不是它的属性,只不过它是个私有属性,你外部是看不到的吗?那么你再去判断是否包含的时候,它会怎么办?调用this.query所以呀,这个地方它省略了一个什么叫this.query是这么个情况,所以这个this不是当前的search对象吗?那是不是就跟search有关系了,所以类的构造参数其实是类的属性啊,那么我们的构造参数它需要什么呢?进行我们的B包啊,咱们的检测其实就等同于就等同于我们的。类啊,它进行我们的B包检测,所以那你肯定不对嘛,啊,他没有序列化对不对,所以刚才的第一种情况它就爆桌了,那然后呢,第二种情况,我们加上序列化之后,它就没事儿了,对不对,这个咱们演示过了啊好,那这个MAX1啊,咱们就知道哦,原来是这么回事儿啊,嗯,我们的这个属性对吧,这个属性它会涉及到类对象的一个序列化问题,那好,我们再来,咱们search,嗯,咱们再来,咱们叫做点点什么呢?我们叫get me,你把RDD传进去,传进去以后把这个拿过来,嗯。
09:32
好了,那你这么写完了以后,咱们再来往下看啊,咱们来往下看,往下看以后大家看一下这个地方。大家看一下这个地方会不会出现问题,其实你会发现也一样,它出现问题,为什么?因为我们的get met2,大家想一想,咱们的这个query用的是不是也是它,所以啊,也就意味着如果这个类不序列化的话,你的M2也依然出现问题啊,所以我们再来运行这个问题,我们预想就能想得到了,嗯,它是序列化的问题啊。
10:09
所以咱们看一看。好了,诶确实出现问题了,那怎么办呀,很简单,你把这个地方加上一个什么混入特值是不是就OK了,或者你加上一个case是不是也就解决了,那也就解决了,但是这种一种解决方案啊,咱们说一下就行了,嗯,还有还有一种解决方案,什么解决方案呢?你这样。大家看一下,你这么写叫做S等于query,然后呢,你把这个S逆方这这种方式其实是能够解决的啊,所以来我们运行一下,运行以后看结果啊,这个时候你会发现我的这个search呢,并没有序列化,只不过呢,我在这边把query复制给了1S啊,你看看现在会不会出现那个。任务没有序列化的问题,好像没有了吧,那这个原因何在啊?原因就在于我们记住啊,这个是RDD的方法,咱们称之为叫算子,这个代码是不是在driver端?
11:09
而这个代码逻辑它会运行在我们的excucuor端,所以它所引用的S其实就是引用的这个S,这个S什么类型字符串,类型字符串能不能够序列化,那当然能了,对不对?而且这个S我问你它跟我们这个search有关系吗?没有,因为这个S明显就是这个方法的一个局部的变量嘛,所以要改变它的生命周期,形成B包。那么所以说它。不需要,我们这个类怎么怎么办,它是不需要的,所以啊,在我们写代码的时候,一旦出现类似于这些错误的话,我们要有一个分析的过程啊,虽然说解决起来很容易,为什么呢?当你看到那个错误信息以后,解决起来非常容易,但是我们一定要明白它的原理是什么样子的好不好?同学们,我们要去研究它一下啊,不要只看结果,那没有任何的意义,你下回可能还会出现同样的错误的。
我来说两句