声明:本文转自《在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"的更多相关文章

  1. 在Spark中自定义Kryo序列化输入输出API(转)

    原文链接:在Spark中自定义Kryo序列化输入输出API 在Spark中内置支持两种系列化格式:(1).Java serialization:(2).Kryo serialization.在默认情况 ...

  2. PHP保存数组到文件中的方法

    ThinkPHP自3.1以后的版本,F函数保存数组时先序列化后再保存到文件中,因为我需要使用C方法来读取自定义配置文件,故需要把PHP数组保存到文件中以便C方法读取,PHP保存数组到文件的方法如下: ...

  3. java spark list 转为 RDD 转为 dataset 写入表中

    package com.example.demo; import java.util.ArrayList; import java.util.Arrays; import java.util.Hash ...

  4. 理解Spark的RDD

    RDD是个抽象类,定义了诸如map().reduce()等方法,但实际上继承RDD的派生类一般只要实现两个方法: def getPartitions: Array[Partition] def com ...

  5. (转)Spark JAVA RDD API

    对API的解释: 1.1 transform l  map(func):对调用map的RDD数据集中的每个element都使用func,然后返回一个新的RDD,这个返回的数据集是分布式的数据集 l   ...

  6. [转]Spark学习之路 (三)Spark之RDD

    Spark学习之路 (三)Spark之RDD   https://www.cnblogs.com/qingyunzong/p/8899715.html 目录 一.RDD的概述 1.1 什么是RDD? ...

  7. Spark学习之路 (三)Spark之RDD

    一.RDD的概述 1.1 什么是RDD? RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.里面的元素 ...

  8. Spark的RDD原理以及2.0特性的介绍

    转载自:http://www.tuicool.com/articles/7VNfyif 王联辉,曾在腾讯,Intel 等公司从事大数据相关的工作.2013 年 - 2016 年先后负责腾讯 Yarn ...

  9. 【spark】RDD创建

    首先我们要建立 sparkconf 配置文件,然后通过配置文件来建立sparkcontext. import org.apache.spark._ object MyRdd { def main(ar ...

随机推荐

  1. DOM节点的创建

    1.createAttribute() 创建一个属性节点 => 接收参数为string类型的属性名称 var a=document.getElementsByClassName('name1') ...

  2. node命令curl

    一.打开另一个命令行窗口,运行下面的命令. curl -X POST --data "name=Jack" 127.0.0.1:3000 上面代码使用 POST 方法向服务器发送一 ...

  3. vue+webpack+element-ui+git

    webpack.config.jsconst { resolve } = require('path') const webpack = require('webpack') const HtmlWe ...

  4. 【Python&数据结构】 抽象数据类型 Python类机制和异常

    这篇是<数据结构与算法Python语言描述>的笔记,但是大头在Python类机制和面向对象编程的说明上面.我也不知道该放什么分类了..总之之前也没怎么认真接触过基于类而不是独立函数的Pyt ...

  5. 【jQuery】 JQ和AJAX

    AJAX AJAX全称异步 JavaScript 和 XML(Asynchronous JavaScript and XML),是一种用于网页前端和网站后台进行数据交互的手段.关于AJAX的详细介绍在 ...

  6. 基于hi-nginx的web开发(python篇)——表单处理和文件上传

    hi-nginx会自动处理表单,所以,在hi.py框架里,要做的就是直接使用这些数据. 表单数据一般用GET和POST方法提交.hi-nginx会把这些数据解析出来,放在form成员变量里.对pyth ...

  7. 0x02 译文:Windows桌面应用Win32第一个程序

    本节课我们将用C++ 写一个最简单的Windows 程序. 目录: 创建一个窗口 窗口消息 编写窗口过程 绘制窗口 关闭窗口 管理应用程序状态 代码如下: #ifndef UNICODE #defin ...

  8. [css 揭秘]:CSS揭秘 技巧(一):半透明边框

    我的github地址:https://github.com/FannieGirl/ifannie/ 源码都在上面哦 喜欢的给我一个星吧 半透明边框 css 中的半透明颜色,比如用 rgba() 和 h ...

  9. 生产者/消费者问题的多种Java实现方式

    实质上,很多后台服务程序并发控制的基本原理都可以归纳为生产者/消费者模式,而这是恰恰是在本科操作系统课堂上老师反复讲解,而我们却视而不见不以为然的.在博文<一种面向作业流(工作流)的轻量级可复用 ...

  10. 记录一个古老的Sql分页过程

    /* 根据单位ID获取排班信息 For:WXX TIme:2017-11-22 */ ALTER proc [dbo].[proc_ScheduleInfo] )='', --单位ID )='', - ...