hadoop的序列化格式

hadoop自身的序列化存储格式就是实现了Writable接口的类,他只实现了前面两点,压缩和快速。但是不容易扩展,也不跨语言。
我们先来看下Writable接口,Writable接口定义了两个方法:
1.将数据写入到二进制流中
2.从二进制数据流中读取数据
  1. package org.apache.hadoop.io;
  2. public interface Writable {
  3. void write(java.io.DataOutput p1) throws java.io.IOException;
  4. void readFields(java.io.DataInput p1) throws java.io.IOException;
  5. }
我们再来看下Writable接口与序列化和反序列化是如何关联的:
  1. package com.sweetop.styhadoop;
  2. import junit.framework.Assert;
  3. import org.apache.hadoop.io.IntWritable;
  4. import org.apache.hadoop.io.Writable;
  5. import org.apache.hadoop.util.StringUtils;
  6. import org.junit.Before;
  7. import org.junit.Test;
  8. import java.io.*;
  9. /**
  10. * Created with IntelliJ IDEA.
  11. * User: lastsweetop
  12. * Date: 13-7-4
  13. * Time: 下午10:25
  14. * To change this template use File | Settings | File Templates.
  15. */
  16. public class TestWritable {
  17. byte[] bytes=null;
  18. /**
  19. * 初始化一个IntWritable实例,并且调用系列化方法
  20. * @throws IOException
  21. */
  22. @Before
  23. public void init() throws IOException {
  24. IntWritable writable = new IntWritable(163);
  25. bytes = serialize(writable);
  26. }
  27. /**
  28. * 一个IntWritable序列号后的四个字节的字节流
  29. * 并且使用big-endian的队列排列
  30. * @throws IOException
  31. */
  32. @Test
  33. public void testSerialize() throws IOException {
  34. Assert.assertEquals(bytes.length,4);
  35. Assert.assertEquals(StringUtils.byteToHexString(bytes),"000000a3");
  36. }
  37. /**
  38. * 创建一个没有值的IntWritable对象,并且通过调用反序列化方法将bytes的数据读入到它里面
  39. * 通过调用它的get方法,获得原始的值,163
  40. */
  41. @Test
  42. public void testDeserialize() throws IOException {
  43. IntWritable newWritable = new IntWritable();
  44. deserialize(newWritable,bytes);
  45. Assert.assertEquals(newWritable.get(),163);
  46. }
  47. /**
  48. * 将一个实现了Writable接口的对象序列化成字节流
  49. * @param writable
  50. * @return
  51. * @throws IOException
  52. */
  53. public static byte[] serialize(Writable writable) throws IOException {
  54. ByteArrayOutputStream out = new ByteArrayOutputStream();
  55. DataOutputStream dataOut = new DataOutputStream(out);
  56. writable.write(dataOut);
  57. dataOut.close();
  58. return out.toByteArray();
  59. }
  60. /**
  61. * 将字节流转化为实现了Writable接口的对象
  62. * @param writable
  63. * @param bytes
  64. * @return
  65. * @throws IOException
  66. */
  67. public static byte[] deserialize(Writable writable,byte[] bytes) throws IOException {
  68. ByteArrayInputStream in=new ByteArrayInputStream(bytes);
  69. DataInputStream dataIn = new DataInputStream(in);
  70. writable.readFields(dataIn);
  71. dataIn.close();
  72. return bytes;
  73. }
  74. }

WritableComparable和comparators

IntWritable实现了WritableComparable,接口看下源代码知道,WritableComparable是Writable接口和java.lang.Comparable<T>的一个子接口。
  1. package org.apache.hadoop.io;
  2. public interface WritableComparable <T>  extends org.apache.hadoop.io.Writable, java.lang.Comparable<T> {
  3. }

MapReduce在排序部分要根据key值的大小进行排序,因此类型的比较相当重要,RawComparator是Comparator的增强版

  1. package org.apache.hadoop.io;
  2. public interface RawComparator <T>  extends java.util.Comparator<T> {
  3. int compare(byte[] bytes, int i, int i1, byte[] bytes1, int i2, int i3);
  4. }

它可以做到,不先反序列化就可以直接比较二进制字节流的大小:

  1. package com.sweetop.styhadoop;
  2. import org.apache.hadoop.io.IntWritable;
  3. import org.apache.hadoop.io.RawComparator;
  4. import org.apache.hadoop.io.Writable;
  5. import org.apache.hadoop.io.WritableComparator;
  6. import org.eclipse.jdt.internal.core.Assert;
  7. import org.junit.Before;
  8. import org.junit.Test;
  9. import java.io.ByteArrayOutputStream;
  10. import java.io.DataOutputStream;
  11. import java.io.IOException;
  12. /**
  13. * Created with IntelliJ IDEA.
  14. * User: lastsweetop
  15. * Date: 13-7-5
  16. * Time: 上午1:26
  17. * To change this template use File | Settings | File Templates.
  18. */
  19. public class TestComparator {
  20. RawComparator<IntWritable> comparator;
  21. IntWritable w1;
  22. IntWritable w2;
  23. /**
  24. * 获得IntWritable的comparator,并初始化两个IntWritable
  25. */
  26. @Before
  27. public void init() {
  28. comparator = WritableComparator.get(IntWritable.class);
  29. w1 = new IntWritable(163);
  30. w2 = new IntWritable(76);
  31. }
  32. /**
  33. * 比较两个对象大小
  34. */
  35. @Test
  36. public void testComparator() {
  37. Assert.isTrue(comparator.compare(w1, w2) > 0);
  38. }
  39. /**
  40. * 序列号后进行直接比较
  41. * @throws IOException
  42. */
  43. @Test
  44. public void testcompare() throws IOException {
  45. byte[] b1 = serialize(w1);
  46. byte[] b2 = serialize(w2);
  47. Assert.isTrue(comparator.compare(b1, 0, b1.length, b2, 0, b2.length) > 0);
  48. }
  49. /**
  50. * 将一个实现了Writable接口的对象序列化成字节流
  51. *
  52. * @param writable
  53. * @return
  54. * @throws java.io.IOException
  55. */
  56. public static byte[] serialize(Writable writable) throws IOException {
  57. ByteArrayOutputStream out = new ByteArrayOutputStream();
  58. DataOutputStream dataOut = new DataOutputStream(out);
  59. writable.write(dataOut);
  60. dataOut.close();
  61. return out.toByteArray();
  62. }
  63. }

