1. 序列化从头说
在面向对象程序设计中,类是个很重要的概念。所谓“类”,可以将它想像成建筑图纸,而对象就是根据图纸盖的大楼。类,规定了对象的一切。根据建筑图纸造房子,盖出来的就是大楼,等同于将类进行实例化,得到的就是对象。
一开始,在源代码里,类的定义是明确的,但对象的行为有些地方是明确的,有些地方是不明确的。对象里不明确地方,是因为对象在运行的时候,需要处理无法预测的事情,诸如用户点了下屏幕,用户点了下按钮,输入点东西,或者需要从网络发送接收数据之类的。后来,引入了泛型的概念之后,类也开始不明确了,如果使用了泛型,直到程序运行的时候,才知道究竟是哪种对象需要处理。
对象可以很复杂,也可以跟时序相关。一般来说,“活的”对象只生存在内存里,关机断电就没有了。一般来说,“活的”对象只能由本地的进程使用,不能被发送到网络上的另外一台计算机。
序列化,可以存储“活的”对象,可以将“活的”对象发送到远程计算机。
把“活的”对象序列化,就是把“活的”对象转化成一串字节,而“反序列化”,就是从一串字节里解析出“活的”对象。于是,如果想把“活的”对象存储到文件,存储这串字节即可,如果想把“活的”对象发送到远程主机,发送这串字节即可,需要对象的时候,做一下反序列化,就能将对象“复活”了。
将对象序列化存储到文件,术语又叫“持久化”。将对象序列化发送到远程计算机,术语又叫“数据通信”。
Java 对序列化提供了非常方便的支持,在定义类的时候,如果想让对象可以被序列化,只要在类的定义上加上了”implementsSerializable” 即可,比如说,可以这么定义”publicclassBuilding implementsSerializable” ,其他什么都不要做,Java 会自动的处理相关一切。Java 的序列化机制相当复杂,能处理各种对象关系。
Java 的序列化机制的缺点就是计算量开销大,且序列化的结果体积大太,有时能达到对象大小的数倍乃至十倍。它的引用机制也会导致大文件不能分割的问题。这些缺点使得Java 的序列化机制对Hadoop 来说是不合适的。于是Hadoop 设计了自己的序列化机制。
为什么序列化对Hadoop 很重要?因为Hadoop 在集群之间进行通讯或者RPC 调用的时候,需要序列化,而且要求序列化要快,且体积要小,占用带宽要小。所以必须理解Hadoop 的序列化机制。
2.Hadoop 的序列化接口
什么是接口?简答来说,接口就是规定,它规定类必须实现的方法。一个接口可以包含多干个方法。如果一个类说自己实现了某个接口,那么它必须实现这个接口里的所有方法。特殊情况下,接口也可以没有任何方法。
Writable 接口,也就是org.apache.hadoop.io.Writable 接口。Hadoop 的所有可序列化对象都必须实现这个接口。Writable 接口里有两个方法,一个是write 方法,将对象写入字节流,另一个是readFields 方法,从字节流解析出对象。
Java 的API 提供了Comparable 接口,也就是java.lang.Comparable 接口。这个接口只有一个方法,就是compareTo ,用于比较两个对象。
WritableComparable 接口同时继承了Writable 和Comparable 这两个接口。
Hadoop 里的三个类IntWritable 、DoubleWritable 和ByteWritable ,都继承了WritableComparable 接口。注意,IntWritable 、DoubleWritable 和ByteWritable ,尽管后缀是“Writable” ,但它们不是接口,是类!!
Hadoop 的序列化接口还有更多的类型,在这里不一一列举。
3.IntWritable 如何序列化
3.1 目录和文件结构
这个例子演示IntWritable 如何序列化。首先,创建一个IntWritable ,然后,将它序列化,输出到一个字节流中。然后,创建一个新的IntWritable ,从字节流中读取值,这是反序列化。
创建目录~/intser 存放源代码、编译和打包结果。在intser 目录下,有两个子目录,分别是src 目录和classes 目录,src 目录存放Java 源代码,class 存放编译结果。在src 目录下,只有一个源代码文件IntSer.java 。
3.2 IntSer.jav 文件的源代码
packagecom.brianchen.hadoop;
importjava.io.DataOutputStream;
importjava.io.DataInputStream;
importjava.io.ByteArrayOutputStream;
importjava.io.ByteArrayInputStream;
importjava.io.IOException;
importorg.apache.hadoop.io.Writable;
importorg.apache.hadoop.io.IntWritable;
importorg.apache.hadoop.util.StringUtils;
public classIntSer{
public byte[]serialize(Writable w)throws IOException{
ByteArrayOutputStreamout = new ByteArrayOutputStream();
DataOutputStreamdataout = new DataOutputStream(out);
w.write(dataout);
dataout.close();
returnout.toByteArray();
}
public byte[]deserialize(Writable w, byte[] bytes) throws IOException{
ByteArrayInputStreamin = new ByteArrayInputStream(bytes);
DataInputStreamdatain = new DataInputStream(in);
w.readFields(datain);
datain.close();
return bytes;
}
public staticvoid main(String[] args) throws Exception{
IntWritableintw = new IntWritable(7);
byte[] bytes= serialize(intw);
Stringbytes_str = StringUtils.byteToHexString(bytes);
System.out.println(bytes_str);
IntWritableintw2 = new IntWritable(0);
deserialize(intw2,bytes);
System.out.println(intw2);
}
}
3.3 编译
“cd~/intser”
“javac-cp /home/brian/usr/hadoop/hadoop-1.2.1/hadoop-core-1.2.1.jar -d./classes src/*.java”
3.4 打包
“jar-cvf intser.jar -C ./classes .”
3.5 运行
“cd~/usr/hadoop/hadoop-1.2.1”
“./bin/hadoopjar /home/brian/intser/intser.jar com.brianchen.hadoop.IntSer”
首先确认Hadoop 已经是运行的,然后切换到Hadoop 的安装目录,然后运行,输出结果是两行,第一行是”00000007” ,第二行是”7” 。
版权声明:本文为博主原创文章,未经博主允许不得转载。
运维网声明
1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网 享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com