教程索引目录请访问:《大数据技术入门级系列教程》
上一节我们讲了编程的方式使用 MapReduce,在其中我们第一次接触了到 Writable 类,本节就大概讲一下 Writable 类是干嘛的。
序列化的需求
Hadoop 是分布式的框架,这就意味着数据需要在各个节点之间流转或者到硬盘上存取,这就需要将内存中的对象序列化,然后再反序列化,这部分工作会非常多,所以 Hadoop 需要高效的序列化和反序列化机制,这就是 Writable 类。
在 Java 中有 Serializable 接口,用于对象的序列化和反序列化,但这个接口在把对象序列化和反序列化的时候会附带很多额外的信息,比如各种校验信息、继承信息等,在网络IO和磁盘IO中去存储和传输这些信息很不划算,没有必要,所以 Hadoop 搞出了 Writable 类来存储对象。
Hadoop 中的 Writable 类
上一篇中我们使用了LongWritable、Text、IntWritable,其实还有BooleanWritable、ByteWritable、FloatWritabl、DoubleWritable,下面是个简单的关系表:
| Java 基本类型 | Writable 实现 | 字节 |
|---|---|---|
| boolean | BooleanWritable | 1 |
| byte | ByteWritable | 1 |
| int | IntWritable | 4 |
| float | FloatWritable | 4 |
| long | LongWritable | 8 |
| double | DoubleWritable | 8 |
创建自己的 Writable 类
Hadoop 提供给我们的只是基础的几类,我们可能还需要更多类型的支持,就需要自定义一个对象实现 Writable 接口,这也很简单,只需要实现 org.apache.hadoop.io.Writable 接口,并实现里面的 write 和 readFields方法,例如这样:
package net.renfei.hadoop.entity;
import org.apache.hadoop.io.Writable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
/**
* Title: DemoEntity
* Description:
*
* @author RenFei
*/
public class DemoEntity implements Writable {
private String ip;
private String path;
private int port;
/**
* 序列化方法
*
* @param dataOutput 框架给我们的数据出口
* @throws IOException
*/
public void write(DataOutput dataOutput) throws IOException {
dataOutput.writeUTF(ip);
dataOutput.writeUTF(path);
dataOutput.writeInt(port);
}
/**
* 反序列化方法
*
* @param dataInput 框架给我们的数据来源
* @throws IOException
*/
public void readFields(DataInput dataInput) throws IOException {
ip = dataInput.readUTF();
path = dataInput.readUTF();
port = dataInput.readInt();
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
}
需要注意的是:write中的顺序需要和readFields中的顺序一致。
这个时候我们就可以在 Hadoop 框架中使用我们自己的 DemoEntity 进行输入输出数据了。