Writable、WritableComparable和comparators的更多相关文章

  1. hadoop中的序列化与Writable接口

    本文地址:http://www.cnblogs.com/archimedes/p/hadoop-writable-interface.html,转载请注明源地址. 简介 序列化和反序列化就是结构化对象 ...

  2. Hadoop开发相关问题

    总结自己在Hadoop开发中遇到的问题,主要在mapreduce代码执行方面.大部分来自日常代码执行错误的解决方法,还有一些是对Java.Hadoop剖析.对于问题,通过查询stackoverflow ...

  3. 分别使用Hadoop和Spark实现二次排序

    零.序(注意本部分与标题无太大关系,可直接调至第一部分) 既然没用为啥会有序?原因不想再开一篇文章,来抒发点什么感想或者计划了,就在这里写点好了: 前些日子买了几本书,打算学习和研究大数据方面的知识, ...

  4. 02Hadoop二次排序2

    案例: 数据: 邮编   |     日期     |金额 ILMN,2013-12-05,97.65GOOD,2013-12-09,1078.14IBM,2013-12-09,177.46ILMN, ...

  5. 01Hadoop二次排序

    我的目的: 示例: 2012,01,01,352011,12,23,-42012,01,01,432012,01,01,232011,12,23,52011,4,1,22011,4,1,56 结果: ...

  6. 解读:MultipleOutputs类

    //MultipleOutputs类用于简化多文件输出The MultipleOutputs class simplifies writing output data to multiple outp ...

  7. 详细讲解MapReduce二次排序过程

    我在15年处理大数据的时候还都是使用MapReduce, 随着时间的推移, 计算工具的发展, 内存越来越便宜, 计算方式也有了极大的改变. 到现在再做大数据开发的好多同学都是直接使用spark, hi ...

  8. 二次排序问题(分别使用Hadoop和Spark实现)

    不多说,直接上干货! 这篇博客里的算法部分的内容来自<数据算法:Hadoop/Spark大数据处理技巧>一书,不过书中的代码虽然思路正确,但是代码不完整,并且只有java部分的编程,我在它 ...

  9. 自定义Writable、RawComparatorWritable、comparators(转)

    自定义Writable hadoop虽然已经实现了一些非常有用的Writable,而且你可以使用他们的组合做很多事情,但是如果你想构造一些更加复杂的结果,你可以自定义Writable来达到你的目的,我 ...

随机推荐

  1. 【C++】动态内存与智能指针

    C++常见的内存分配方式有三种: 从静态存储区分配,这里主要是存储局部static对象,类的static成员以及定义在函数之外的变量: 从栈内存分配,这里主要是存储函数内的非static对象: 从堆内 ...

  2. C# 常用日期函数

    我想知道取的时期是几月.几日,然后做一些统计,上网找了一些方法. --DateTime 数字型 System.DateTime currentTime=new System.DateTime(); 1 ...

  3. Exception not a valid month

    oracle中的to_date('date','pattern') 其中的date和pattern格式应该要一样 SELECT to_date('2016-03-29 00:00:00','yyyy- ...

  4. Android 一个漂亮的Android日期和时间选择器:DateTimePicker

    DateTimePicker这个类库包含了漂亮的 DatePicker 和 TimePicker ,类似于在新 Google Agenda App中看到的. 项目主页:http://www.open- ...

  5. Vue.2.0.5-Vue 实例

    构造器 每个 Vue.js 应用都是通过构造函数 Vue 创建一个 Vue 的根实例 启动的: var vm = new Vue({ // 选项 }) 虽然没有完全遵循 MVVM 模式, Vue 的设 ...

  6. (Protype Pattern)原型模式

    定义: 原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象 适用性: 当我们系统中有一些类,在使用的时候都有同样需要大量的创建,而这样的创建是复杂的而且是浪费CPU,内存资源的 ...

  7. C++Primer 第三章

    //1.位于头文件中的代码一般不应该使用using声明.这是因为头文件的内容会拷贝到所有引用它的文件中,可能会产生始料未及的命名空间冲突. // 三种使用命名空间中的名字的方法 using names ...

  8. 网易免费邮件开启smtp教程

    网易免费邮件开启smtp教程     作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们在部署zabbix邮件报警中可能会用到163.com.那么我们如何去开启smtp服务呢? 1 ...

  9. AJAX简单的数据增删改与分页应用

    运行截图: PageBar.js: /* * 说明: * 整体思想,1.第一页时不显示:首页,上一页, * 2.最后一页时不显示:下一页,尾页 * 3.中间有 5 页导航, * 若:3.1.(总页数& ...

  10. URAL 1001 Reverse Root(水题?)

    The problem is so easy, that the authors were lazy to write a statement for it! Input The input stre ...