一、序列化
实现序列化:extends Serializable
首先,任务提交的过程,需要先在Driver端进行初始化,算子的函数需要的Executor端进行计算。
Driver端的计算过程需要传给Executor端进行实际的计算,就需要发生网络io,
而Executor端的计算需要在jvm里进行计算,
Driver端传过来的对象在jvm中是以字节表示
所以,在节点传输对象的时候,就需要将所传输的对象进行序列化
所以会发生这样的场景:当一个对象从Driver端传输到Executor端的时候就需要进行序列化
通过实例总结:
前面两个方法的调用都需要将this对象进行传输给Executor,此时就需要进行序列化
而最后一个方法可以发现用的是局部变量,此时不是当前类了,就不需要进行序列化
在给算子传函数时,一定要注意,尽量少的传入对象,可以减少网络io
package com.qf.gp1921.day09
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD
class SearchFunction (val query: String) extends Serializable
{
// 第一个方法判断输入的字符串是否存在query
def isMatch(s: String): Boolean = {
s.contains(query)
}
def getMatchFuncRef(rdd: RDD[String]): RDD[String] = {
// 在这儿,调用isMatch方法,相当于this.isMatch, 需要将this对象传给Executor
rdd.filter(this.isMatch)
}
def getMatchFieldRef(rdd: RDD[String]): RDD[String] = {
// 在这儿,相当于将this传给Executor
rdd.filter(_.contains(this.query))
}
def getMatchNoRef(rdd: RDD[String]): RDD[String] = {//这个函数不需要序列化条件
val _query = query
rdd.filter(_.contains(_query))
}
}
object SearchFunction {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("SearchFunction").setMaster("local[2]")
val sc = new SparkContext(conf)
val rdd = sc.parallelize(List("hello java", "hello scala"))
val sf = new SearchFunction("java")
// sf.getMatchFuncRef(rdd)
// sf.getMatchFieldRef(rdd)
sf.getMatchNoRef(rdd)
}
}