我们进行 Spark 进行编程的时候,初始化工作是在driver端完成的,而实际的运行程序是在executor端进行,所以就涉及到了进程间的通讯,数据是需要序列化的

1、传递函数

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD object SerDemo {
def main(args: Array[String]): Unit = {
val conf: SparkConf = new SparkConf().setAppName("SerDemo").setMaster("local[*]")
val sc = new SparkContext(conf)
val rdd: RDD[String] = sc.parallelize(Array("hello world", "hello h", "h", "hahah"), 2)
val searcher = new Searcher("hello")
val result: RDD[String] = searcher.getMatchedRDD1(rdd)
result.collect.foreach(println)
}
}
//需求: 在 RDD 中查找出来包含 query 子字符串的元素 // query 为需要查找的子字符串
class Searcher(val query: String){
// 判断 s 中是否包括子字符串 query
def isMatch(s : String) ={
s.contains(query)
}
// 过滤出包含 query字符串的字符串组成的新的 RDD
def getMatchedRDD1(rdd: RDD[String]) ={
rdd.filter(isMatch) //
}
}

说明:

(1)直接运行程序会报错:没有初始化。因为rdd.filter(isMatch)用到了对象this的方法isMatch,所以对象this需要序列化才能把对象从driver发送到executor

(2)解决方法:让 Searcher 类实现序列化接口:Serializable

// query 为需要查找的子字符串
class Searcher(val query: String) extends Serializable{
// 判断 s 中是否包括子字符串 query
def isMatch(s : String) ={
s.contains(query)
}
// 过滤出包含 query字符串的字符串组成的新的 RDD
def getMatchedRDD1(rdd: RDD[String]) ={
rdd.filter(isMatch) //
}
}

2、传递变量

// query 为需要查找的子字符串
class Searcher(val query: String){
// 过滤出包含 query字符串的字符串组成的新的 RDD
def getMatchedRDD2(rdd: RDD[String]) ={
rdd.filter(_.contains(query))
}
}

说明:

(1)这次没有传递函数, 而是传递了一个属性过去. 仍然会报错没有序列化. 因为this仍然没有序列化属性query也是属于this

(2)解决方法1:让类实现序列化接口:Serializable

(3)解决方法2:传递局部变量而不是属性

// query 为需要查找的子字符串
class Searcher(val query: String){
// 过滤出包含 query字符串的字符串组成的新的 RDD
def getMatchedRDD2(rdd: RDD[String]) ={
var q = query
rdd.filter(_.contains(q))
}
}

3、kryo序列化框架

Java 的序列化比较重, 能够序列化任何的类. 比较灵活,但是相当的慢, 并且序列化后对象的提交也比较大.

Spark 处于性能的考虑, 支持另外一种序列化机制: kryo (2.0开始支持). kryo 比较快和简洁.(速度是Serializable的10倍). 想获取更好的性能应该使用 kryo 来序列化.

2.0开始, Spark 内部已经在使用 kryo 序列化机制: 当 RDD 在 Shuffle数据的时候, 简单数据类型, 简单数据类型的数组和字符串类型已经在使用 kryo 来序列化.

有一点需要注意的是: 即使使用 kryo 序列化, 也要继承 Serializable 接口.

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD object SerDemo {
def main(args: Array[String]): Unit = {
val conf: SparkConf = new SparkConf()
.setAppName("SerDemo")
.setMaster("local[*]")
// 替换默认的序列化机制
.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
// 注册需要使用 kryo 序列化的自定义类
.registerKryoClasses(Array(classOf[Searcher]))
val sc = new SparkContext(conf)
val rdd: RDD[String] = sc.parallelize(Array("hello world", "hello h", "h", "h"), 2)
val searcher = new Searcher("hello")
val result: RDD[String] = searcher.getMatchedRDD1(rdd)
result.collect.foreach(println)
}
} class Searcher(val query: String) extends Serializable{
// 判断 s 中是否包括子字符串 query
def isMatch(s: String) = {
s.contains(query)
}
// 过滤出包含 query字符串的字符串组成的新的 RDD
def getMatchedRDD1(rdd: RDD[String]) = {
rdd.filter(isMatch) //
} // 过滤出包含 query字符串的字符串组成的新的 RDD
def getMatchedRDD2(rdd: RDD[String]) = {
val q = query
rdd.filter(_.contains(q))
}
}

4、以上extends Serializable都可以使用样例类

