Hadoop序列化

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

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

因为Java自带的序列化存储了很多额外信息(各种校验、Header、继承体系等),是一个重量级序列化框架,不便于在网络中传输,所以Hadoop有自己的一套序列化。

Hadoop序列化的特点:

  • 紧凑:存储空间少
  • 快速:传输速度快
  • 互操作性:支持多语言的交互

实际开发中,Hadoop自带的TextIntWritable等基本的序列化类型往往不够用,需要自定义一些可序列化的 JavaBean。

自定义需要序列化的类:

  1. 必须实现Writable接口
  2. 反序列化时,需要反射调用空参构造函数,所以必须要有空参构造
  3. 实现序列化方法write()
  4. 实现反序列化方法readFields()
  5. 注意反序列化顺序要和序列化的顺序完全一致(先进先出)
  6. 如果想把结果显示在文件中,还需要重写 toString()方法
  7. 如果要把自定义的类的对象放在key中传输,则还需要实现 Comparable接口,因为MapReduce框架中的Shuffle过程要求key必须能够排序

示例:

  1. package com.study.mapreduce.writable;
  2. import org.apache.hadoop.io.Writable;
  3. import java.io.DataInput;
  4. import java.io.DataOutput;
  5. import java.io.IOException;
  6. public class MyWritable implements Writable,Comparable<MyWritable> {
  7. private Integer id;
  8. private Long scale;
  9. private Integer age;
  10. /**
  11. * 需要有无参构造器
  12. */
  13. public MyWritable() {
  14. }
  15. /**
  16. * 序列化
  17. * @param out
  18. * @throws IOException
  19. */
  20. @Override
  21. public void write(DataOutput out) throws IOException {
  22. out.writeInt(id);
  23. out.writeLong(scale);
  24. out.writeInt(age);
  25. }
  26. /**
  27. * 反序列化
  28. * @param in
  29. * @throws IOException
  30. */
  31. @Override
  32. public void readFields(DataInput in) throws IOException {
  33. // 读取顺序要和write方法写的顺序一致,即先进先出
  34. id = in.readInt();
  35. scale = in.readLong();
  36. age = in.readInt();
  37. }
  38. /**
  39. * 如果想当做key在MapReduce中传输,需要实现Comparable,因为Shuffle过程要求key必须能排序
  40. * @param o
  41. * @return
  42. */
  43. @Override
  44. public int compareTo(MyWritable o) {
  45. return this.id > o.getId() ? -1 : 1;
  46. }
  47. /**
  48. * 为方便查看,还可以重写toString()方法
  49. * @return
  50. */
  51. @Override
  52. public String toString() {
  53. MessageFormat mf = new MessageFormat("MyWritable:{id:[0], scale:[1], age:[2]}");
  54. return mf.format(new Object[]{id, scale, age});
  55. }
  56. // 生成getter/setter
  57. public Integer getId() {
  58. return id;
  59. }
  60. public void setId(Integer id) {
  61. this.id = id;
  62. }
  63. public Long getScale() {
  64. return scale;
  65. }
  66. public void setScale(Long scale) {
  67. this.scale = scale;
  68. }
  69. public Integer getAge() {
  70. return age;
  71. }
  72. public void setAge(Integer age) {
  73. this.age = age;
  74. }
  75. }