从零开始学习Hadoop--第4章 序列化(转载)

作者对序列化的描述浅显易懂!(https://www.douban.com/note/313096752/)

1. 序列化从头说
    在面向对象程序设计中,类是个很重要的概念。所谓“类”,可以将它想像成建筑图纸,而对象就是根据图纸盖的大楼。类,规定了对象的一切。根据建筑图纸造房子,盖出来的就是大楼,等同于将类进行实例化,得到的就是对象。

    一开始,在源代码里,类的定义是明确的,但对象的行为有些地方是明确的,有些地方是不明确的。对象里不明确地方,是因为对象在运行的时候,需要处理无法预测的事情,诸如用户点了下屏幕,用户点了下按钮,输入点东西,或者需要从网络发送接收数据之类的。后来,引入了泛型的概念之后,类也开始不明确了,如果使用了泛型,直到程序运行的时候,才知道究竟是哪种对象需要处理。

    对象可以很复杂,也可以跟时序相关。一般来说,“活的”对象只生存在内存里,关机断电就没有了。一般来说,“活的”对象只能由本地的进程使用,不能被发送到网络上的另外一台计算机。

    序列化,可以存储“活的”对象,可以将“活的”对象发送到远程计算机。

    把“活的”对象序列化,就是把“活的”对象转化成一串字节,而“反序列化”,就是从一串字节里解析出“活的”对象。于是,如果想把“活的”对象存储到文件,存储这串字节即可,如果想把“活的”对象发送到远程主机,发送这串字节即可,需要对象的时候,做一下反序列化,就能将对象“复活”了。

    将对象序列化存储到文件,术语又叫“持久化”。将对象序列化发送到远程计算机,术语又叫“数据通信”。

    Java对序列化提供了非常方便的支持,在定义类的时候,如果想让对象可以被序列化,只要在类的定义上加上了”implements Serializable”即可,比如说,可以这么定义”public class Building implements Serializable”,其他什么都不要做,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.java文件的源代码

package com.brianchen.hadoop;

import java.io.DataOutputStream;
import java.io.DataInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;

import org.apache.hadoop.io.Writable;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.util.StringUtils;

public class IntSer{
  public byte[] serialize(Writable w)throws IOException{
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    DataOutputStream dataout = new DataOutputStream(out);
    w.write(dataout);
    dataout.close();
    return out.toByteArray();
  }  

  public byte[] deserialize(Writable w, byte[] bytes) throws IOException{
    ByteArrayInputStream in = new ByteArrayInputStream(bytes);
    DataInputStream datain = new DataInputStream(in);
    w.readFields(datain);
    datain.close();
    return bytes;
  }  

  public static void main(String[] args) throws Exception{
    IntWritable intw = new IntWritable(7);
    byte[] bytes = serialize(intw);
    String bytes_str = StringUtils.byteToHexString(bytes);
    System.out.println(bytes_str);

    IntWritable intw2 = 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/hadoop jar /home/brian/intser/intser.jar com.brianchen.hadoop.IntSer”
    首先确认Hadoop已经是运行的,然后切换到Hadoop的安装目录,然后运行,输出结果是两行,第一行是”00000007”,第二行是”7”。
时间: 2025-01-06 18:08:04

从零开始学习Hadoop--第4章 序列化(转载)的相关文章

从零开始学习hadoop之发行版选择

从零开始学习hadoop之发行版选择 经常会看到这样的问题:零基础学习hadoop难不难?有的人回答说:零基础学习hadoop,没有想象的那么难,也没有想象的那么容易.看到这样的答案不免觉得有些尴尬,这个问题算是白问了,因为这个回答似乎什么也没给出来.这个问题的关键在于"零基础"到底是个什么样的基础? 所谓的零基础大体可以分为两种:第一种是hadoop初学者,有一定的Linux基础.虚拟机和Java基础:第二种是hadoop兴趣爱好者,但缺乏最基本的Linux基础.虚拟机和Java基础

Python学习笔记__9.4章 序列化

# 这是学习廖雪峰老师python教程的学习笔记 1.概览 在程序运行的过程中,所有的变量都是在内存中.但是一旦程序结束,变量所占用的内存就被操作系统全部回收.而如果要保存变量的修改,我们就可以用序列化. 我们把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling. 序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上 反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling. 2.pickle模块 Python提供了

从零开始学习jQuery (一) 开天辟地入门篇

原文:从零开始学习jQuery (一) 开天辟地入门篇 本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式 从零开始学习jQuery (五) 事件与事件对象 从零开始学习jQuery (六) jQuery中的Ajax 从零开始学习jQuery (七) jQuery动画-让页面动起来! 从零开始学习jQuer

从零开始学习jQuery (六) AJAX快餐

原文:从零开始学习jQuery (六) AJAX快餐 本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式 从零开始学习jQuery (五) 事件与事件对象 从零开始学习jQuery (六) jQuery中的Ajax 从零开始学习jQuery (七) jQuery动画-让页面动起来! 从零开始学习jQuery

从零开始学习jQuery (九) jQuery工具函数

原文:从零开始学习jQuery (九) jQuery工具函数 本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式 从零开始学习jQuery (五) 事件与事件对象 从零开始学习jQuery (六) jQuery中的Ajax 从零开始学习jQuery (七) jQuery动画-让页面动起来! 从零开始学习jQ

从零开始学习jQuery (一) 入门篇

一.摘要 本系列文章将带您进入jQuery的精彩世界, 其中有很多作者具体的使用经验和解决方案,  即使你会使用jQuery也能在阅读中发现些许秘籍. 本篇文章是入门第一篇, 主要是简单介绍jQuery, 通过简单示例指导大家如何编写jQuery代码以及搭建开发环境. 详细讲解了如何在Visual Studio中配合使用jQuery. 转载请注明子秋出品!博客园首发! 二.前言 首先道个歉! "从零开始学习ASP.NET MVC"系列文章在即将介绍Filter时就没有更新了, 原因就是

从零开始学习jQuery (三) 管理jQuery包装集

本系列文章导航 从零开始学习jQuery (三) 管理jQuery包装集 一.摘要 在使用jQuery选择器获取到jQuery包装集后, 我们需要对其进行操作. 本章首先讲解如何动态的创建元素, 接着学习如何管理jQuery包装集, 比如添加,删除,切片等. 二.前言 本系列的2,3篇上面列举了太多的API相信大家看着眼晕. 不过这些基础还必须要讲, 基础要扎实.其实对于这些列表大家可以跳过, 等以后用到时再回头看或者查询官方的API说明. 本章内容很少, 主要讲解动态创建元素和操作jQuery

从零开始学习CocoaPods安装和使用

从零开始学习CocoaPods安装和使用 转载: Code4App原创:http://code4app.com/article/cocoapods-install-usage http://m.ithao123.cn/content-9745764.html CocoaPods是什么? 当你开发iOS应用时,会经常使用到很多第三方开源类库,比如JSONKit,AFNetWorking等等.可能某个类库又用到其他类库,所以要使用它,必须得另外下载其他类库,而其他类库又用到其他类库,“子子孙孙无穷尽

AspectJ基础学习之二搭建环境(转载)

AspectJ基础学习之二搭建环境(转载) 一.下载Aspectj以及AJDT 上一章已经列出了他的官方网站,自己上去download吧.AJDT是一个eclipse插件,开发aspectj必装,他可以提供语法检查,以及编译.这里要说一点重要的知识: aspectj不能使用传统的JDK编译,他的编译器扩展自JDK.AJDT提供的编译功能,就为我们省了很多事,当然你也可以用命令行自己去编译(不过我从来没有这么做过). 无论是apsectj的安装,还是AJDT网上还是有很多文章讲的.不会的同学可以自