1、序列化
把内存中的对象转换成字节序列(或其他数据传输协议)以便存储到磁盘和网络传输。
2、反序列化
将字节序列(或其他数据传输协议)或者磁盘的持久化数据转成内存对象
3、Hadoop为什么不使用java的序列化机制
java的序列化是一个重量级序列化框架,一个对象被序列化后,会附带很多额外的信息(各种校验信息,Header,继承体系等),不便于在网络中高效传输。
4、Hadoop序列化特点
(1)紧凑:高效使用存储空间
(2)快速:读写数据的额外开销小。
(3)可扩展:随着通信协议的升级而升级
(4)互操作:支持多语言的交互
5、常用的数据类型对应的Hadoop数据序列化类型
Java类型 | Hadoop Writable类型 |
boolean | BooleanWritable |
byte | ByteWritable |
int | IntWritable |
float | FloatWritable |
long | LongWritable |
double | DoubleWritable |
String | Text |
map | MapWritable |
array | ArrayWritable |
6、序列化实例
自定义bean对象实现序列化接口(Writable)
public class Flow implements Writable ,Comparable<Flow>{ private Long upFlow;//上行流量 private Long downFlow;//下行流量 private Long sumFlow;//总流量 @Override public String toString() { return "Flow{" + "upFlow=" + upFlow + ", downFlow=" + downFlow + ", sumFlow=" + sumFlow + '}'; } public Long getUpFlow() { return upFlow; } public void setUpFlow(long upFlow) { this.upFlow = upFlow; } public Long getDownFlow() { return downFlow; } public void setDownFlow(long downFlow) { this.downFlow = downFlow; } public Long getSumFlow() { return sumFlow; } public void setSumFlow(long sumFlow) { this.sumFlow = sumFlow; } @Override public void write(DataOutput dataOutput) throws IOException { dataOutput.writeLong(upFlow); dataOutput.writeLong(downFlow); dataOutput.writeLong(sumFlow); } @Override public void readFields(DataInput dataInput) throws IOException { upFlow=dataInput.readLong(); downFlow=dataInput.readLong(); sumFlow=dataInput.readLong(); } @Override public int compareTo(Flow o) { return this.getSumFlow().compareTo(o.getSumFlow()); } }
注意:
(1)必须实现Writable接口
(2)反序列化时,需要反射调用空参构造函数,所以必须有空参构造
(3)重写序列化方法和反序列化方法,反序列化的顺序和序列化的顺序完全一致
(4)如果需要将自定义的bean放在key中传输,则还需要实现Comparable接口,因为MapReduce框中的Shuffle过程要求对key必须能排序。