一、概述

1.1、什么是序列化

序列化就是把内存中的对象,转换成字节序列(或其他数据传输协议)以便 于存储到磁盘(持久化)和网络传输。
反序列化就是将收到字节序列(或其他数据传输协议)或者是磁盘的持久化数据,转换成内存中的对象。

1.2、为什么要序列化

一般来说,“活的”对象只生存在内存里,关机断电就没有了。而且“活的” 对象只能由本地的进程使用,不能被发送到网络上的另外一台计算机。 然而 序列化可以存储“活的”对象,可以将“活的”对象发送到远程计算机

1.3、为什么不用Java的序列化

Java的序列化是一个重量级序列化框架(Serializable),一个对象被序列化后,会附带很多额外的信息(各种校验信息,Header,继承体系等),不便于在网络中高效传输。所以,Hadoop自己开发了一套序列化机制(Writable)。

Hadoop序列化特点:

  • 紧凑 :高效使用存储空间
  • 快速:读写数据的额外开销小
  • 可扩展:随着通信协议的升级而可升级
  • 互操作:支持多语言的交互

二、序列化案例

2.1、自定义对象直接实现java的Serializable

2.2、实现Hadoop的序列化接口(Writable)

具体实现 bean 对象序列化步骤如下 7 步:

  • 必须实现 Writable 接口
  • 反序列化时,需要反射调用空参构造函数,所以必须有空参构造

  • 重写序列化方法

  • 重写反序列化方法

  • 注意反序列化的顺序和序列化的顺序完全一致

  • 要想把结果显示在文件中,需要重写 toString(),可用”\t”分开,方便后续用。
  • 如果需要将自定义的 bean 放在 key 中传输,则还需要实现 Comparable 接口,因为MapReduce 框中的 Shuffle 过程要求对 key 必须能排序。

案例:

  1. // 1 实现 writable 接口
  2. public class FlowBean implements Writable{
  3. private long upFlow;
  4. private long downFlow;
  5. private long sumFlow;
  6. //2 反序列化时,需要反射调用空参构造函数,所以必须有
  7. public FlowBean() {
  8. super();
  9. }
  10. public FlowBean(long upFlow, long downFlow) {
  11. super();
  12. this.upFlow = upFlow;
  13. this.downFlow = downFlow;
  14. this.sumFlow = upFlow + downFlow;
  15. }
  16. //3 重写序列化方法
  17. @Override
  18. public void write(DataOutput out) throws IOException {
  19. out.writeLong(upFlow);
  20. out.writeLong(downFlow);
  21. out.writeLong(sumFlow);
  22. }
  23. //4 重反序列化方法
  24. //5 反序列化方法读顺序必须和写序列化方法的写顺序必须一致
  25. @Override
  26. public void readFields(DataInput in) throws IOException {
  27. this.upFlow = in.readLong();
  28. this.downFlow = in.readLong();
  29. this.sumFlow = in.readLong();
  30. }
  31. // 6 编写 toString 方法,方便后续打印到文本 @Override
  32. public String toString() {
  33. return upFlow + "\t" + downFlow + "\t" + sumFlow;
  34. }
  35. public long getUpFlow() {
  36. return upFlow;
  37. }
  38. public void setUpFlow(long upFlow) {
  39. this.upFlow = upFlow;
  40. }
  41. public long getDownFlow() {
  42. return downFlow;
  43. }
  44. public void setDownFlow(long downFlow) {
  45. this.downFlow = downFlow;
  46. }
  47. public long getSumFlow() {
  48. return sumFlow;
  49. }
  50. public void setSumFlow(long sumFlow) {
  51. this.sumFlow = sumFlow;
  52. }
  53. }