`
flyingdutchman
  • 浏览: 353261 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Hadoop深入学习:MapReduce的序列化

阅读更多
       在学习MapReduce编程模型接口的五个组件之前,我们先来看一下MapReduce的序列化。
       那么什么是序列化呢?
       序列化就是讲一个对象编码成一个字节流;相反,从字节流中重新构建对象就叫做反序列化。序列化主要有三种用途:
       ●持久化:将内存中的对象经序列化后保存到磁盘上;
       ●作为通信的数据传输格式:将一个机器上的内存中的对象经序列化后传输到其他机器上,或在相同机器上的不同进程之间的数据通信;
       ●作为copy、clone机制:将对象序列化到内存中,然后通过反序列化,可以得到一个已存在的对象的copy。
       在分布式系统中,主要使用序列化的前两种功能,数据持久化和通信数字格式。

       MapReduce为什么要专门再开发出自己的序列化(Writable),而不用java原有的序列化(Serializable)?在本节中我们将会找到答案。
       我们先来看一下Java内置的序列化机制,该序列化机制非常简单,只需要将要序列化的对象的类继承java.io.Serializable接口就行了。java.io.Serializable只是一个标志性的接口,不具有任何成员函数:
       public interface Serializable {
       }
       

       Java的序列化机制非常“聪明”,它会将要序列化的对象的类、类签名、类的所有非暂态和非晶态成员变量的值,以及其所有的父类都要序列化。同时,它还会跟踪要序列化的对象所有可以达到的其他对象内部数据,并描述所有这些对象是如何被链接起来的,即使非常复杂的情况如循环引用的对象,序列化也不会陷入死循环。但是,经Java内置的序列化后的数据的大小太庞大了,不但包括用户想要保存的数据,还包括大量的类相关的附加数据信息,这对需要保存和处理的大规模数据的Hadoop来说,很不合适。另外还有一点,Java的序列化机制不能复用反序列化后的对象。

       对于Hadoop,其序列化机制需要有如下的特征:
       ●紧凑:在Hadoop中,带宽是最稀缺的资源,一个紧凑的序列化机制可以充分利用数据中心的带宽;
       ●快速(性能):在进程间通信会大量使用序列化机制,因此需要尽量减少序列化合反序列化的开销;
       ●可扩展:随着系统发展,系统间通信的协议可能会升级,累的定义也可能会发生改变,序列化机制需要这些升级和变化;
       ●互操作:可以支持不同开发语言间的通信。
       Java内置的序列化机制虽然简单而强大,但是却并不符合上述的要求。但是Hadoop平台中新的序列化机制,就完全符合上述要求吗,答案是否定的,它只符合紧凑和快速的要求,但是缺不符合可扩展和互操作的要求。
       为了支持以上特性,Hadoop引入了org.apache.hadoop.io.Writable接口。Writable机制满足了紧凑和快速的这两个特性,Writable接口不是一个说明性的标志接口,声明如下:
 public interface Writable{
				
		/**
		 * 反序列化操作,从流中读数据,为了效率,尽量复用现有对象
		 * @param input DataInput流,从该流中读取数据
                 * @Throws IOException
		 */
		@Override
		public void readFields(DataInput input) throws IOException {
			//TODO
		}
		
		/**
		 * 序列化操作,将对象输出到流中
		 * @param output DataOutput流,序列化后的结果
                 * @Throws IOException
		 */
		@Override
		public void write(DataOutput output) throws IOException {
			//TODO
		}
 }

         Writable的使用示例代码:
 public class ModeEntry implements Writable{
		
		private long key;
		private long value;
		
		public ModeEntry(long key,long value){
			this.key = key;
			this.value = value;
		}
		
		/**
		 * 反序列化操作,从流中读数据,为了效率,尽量复用现有对象
		 * @param input DataInput流,从该流中读取数据
		 * @throws IOException
         */
		@Override
		public void readFields(DataInput input) throws IOException {
			this.key = input.readLong();
			this.value = input.readLong();
		}
		
		/**
		 * 序列化操作,将对象输出到流中
		 * @param output DataOutput流,序列化后的结果
		 * @throws IOException
		 */
		@Override
		public void write(DataOutput output) throws IOException {
			output.writeLong(this.key);
			output.writeLong(this.value);
		}
 }
         

     
         总的来说,Hadoop的序列化机制的特点是紧凑、高效和可复用反序列化后的对象。另外相比Java内建的序列化机制,序列化后的数据比较少,不会附加大量的类信息和其应用对象及对象的链接信息,在序列化和反序列化的开销上,Hadoop的序列化机制要较Java内建的序列化机制开销要少很多。
      
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics