RDD(九)——序列化问题
在实际开发中我们往往需要自己定义一些对于RDD的操作,那么此时需要考虑的主要问题是,初始化工作是在Driver端进行的,而实际运行程序是在Executor端进行的,这就涉及到了跨进程通信,是需要序列化的。
传递一个方法
import org.apache.spark.rdd.RDD
class Search(query:String) {
//过滤出包含字符串的数据
def isMatch(s: String): Boolean = {
s.contains(query)
}
//过滤出包含字符串的RDD
def getMatch1 (rdd: RDD[String]): RDD[String] = {
rdd.filter(isMatch)
}
//过滤出包含字符串的RDD
def getMatche2(rdd: RDD[String]): RDD[String] = {
rdd.filter(x => x.contains(query))
}
}
创建Spark主程序
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext} object SeriTest { def main(args: Array[String]): Unit = { //1.初始化配置信息及SparkContext
val sparkConf: SparkConf = new SparkConf().setAppName("WordCount").setMaster("local[*]")
val sc = new SparkContext(sparkConf) //2.创建一个RDD
val rdd: RDD[String] = sc.parallelize(Array("hadoop", "spark", "hive", "atguigu")) //3.创建一个Search对象
val search = new Search("h") //4.运用第一个过滤函数并打印结果
val match1: RDD[String] = search.getMatch1(rdd)
match1.collect().foreach(println)
}
}
运行程序
报错:java.io.NotSerializableException: Search;
在这个方法中所调用的方法isMatch()是定义在Search这个类中的,实际上调用的是this. isMatch(),this表示Search这个类的对象,程序在运行过程中需要将Search对象序列化以后传递到Executor端。
解决方案:
使类继承scala.Serializable即可。告诉“它们”:Search对象是可以被序列化的
class Search(query:String) extends Serializable {
问题解决,打印:
hadoop
hive
传递一个属性
创建spark主程序
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext} object SeriTest { def main(args: Array[String]): Unit = { //1.初始化配置信息及SparkContext
val sparkConf: SparkConf = new SparkConf().setAppName("WordCount").setMaster("local[*]")
val sc = new SparkContext(sparkConf) //2.创建一个RDD
val rdd: RDD[String] = sc.parallelize(Array("hadoop", "spark", "hive", "atguigu")) //3.创建一个Search对象
val search = new Search("h") val matcher2: RDD[String] = search.getMatche2(rdd)
matcher2.collect().foreach(println) }
}
运行程序,也会报同样的错误:java.io.NotSerializableException: Search;
问题说明:
//过滤出包含字符串的RDD
def getMatche2(rdd: RDD[String]): RDD[String] = {
rdd.filter(x => x.contains(query))
}
在这个方法中所调用的方法query是定义在Search这个类中的字段,实际上调用的是this. query,this表示Search这个类的对象,程序在运行过程中需要将Search对象序列化以后传递到Executor端。
解决方法同上。
补充:创建一个object,在object中定义方法,以对象名引用的方式将方法传递给各个executor,不会出现序列化问题。见博文《JdbcRDD连接MySQL 》
RDD(九)——序列化问题的更多相关文章
- JdbcRDD连接MySQL
(1)添加依赖 <dependencies> <dependency> <groupId>org.apache.spark</groupId> < ...
- spark新能优化之序列化的持久化级别
除了对多次使用的RDD进行持久化操作之外,还可以进一步优化其性能.因为很有可能,RDD的数据是持久化到内存,或者磁盘中的.那么,此时,如果内存大小不是特别充足,完全可以使用序列化的持久化级别,比如ME ...
- RDD缓存策略
Spark支持将数据集放置在集群的缓存中,以便于数据重用. Spark缓存策略对应的类: class StorageLevel private( private var useDisk_ : Bool ...
- 在Spark中使用Kryo序列化
spark序列化 对于优化<网络性能>极为重要,将RDD以序列化格式来保存减少内存占用. spark.serializer=org.apache.spark.serializer.Jav ...
- C#[Serializable]在C#中的作用-NET 中的对象序列化
为什么要使用序列化?最重要的两个原因是:将对象的状态保存在存储媒体中以便可以在以后重新创建出完全相同的副本:按值将对象从一个应用程序域发送至另一个应用程序域.例如,序列化可用于在 ASP.NET 中保 ...
- 五、RDD持久化
Spark最重要的一个功能是它可以通过各种操作(operations)持久化(或者缓存)一个集合到内存中.当你持久化一个RDD的时候,每一个节点都将参与计算的所有分区数据存储到内存中,并且这些数据可以 ...
- Spark RDD持久化、广播变量和累加器
Spark RDD持久化 RDD持久化工作原理 Spark非常重要的一个功能特性就是可以将RDD持久化在内存中.当对RDD执行持久化操作时,每个节点都会将自己操作的RDD的partition持久化到内 ...
- 【Spark调优】:RDD持久化策略
[场景] Spark对RDD执行一系列算子操作时,都会重新从头到尾计算一遍.如果中间结果RDD后续需要被被调用多次,可以显式调用 cache()和 persist(),以告知 Spark,临时保存之前 ...
- Properties-转换流-打印流-序列化和反序列化-Commons-IO工具类
一.Properties 类(java.util) 概述:Properties 是一个双列集合;Properties 属于map的特殊的孙子类;Properties 类没有泛型,propert ...
随机推荐
- 如何拖拽DIV边线并左右自适应改变大小?
//树图拉伸 jQuery(function ($){ var doc = $(document), dl = $(".side-tree" ...
- cf 478D.Santa Claus and a Palindrome
原来set,priority_queue也可以映射..涨姿势2333 比较麻烦的应该就是判断自身回文的串是选2个还是选一个吧. #include<bits/stdc++.h> #defin ...
- HBase从入门到精通系列:误删数据如何抢救?
云栖君导读:有时候我们操作数据库的时候不小心误删数据,这时候如何找回?mysql里有binlog可以帮助我们恢复数据,但是没有开binlog也没有备份就尴尬了.如果是HBase,你没有做备份误删了又如 ...
- 洛谷 P2341 [HAOI2006]受欢迎的牛|【模板】强连通分量
题目传送门 解题思路: 先求强联通分量,缩点,然后统计新图中有几个点出度为0,如果大于1个,则说明这不是一个连通图,答案即为0.否则入度为0的那个强连通分量的点数即为答案 AC代码: #include ...
- 实验吧web-易-这个看起来有点简单
看url中有id=1,明显的sql注入,这里使用手工注入不适用sqlmap,想用的话参考文章(传送门) 1.首先测试有没有sql注入漏洞, http://ctf5.shiyanbar.com/8/in ...
- 201771010123汪慧和《面向对象程序设计JAVA》第七周实验总结
一.理论部分 1.继承 如果两个类存在继承关系,则子类会自动继承父类的方法和变量,在子类中可以调用父类的方法和变量,如果想要在子类里面做一系列事情,应该放在父类无参构造器里面,在java中,只允许单继 ...
- ubuntu---【NVIDIA驱动 + CUDA 安装】不成功时的卸载方式
NVIDIA驱动 与 CUDA 安装不成功时,可以卸载,检查相关问题(配置.兼容性等),重新安装.这里记录一下,卸载方式.
- Docker MongoDB 集群搭建
简单地在Docker环境上搭建一个无认证的MongoDB集群.1.本文使用的容器集群角色 ContainerName IP:portConfig Server cfg_1 10.1.1.2:27 ...
- 冲刺期末阶段一<公文档案流转管理系统>
今天下午的四节课要求自己完成公文流转管理系统,并规定时间看个人进程,相对来说我对增删改查掌握的不彻底,对项目的逻辑框架不太熟练,所以我感觉今天的进度有点慢.有待继续学习. 完成进度:1.分步骤先理清整 ...
- h5-localStorage储存的使用
<!-- localStorage的使用: 1.存储的内容大概20mb 2.不同浏览器不能共享数据,但是在同意浏览器的不同窗口中可以共享数据 3.永久生效,他的数据是储存在硬盘上,并不会随着页面 ...