hadoop文件序列化和反序列化

381 阅读2分钟

一.是什么

序列化:就是将对象转化成字节序列的过程。

反序列化:就是讲字节序列转化成对象的过程。

对象序列化成的字节序列会包含对象的类型信息、对象的数据等,说白了就是包含了描述这个对象的所有信息,能根据这些信息“复刻”出一个和原来一模一样的对象。

二.为什么

那么为什么要去进行序列化呢?有以下两个原因

  1. 持久化:对象是存储在JVM中的堆区的,但是如果JVM停止运行了,对象也不存在了。序列化可以将对象转化成字节序列,可以写进硬盘文件中实现持久化。在新开启的JVM中可以读取字节序列进行反序列化成对象。
  2. 网络传输:网络直接传输数据,但是无法直接传输对象,可在传输前序列化,传输完成后反序列化成对象。所以所有可在网络上传输的对象都必须是可序列化的。

简单来说,磁盘进内存就要反序列化,内存要传输,或者存进磁盘,就要序列化。

三.怎么做

怎么去实现对象的序列化呢?

Java为我们提供了对象序列化的机制,规定了要实现序列化对象的类要满足的条件和实现方法。

  1. 对于要序列化对象的类要去实现Serializable接口或者Externalizable接口
  2. 实现方法:JDK提供的ObjectOutputStream和ObjectInputStream来实现序列化和反序列化

四.hadoop中的序列化

hadoop的读写语句分别如下:

JavaPairRDD<BytesWritable,BytesWritable> rdd = javaSparkContext.hadoopFile(path, PBInputFormat.class, BytesWritable.class, BytesWritable.class);

解析:
只是按照PBInputFormat.class的格式对写入的文件,进行拆分,分成<key,value>,并进行反序列化。 即: 1.反序列化 2.解析成BytesWritable对象
点进源码里也可以看到, 实现了Serializable接口。

byte[] originalValue = rdd.map(data -> data._2.getBytes()).

序列化的写入方法同理:

rdd.saveAsHadoopFile(outputPath, BytesWritable.class, BytesWritable.class, PBOutputFormat.class);

常见的OutputFormat实现类

1、TextOutputFormat

默认的输出格式是TextOutputFormat,它把每条记录写在文本行。

它的键和值可以是任意类型,因为TextOutputFormat调用toString()方法可以把他们转换成字符串

2、SequenceFileOutputFormat

将SequenceFileOutputFormat输出作为后续 MapReduce任务的输入,这便是一种好的输出格式。

因为它的格式紧凑,很容易压缩

3、自定义OutputFormat

根据用户需求,自定义实现输出

 ## 自定义OutputFormat

1、自定义一个继承FileOutputFormat

2、改写RecordWriter,具体改写输出数据的方法write()

PBOutputFormat属于这个