As we saw in the previous posts, Hadoop makes an heavy use of network transmissions for executing its jobs. As Doug Cutting (the creator of Hadoop) explaines in this post on the Lucene mailing list, java.io.Serializable is too heavy for Hadoop's needs and so a new interface has been developed: Writable. Every object you need to emit from mapper to reducers or as an output has to implement this interface in order to make Hadoop trasmit the data from/to the nodes in the cluster.

Hadoop comes with several wrappers around primitive types and widely used classes in Java:

Java primitive Writable implementation
boolean BooleanWritable
byte ByteWritable
short ShortWritable
int IntWritable
VIntWritable
float FloatWritable
long LongWritable
VLongWritable
double DoubleWritable
Java class Writable implementation
String Text
byte[] BytesWritable
Object ObjectWritable
null NullWritable
Java collection Writable implementation
array ArrayWritable
ArrayPrimitiveWritable
TwoDArrayWritable
Map MapWritable
SortedMap SortedMapWritable
enum EnumWritable

For example, if we need a mapper to emit a String, we need to use a Text object wrapped around the string we want to emit.

The interface Writable defines two methods:

  • public void write(DataOutput dataOutput) throws IOException
  • public void readFields(DataInput dataInput) throws IOException

The first method, write() is used for writing the data onto the stream, while the second method, readFields(), is used for reading data from the stream. The wrappers we saw above just send and receive their binary representation over a stream. 
Since Hadoop needs also to sort data while in the shuffle-and-sort phase, it needs also the Comparable interface to be implemented, so it defines the WritableComparable interface which is an interface that implements both Writable and Comparable. 
If we need to emit a custom object which has no default wrapper, we need to create a class that implements the WritableComparable interface. In the mean example we saw on this post, we used the SumCount class, which is a class that implements WritableComparable (the source code is available on github):

public class SumCount implements WritableComparable<SumCount> {

    DoubleWritable sum;
IntWritable count; public SumCount() {
set(new DoubleWritable(0), new IntWritable(0));
} public SumCount(Double sum, Integer count) {
set(new DoubleWritable(sum), new IntWritable(count));
} public void set(DoubleWritable sum, IntWritable count) {
this.sum = sum;
this.count = count;
} public DoubleWritable getSum() {
return sum;
} public IntWritable getCount() {
return count;
} public void addSumCount(SumCount sumCount) {
set(new DoubleWritable(this.sum.get() + sumCount.getSum().get()), new IntWritable(this.count.get() + sumCount.getCount().get()));
} @Override
public void write(DataOutput dataOutput) throws IOException { sum.write(dataOutput);
count.write(dataOutput);
} @Override
public void readFields(DataInput dataInput) throws IOException { sum.readFields(dataInput);
count.readFields(dataInput);
} @Override
public int compareTo(SumCount sumCount) { // compares the first of the two values
int comparison = sum.compareTo(sumCount.sum); // if they're not equal, return the value of compareTo between the "sum" value
if (comparison != 0) {
return comparison;
} // else return the value of compareTo between the "count" value
return count.compareTo(sumCount.count);
} @Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; SumCount sumCount = (SumCount) o; return count.equals(sumCount.count) && sum.equals(sumCount.sum);
} @Override
public int hashCode() {
int result = sum.hashCode();
result = 31 * result + count.hashCode();
return result;
}
}

As we can see, it's very easy to code the two methods defined by the Writable interface: they just call the write() and readFields() method of the primitive types of the properties of SumCount class; it's important setting the properties in the same order in both read() and writeFields(), otherwise it will not work. The other methods of this class are the getters, setters and the methods needed by the Comparable interface, which should be nothing new to a Java developer.

from: http://andreaiacono.blogspot.com/2014/05/implementing-writable-interface-of.html

