我们进行 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. 阅读之SQL优化

    一.性能不理想的系统中除了一部分是因为应用程序的负载确实超过了服务器的实际处理能力外,更多的是因为系统存在大量的SQL语句需要优化. 为了获得稳定的执行性能,SQL语句越简单越好.对复杂的SQL语句, ...

  2. 【leetcode】1186. Maximum Subarray Sum with One Deletion

    题目如下: Given an array of integers, return the maximum sum for a non-empty subarray (contiguous elemen ...

  3. 【leetcode】Global and Local Inversions

    题目如下: We have some permutation A of [0, 1, ..., N - 1], where N is the length of A. The number of (g ...

  4. 【leetcode database】Human Traffic of Stadium

    X city built a new stadium, each day many people visit it and the stats are saved as these columns: ...

  5. 11.Linux date命令的用法

    date命令常的日常应用   修改时间 date -s “2008/05/23 19:20″ 打包文件 tar zcvf log-$(date +$F).gz /home/admin/logs 同步阿 ...

  6. 微信浏览器video播放视频踩坑

    video属性介绍 iOS的属性 playsinline On iPhone, video playsinline elements will now be allowed to play inlin ...

  7. es6新的数据类型——generator

    todo 一.Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同. 语法上,首先可以把它理解成,Generator 函数是一个状态机,封装了多个内部状态. 执行 ...

  8. mini dc(选做)

    一.题目要求 提交测试截图和码云练习项目链接,实现Linux下dc的功能,计算后缀表达式的值 二.源代码 1.MyDC类 import java.util.StringTokenizer; impor ...

  9. springboot+druid+mybatis-Plus 配置详解

    网上找了很多关于springboot+druid+mybatis-Plus的配置,遇见的很多问题 也没找到好的解决方案.折腾了好几天终于自己配置通过了. springboot的pom文件 <pa ...

  10. 【C++ STL 优先队列priority_queue】

    https://www.cnblogs.com/fzuljz/p/6171963.html