序列化
1)什么是序列化
序列化就是把内存中的对象,转换成字节序列(或其他数据传输协议)以便于存储到磁盘(持久化)和网络传输。
反序列化就是将收到字节序列(或其他数据传输协议)或者是磁盘的持久化数据,转换成内存中的对象。
2)为什么要序列化
一般来说,“活的”对象只生存在内存里,关机断电就没有了。而且“活的”对象只能由本地的进程使用,不能被发送到网络上的另外一台计算机。 然而序列化可以存储“活的”对象,可以将“活的”对象发送到远程计算机。
3)为什么不用Java的序列化
Java的序列化是一个重量级序列化框架(Serializable),一个对象被序列化后,会附带很多额外的信息(各种校验信息,Header,继承体系等),不便于在网络中高效传输。所以,Hadoop自己开发了一套序列化机制(Writable)。
4)Hadoop序列化特点:
(1)紧凑 :高效使用存储空间。
(2)快速:读写数据的额外开销小。
(3)互操作:支持多语言的交互。
自定义bean对象实现序列化接口
在企业开发中往往常用的基本序列化类型不能满足所有需求,比如在Hadoop框架内部传递一个bean对象,那么该对象就需要实现序列化接口。
具体实现bean对象序列化步骤如下7步。
(1)必须实现Writable接口
(2)反序列化时,需要反射调用空参构造函数,所以必须有空参构造
(3)重写序列化方法
(4)重写反序列化方法
(5)注意反序列化的顺序和序列化的顺序完全一致
(6)要想把结果显示在文件中,需要重写toString(),可用"\t"分开,方便后续用。
(7)如果需要将自定义的bean放在key中传输,则还需要实现Comparable接口,因为MapReduce框中的Shuffle过程要求对key必须能排序。
如:
1 import org.apache.hadoop.io.Writable; 2 3 import java.io.DataInput; 4 import java.io.DataOutput; 5 import java.io.IOException; 6 7 /** 8 * 1. 定义类实现writable接口 9 * 2. 重写序列化和反序列化方法 10 * 3. 重写空参构造 11 * 4. toString方法 12 */ 13 public class FlowBean implements Writable { 14 15 private long upFlow; 16 private long downFlow; 17 private long sumFlow; 18 19 public long getUpFlow() { 20 return upFlow; 21 } 22 23 public void setUpFlow(long upFlow) { 24 this.upFlow = upFlow; 25 } 26 27 public long getDownFlow() { 28 return downFlow; 29 } 30 31 public void setDownFlow(long downFlow) { 32 this.downFlow = downFlow; 33 } 34 35 public long getSumFlow() { 36 return sumFlow; 37 } 38 39 public void setSumFlow() { 40 this.sumFlow = this.upFlow + this.downFlow; 41 } 42 43 //空参构造 44 public FlowBean() { 45 } 46 47 48 @Override 49 public void write(DataOutput out) throws IOException { 50 // 序列化方法 51 out.writeLong(upFlow); 52 out.writeLong(downFlow); 53 out.writeLong(sumFlow); 54 } 55 56 @Override 57 public void readFields(DataInput in) throws IOException { 58 59 // 反 60 this.upFlow = in.readLong(); 61 this.downFlow = in.readLong(); 62 this.sumFlow = in.readLong(); 63 } 64 65 @Override 66 public String toString() { 67 return "\t" + upFlow + "\t" + downFlow + sumFlow ; 68 } 69 }