spark分布式算子里面异步处理
算子:Opera(操作)
主要原因是RDD的方法和scala集合对象的方法不一样,scala集合对象的方法都是在同一个节点的内存中完成的;而RDD的方法可以将计算逻辑发送到Execu端(分布式节点)执行的。所以为了区分scala集合的方法和RDD的方法,所以才把RDD的方法叫做算子
RDD方法外部的操作都是在Driver端执行的,而方法的内部的逻辑代码是在Execu端执行的
分区内的数据都是有序的
p
案例说明
为什么会提示没有序列化这个错误?
首先foreach这个算子内部进行了user.age + num操作,而RDD方法的内部逻辑代码是在Exe
cu端执行的,val user = new User()这段代码是在RDD方法的外部,是在Driver端执行的。所以Execu端没有User这个对象,这需要到Driver端去拉去,拉去的过程中需要进行网络传输,而网络传输是不能进行对象的传输,只能进行asccii码的传输,所以User这个类需要序列化操作
下面是图解:
正确代码:
或者把User类变成一个样例类
case class User ( ) { val age : Int = 30 }
样例类会自动生成很多的方法,其中也会自动实现可序列化的接口
比如会自动生成:ap方法、toString方法、equals方法、hashCode方法、copy方法等
1.判断是否存在闭包
2.如果是闭包操作,那么会对数据进行序列化检查
(1)首先什么是闭包?
只要是函数式编程都会有闭包操作
首先闭包是有一个生命周期的概念,一个函数使用了外部的变量,改变这个变量的生命周期,将变量包含到函数的内部,形成闭合的环境,这个环境称之为闭包环境,简称闭包
(2)案例引入
输出为:300
代码解析:
①当代码val funObj = outer()执行完的时候,上面的函数outer()已经执行完结束了,为什么说执行完了,如果没执行完,就不会返回一个结果给funObj
②而Scala的函数本质是Ja中的方法,而Ja中方法结束后那么方法中的局部变量就会弹栈
③所以上面outer()函数结束后局部变量a 就会弹栈,而outer()返回结果是一个函数对象inner,下面就执行了funObj()相当于执行该函数(加了个括号相当于函数调用)
④在val funObj = outer()执行完以后 funObj()刚执行,而inner()函数里用到了 outer()函数中的局部变量a,但是局部变量a 在outer()函数结束后就已经弹栈不存在了,最后运行的时候并没有报错,可以输出300,那这到底是为什么?
原因:
因为这里就涉及到了函数闭包,当一个函数使用了外部的变量,改变这个变量的生命周期,将变量包含到函数的内部,形成闭合的环境,这个环境称之为闭包环境,简称闭包
案例深入:根据第一个案例进行小小改动
代码解析:
scala不是内部或外部命令因为RDD算子里面传递的函数为匿名函数,RDD算子在引入了外部的变量时,外部的变量user(Driver端)就会传入到foreach算子内部(Execu端),那么就会改变user的生命周期,形成闭包。所以说匿名函数就会用到闭包操作,那么就会有闭包检测功能。从而发现user没有序列化,所以说根本不需要执行foreach中的代码,就会检测出错误,而这个功能称为闭包检测功能
注意:所有的匿名函数都有闭包
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论