Spark-Core RDD中函数(变量)传递的更多相关文章

  1. C++中函数变量布局小结

    把布局作为一种信仰(Layout as Religion).                                                                       ...

  2. 用闭包解决 js 循环中函数变量暂存问题

    需求:有一个数组,根据数组的值渲染对应的数字div,单击对应的div 在控制台打印对应的数字.如点击1,控制台打印1. 问题: 不管点击哪个值 打出来都是4 代码如下 <!DOCTYPE htm ...

  3. JS中函数参数值传递和引用传递

    也许大家对于函数的参数都不会太在意,简单来说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样.深入研究,你会发现其实没那么简单,这个传参是要分俩种情况(其实这是个错误的说法 ...

  4. Java中的变量传递机制以及JS中的参数传递机制

    JAVA: 传递基本类型是 就是基本的值传递 不会影响值本身. package com.wuqi.p1; public class ValuePassTest { public static void ...

  5. Spark Core知识点复习-1

    Day1111 Spark任务调度 Spark几个重要组件 Spark Core RDD的概念和特性 生成RDD的两种类型 RDD算子的两种类型 算子练习 分区 RDD的依赖关系 DAG:有向无环图 ...

  6. 【pytest】使用parametrize将参数化变量传递到fixture

    分享一个关于在pytest中,如何将测试用例文件中的变量传递到fixture函数. 一.交代应用场景 目前组内的项目,在根目录下是有一个conftest.py文件的,这里有个生成api token的f ...

  7. 通过transmittable-thread-local源码理解线程池线程本地变量传递的原理

    前提 最近一两个月花了很大的功夫做UCloud服务和中间件迁移到阿里云的工作,没什么空闲时间撸文.想起很早之前写过ThreadLocal的源码分析相关文章,里面提到了ThreadLocal存在一个不能 ...

  8. Spark学习笔记之RDD中的Transformation和Action函数

    总算可以开始写第一篇技术博客了,就从学习Spark开始吧.之前阅读了很多关于Spark的文章,对Spark的工作机制及编程模型有了一定了解,下面把Spark中对RDD的常用操作函数做一下总结,以pys ...

  9. Spark RDD中的aggregate函数

    转载自:http://blog.csdn.net/qingyang0320/article/details/51603243 针对Spark的RDD,API中有一个aggregate函数,本人理解起来 ...

随机推荐

  1. 动态树(Link-Cut-Tree)简单总结(指针版本)

    Link-Cut-Tree(动态树 LCT) 1.定义 1. 偏爱子节点: 一颗子树内最后访问的点若在该子树根节点 X 的某个儿子节点 P 的子树中,则称 P 为 X 的偏爱子节点. 偏爱边:连向偏爱 ...

  2. c++ copy和operator =

    目录(?)[+] 构造函数 拷贝构造函数 赋值函数   C++中一般创建对象,拷贝或赋值的方式有构造函数,拷贝构造函数,赋值函数这三种方法.下面就详细比较下三者之间的区别以及它们的具体实现 1.构造函 ...

  3. layui静态表格固定td宽度,table固定td宽度

    正在做一个项目,要求数据表的列是不固定的,有可能是有10列,有可能是20列,第一列宽度要固定,然后我怎么设置都没有用, 这个问题困扰了我三天,后来终于百度到了, 这个博客: https://www.c ...

  4. ansible-乱

    工作机制:ssh 无客户端 工作方式: 1,CMDB 2,公有云私有云API 3,使用ad-hoc 4,ansible-playbook ansible 执行命令,底层调用传输连接模块,将命令或文件传 ...

  5. Linux基础教程 linux下cat 命令使用详解

    cat命令的用途是连接文件或标准输入并打印.这个命令常用来显示文件内容,或者将几个文件连接起来显示,或者从标准输入读取内容并显示,它常与重定向符号配合使用. 1.命令格式: cat [选项] [文件] ...

  6. 【BZOJ5249】IIIDX(贪心,线段树)

    题意: 思路:赛季结束之前余总推荐的一道好题,不愧是余总 From https://www.cnblogs.com/suika/p/8748115.html 简略的说就是在预留足够多的位置的前提下贪心 ...

  7. HDU 1312 Red and Black(bfs,dfs均可,个人倾向bfs)

    题目代号:HDU 1312 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1312 Red and Black Time Limit: 2000/100 ...

  8. vue 使用 axios 时 post 请求方法传参无法发送至后台

    axios 时 post 请求方法传参无法发送至后台报错如下 Response to preflight request doesn't pass access control check: No ' ...

  9. SSM整合之---环境搭建

    SSM整合---环境搭建 l  查询所有用户的信息,保存用户信息 1.pom.xml配置项目所需的jar包 <dependencies> <dependency> <gr ...

  10. 大哥带我们的mysql注入 基于时间的盲注

    ?id= and ,,sleep()) ?id= and ,,sleep()) if语句/if()函数 在基于时间型SQL盲注中,我们经常使用条件语句来判断我们的操作是否正确: ?id= and = ...