实现Hadoop的Writable接口Implementing Writable interface of Hadoop的更多相关文章

  1. 如何实现多个接口Implementing Multiple Interface

    4.实现多个接口Implementing Multiple Interface 接口的优势:马克-to-win:类可以实现多个接口.与之相反,类只能继承一个超类(抽象类或其他类). A class c ...

  2. Hadoop中序列化与Writable接口

    学习笔记,整理自<Hadoop权威指南 第3版> 一.序列化 序列化:序列化是将 内存 中的结构化数据 转化为 能在网络上传输 或 磁盘中进行永久保存的二进制流的过程:反序列化:序列化的逆 ...

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

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

  4. Hadoop序列化与Writable接口(一)

    Hadoop序列化与Writable接口(一) 序列化 序列化(serialization)是指将结构化的对象转化为字节流,以便在网络上传输或者写入到硬盘进行永久存储:相对的反序列化(deserial ...

  5. Hadoop Serialization hadoop序列化详解(最新版) (1)【java和hadoop序列化比较和writable接口】

    初学java的人肯定对java序列化记忆犹新.最开始很多人并不会一下子理解序列化的意义所在.这样子是因为很多人还是对java最底层的特性不是特别理解,当你经验丰富,对java理解更加深刻之后,你就会发 ...

  6. eclipse 提交作业到JobTracker Hadoop的数据类型要求必须实现Writable接口

    问:在eclipse中的写的代码如何提交作业到JobTracker中的哪?答:(1)在eclipse中调用的job.waitForCompletion(true)实际上执行如下方法 connect() ...

  7. Hadoop基础-序列化与反序列化(实现Writable接口)

    Hadoop基础-序列化与反序列化(实现Writable接口) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.序列化简介 1>.什么是序列化 序列化也称串行化,是将结构化 ...

  8. Hadoop序列化与Writable接口(二)

    Hadoop序列化与Writable接口(二) 上一篇文章Hadoop序列化与Writable接口(一)介绍了Hadoop序列化,Hadoop Writable接口以及如何定制自己的Writable类 ...

  9. hadoop学习第四天-Writable和WritableComparable序列化接口的使用&&MapReduce中传递javaBean的简单例子

    一. 为什么javaBean要继承Writable和WritableComparable接口? 1. 如果一个javaBean想要作为MapReduce的key或者value,就一定要实现序列化,因为 ...

随机推荐

  1. Signalr信息推送

    前序 距离上次写文章,差不多已经大半年了.感觉自己越来越懒了,即使有时候空闲下来了,也不想动.前面买了一系列的Python的书,基础的看了大概有四分之一,剩下的基本上还未动,晚上回去也只是吃饭看电影. ...

  2. Python并发编程-IO模型-非阻塞IO实现SocketServer

    Server.py import socket sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.setblocking(False) #把soc ...

  3. NetStandard类库实现Log4Net集成

    前面都是Log4Net集成到NetCore项目中,集成到NetStandard类库还是第一次,所以记录一下 小提示:NetStandard要想同时被NetCore和NetFramework调用,需要在 ...

  4. 【SQL】181. Employees Earning More Than Their Managers

    The Employee table holds all employees including their managers. Every employee has an Id, and there ...

  5. python opencv3 圆检测

    git:https://github.com/linyi0604/Computer-Vision # coding:utf8 import cv2 import numpy as np img_ori ...

  6. 机器学习之路: python 线性回归LinearRegression, 随机参数回归SGDRegressor 预测波士顿房价

    python3学习使用api 线性回归,和 随机参数回归 git: https://github.com/linyi0604/MachineLearning from sklearn.datasets ...

  7. ZOJ 2819 Average Score 牡丹江现场赛A题 水题/签到题

    ZOJ 2819 Average Score Time Limit: 2 Sec  Memory Limit: 60 MB 题目连接 http://acm.zju.edu.cn/onlinejudge ...

  8. 移动端适配之雪碧图(sprite)背景图片定位

    为了减少网络请求个数量,提高网站的访问速度,我们一般都会把一些小的图片合并成一张sprite图,然后根据background-position来进行定位.在web端由于是固定的大小与left .top ...

  9. C#设计模式泛型注入

    TSFac注入方式: 泛型接口工厂: public class SFac<TInterface, TClass> where TInterface : class where TClass ...

  10. SQL(insert、delete、update)执行成功,但是数据库表中无显示无记录

    如题,程序中insert一条记录,调试过程中根据执行结果发现此条sql已经执行成功(影响行数为1且插入记录已生成自增主键正确值),但是查询数据库相应表时发现表中并无相应记录,通过直接在表中插入测试数据 ...