c语言sscanf函数的用法是什么
279
2022-11-26
十二、hadoop的序列化
一、序列化基本概述
1、何为序列化
序列化就是将内存中的对象,转换成字节序列(或者按照其他数据传输协议转换),以便于持久化存储到磁盘中以及网络传输
2、为什么需要序列化
一般情况下,对象只存储在本地的内存中,只允许本地的进程调用。而随着分布式程序的出现,需要在不同的主机上不同进程调用对象,这就需要将对象通过网络传输到另外的主机上。但是对象不经过处理无法通过网络传输,而通过序列化处理之后,对象可以通过网络传输了。
3、java中的序列化方案
java中自行实现了序列化方案,只要定义一个类的时候实现 Serializable 接口,那么java内部就会自动实现相应的序列化。如:
public class Test implements Serializable{ //这个序列化号是必须的,用于标识该类 private static final long serialVersionUID = xxxx; }
但是由于Java中的序列化接口实现的时候,会附带很多额外的信息,如各种校验信息,header,继承体系等。不便于在网络上高效传输(性能不高)。所以hadoop自己额外实现了序列化的机制,体积短小,占用带宽低,序列化和反序列化快速
二、hadoop中序列化
1、类基本依赖
图 2.1 hadoop序列化依赖图
可以看到所有的可序列化的类都实现了 WritableComparable 这个接口,这个接口同时继承了 Writable 以及 Comparable 接口。下面看看这个这三个接口:
//WritableComparable.java
public interface WritableComparable
2、hadoop序列化类和基本类型的对照表
java类型 | hadoop writable类型 |
---|---|
boolean | BooleanWritable |
byte | ByteWritable |
Int | IntWritable |
float | FloatWritable |
long | LongWritable |
double | DoubleWritable |
string | Text |
map | MapWritable |
array | ArrayWritable |
3、常用序列化类的源码实现
下面挑个IntWritable这个常用的序列化类来看看源码
package org.apache.hadoop.io;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.classification.InterfaceAudience.Public;
import org.apache.hadoop.classification.InterfaceStability.Stable;
@Public
@Stable
public class IntWritable implements WritableComparable
其他short,long的序列化类的实现也是类似的。
4、自定义序列化类
要点:(1)必须实现 Writable接口(2)必须有无参构造方法,因为反序列化时需要反射调用无参构造方法(3)重写序列化方法
public void write(DataOutput out) throws IOException{ //DataOutput接口中定义了每个基本类型序列化的方法,这里以Long为例 out.writeLong(upFlow); out.writeLong(downFlow); out.writeLong(sumFlow); }
(4)重写反序列化方法
public void readFields(DataInput in) throws IOException{ upFlow = in.readLong(); downFlow = in.readLong(); sumFlow = in.readLong(); }
(5)序列化写入和反序列化读取时要注意,写入和读取的顺序必须完全一致(6)按照需要可以重写 toSting 方法,便于保存在文件中的内容(7)如果该自定义序列化类是作为键值对中的key使用的话,因为MapReduce中会以key进行排序,那么就会涉及到 key 的比较问题。所以需要实现 Comparable 接口。而该接口就得实现 compareTo 方法
public int compareTo(Test o) { return (-1 | 0 |1 ); 表示小于,等于,大于三种结果 }
5、属性中包含自定义类的序列化
首先属性中的自定义类也是需要实现序列化接口的。所以下面的DateDimension和ContactDimension都是已经实现序列化的了。
public class ComDimension extends BaseDimension { private DateDimension dateDimension = new DateDimension(); private ContactDimension contactDimension = new ContactDimension(); //序列化就直接调用类的write方法即可,按照下面的形式 @Override public void write(DataOutput dataOutput) throws IOException { this.dateDimension.write(dataOutput); this.contactDimension.write(dataOutput); } @Override public void readFields(DataInput dataInput) throws IOException { this.dateDimension.readFields(dataInput); this.contactDimension.readFields(dataInput); } }
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~