Spark:将RDD[List[String,List[Person]]]中的List[Person]通过spark api保存为hdfs文件时一直出现not serializable task,没办法找到"spark自定义Kryo序列化输入输出API"
声明:本文转自《在Spark中自定义Kryo序列化输入输出API》
在Spark中内置支持两种系列化格式:(1)、Java serialization;(2)、Kryo serialization。在默认情况下,Spark使用的是Java的ObjectOutputStream系列化框架,它支持所有继承java.io.Serializable的类系列化,虽然Java系列化非常灵活,但是它的性能不佳。然而我们可以使用Kryo 库来系列化,它相比Java serialization系列化高效,速度很快(通常比Java快10x),但是它不支持所有的系列化对象,而且要求用户注册类。
在Spark中,使用Kryo系列化比使用Java系列化更明智。在shuffling和caching大量数据的情况下,使用 Kryo系列化就变得非常重要。
虽然Kryo支持对RDD的cache和shuffle,但是在Spark中不是内置就显示提供使用Kryo将数据系列化到磁盘中的输入输出API,RDD中的saveAsObjectFile和SparkContext中的objectFile方法仅仅支持使用Java系列化。所以如果我们可以使用Kryo系列化将会变得很棒!
实现代码:
import java.sql.Timestamp
import java.text.SimpleDateFormat
import java.util.Calendar import org.apache.spark.api.java.JavaPairRDD
import org.apache.spark.api.java.function.PairFunction
import org.apache.spark.sql.functions._
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql.hive.HiveContext
import java.io._ import com.esotericsoftware.kryo.io.Input
import org.apache.hadoop.conf._
import org.apache.hadoop.fs._
import org.apache.hadoop.fs.Path._
import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.FileSystem
import org.apache.hadoop.fs.Path
import org.apache.hadoop.fs.permission.FsAction
import org.apache.hadoop.fs.permission.FsPermission
import org.apache.hadoop.fs.FSDataOutputStream
import org.apache.hadoop.io.{BytesWritable, NullWritable}
import org.apache.spark.rdd.RDD
import org.apache.spark.serializer.KryoSerializer import scala.reflect.ClassTag // user defined class that need to serialized
class Person(val name: String) /**
* Created by Administrator on 11/10/2017.
*/
object TestSaveClasToHdfs{ def saveAsObjectFile[T: ClassTag](rdd: RDD[T], path: String) {
val kryoSerializer = new KryoSerializer(rdd.context.getConf)
rdd.mapPartitions(iter => iter.grouped()
.map(_.toArray))
.map(splitArray => {
//initializes kyro and calls your registrator class
val kryo = kryoSerializer.newKryo() //convert data to bytes
val bao = new ByteArrayOutputStream()
val output = kryoSerializer.newKryoOutput()
output.setOutputStream(bao)
kryo.writeClassAndObject(output, splitArray)
output.close() // We are ignoring key field of sequence file
val byteWritable = new BytesWritable(bao.toByteArray)
(NullWritable.get(), byteWritable)
}).saveAsSequenceFile(path)
} def objectFile[T](sc: SparkContext, path: String, minPartitions: Int = )(implicit ct: ClassTag[T]) = {
val kryoSerializer = new KryoSerializer(sc.getConf)
sc.sequenceFile(path, classOf[NullWritable], classOf[BytesWritable],
minPartitions)
.flatMap(x => {
val kryo = kryoSerializer.newKryo()
val input = new Input()
input.setBuffer(x._2.getBytes)
val data = kryo.readClassAndObject(input)
val dataObject = data.asInstanceOf[Array[T]]
dataObject
})
} def main(args: Array[String]) {
if (args.length < ) {
println("Please provide output path")
return
}
val conf = new SparkConf().setMaster("local").setAppName("kryoexample")
conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
val sc = new SparkContext(conf) val outputPath = args() //create some dummy data
val personList = to map (value => new Person(value + ""))
val personRDD = sc.makeRDD(personList) saveAsObjectFile(personRDD, outputPath)
val rdd = objectFile[Person](sc, outputPath)
println(rdd.map(person => person.name).collect().toList)
}
}
在spark-shell中执行时,一直出现错误,但是当我把它编译为jar包使用spark-submit命令提交时,错误就没有了。
Spark:将RDD[List[String,List[Person]]]中的List[Person]通过spark api保存为hdfs文件时一直出现not serializable task,没办法找到"spark自定义Kryo序列化输入输出API"的更多相关文章
- 在Spark中自定义Kryo序列化输入输出API(转)
原文链接:在Spark中自定义Kryo序列化输入输出API 在Spark中内置支持两种系列化格式:(1).Java serialization:(2).Kryo serialization.在默认情况 ...
- PHP保存数组到文件中的方法
ThinkPHP自3.1以后的版本,F函数保存数组时先序列化后再保存到文件中,因为我需要使用C方法来读取自定义配置文件,故需要把PHP数组保存到文件中以便C方法读取,PHP保存数组到文件的方法如下: ...
- java spark list 转为 RDD 转为 dataset 写入表中
package com.example.demo; import java.util.ArrayList; import java.util.Arrays; import java.util.Hash ...
- 理解Spark的RDD
RDD是个抽象类,定义了诸如map().reduce()等方法,但实际上继承RDD的派生类一般只要实现两个方法: def getPartitions: Array[Partition] def com ...
- (转)Spark JAVA RDD API
对API的解释: 1.1 transform l map(func):对调用map的RDD数据集中的每个element都使用func,然后返回一个新的RDD,这个返回的数据集是分布式的数据集 l ...
- [转]Spark学习之路 (三)Spark之RDD
Spark学习之路 (三)Spark之RDD https://www.cnblogs.com/qingyunzong/p/8899715.html 目录 一.RDD的概述 1.1 什么是RDD? ...
- Spark学习之路 (三)Spark之RDD
一.RDD的概述 1.1 什么是RDD? RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.里面的元素 ...
- Spark的RDD原理以及2.0特性的介绍
转载自:http://www.tuicool.com/articles/7VNfyif 王联辉,曾在腾讯,Intel 等公司从事大数据相关的工作.2013 年 - 2016 年先后负责腾讯 Yarn ...
- 【spark】RDD创建
首先我们要建立 sparkconf 配置文件,然后通过配置文件来建立sparkcontext. import org.apache.spark._ object MyRdd { def main(ar ...
随机推荐
- 笔记:Hibernate SQL 查询
Hibernate 支持使用原生的SQL查询,使用原生SQL查询可以利用某些数据库特性,原生SQL查询也支持将SQL语句放在配置文件中配置,从而提高程序的解耦,命名SQL查询还可以用于调用存储过程. ...
- SpringBoot 整合 Swagger2
1. Swagger UI 按以下步骤配置,项目启动后访问:http://localhost:8080/swagger-ui.html 1.1 添加依赖 <dependency> < ...
- ArcEngine 10.2 汉化问题
开发环境:VS2010 + ArcEngine 10.2 + DEV 15.2 arcengine自带工具条提示汉化方法: 1:重写tool里的方法 2:利用工具箱里的ToopTip 3:把:ArcG ...
- python之Redis的字符串类型操作
redis的数据类型: 字符串型 哈希 列表 集合 有序集合 1.String(字符串类型) set 命令: 设置一个键和值,键存在则只覆盖,返回ok > s ...
- 【Django】 视图层说明
[Django视图层] 视图层的主要工作是衔接HTTP请求,Python程序和HTML模板,使他们能够有机互相合作从模型层lou到数据并且反馈.说到视图层的工作就有以下几个方面要说 ■ URL映射 对 ...
- Loadrunner初学
1.创建脚本 启动Vvitrual User Generator 创建脚本 因为我们选择录制页面相关的操作,则选择web(HTTP/HTML) application type 选择是录制浏览器网页还 ...
- Linux运维人员共用root帐户权限审计(转至马哥Linux运维)
一.应用场景 在中小型企业,公司不同运维人员基本都是以root 账户进行服务器的登陆管理,缺少了账户权限审计制度.不出问题还好, 出了问题,就很难找出源头.这里介绍下,如何利用编译bash 使不同的客 ...
- UWP 使用Windows.Media.FaceAnalysis.FaceDetector检测人脸
话说现在检测人脸的技术有很多.有在线AI服务,比如Megvii Face++,Microsoft Cognitive Services,Tencent AI等等.还有本地的库实现的,比如OpenCV. ...
- 用C语言协助办公_01 找出所有不对劲的人
近期想出一系列用C语言协助办公的视频教程,这是第一个.具体的移步:https://chuanke.baidu.com/v6658388-240377-1789288.html
- Beta冲刺第三天
一.昨天的困难 没有困难. 二.今天进度 1.林洋洋:修改权限相关的资源表示,修复flex布局排版高度问题,修复文件更新问题,去除登录页面的默认账号密码,服务器部署. 2.黄腾达:修复日程首次执行时间 ...