Hadoop-2.4.1学习之Writable及事实上现
Hadoop基于DataInput和DataOutput实现了简单、高效的序列化协议,而Writable接口定义了Hadoop序列化的方法,MapReduce框架中的不论什么键值类型都实现了该接口,比方IntWritable、LongWritable等,具体的类关系见下图:
通过上图可以发现,MapReduce中经常使用的键值类型都没有直接实现Writable接口,而是实现了该接口的子接口WritableComparable,该子接口还继承了Comparable接口,这意味着实现类除了可以序列化和发序列化外,还可以彼此进行比較,这是由于当这些类做为键在MapReduce中使用时,在排序阶段须要对其进行比較排序。但这并非说假设实现自己定义的序列化类时,必须实现WritableComparable接口,仅当自己定义的序列化类也用作键时才必须实现该接口,假设仅是做为值使用的话,仅实现Writable接口就可以。
当自己定义的序列化类用做键时,须要考虑到在依据键进行分区时经经常使用到hashCode()方法,因此须要确保该方法在不同的JVM实例中返回同样的结果,而Object对象中默认的hashCode()方法不可以满足该特性,所以在实现自己定义类时须要重写hashCode()方法,而假设两个对象依据equals()方法是相等的,那么二者的hashCode()返回值也必须同样,因此在重写hashCode()的时候,有必要重写equals(Object obj)方法。
除了上图中实现WritableComparable的类外,还有若干类直接实现了Writable接口,比方ObjectWritable,一个多态的Writable,该类不使用Writable封装就行处理数组、字符串和其他Java基本类型。还有Writable集合类:ArrayWritable、EnumSetWritable、MapWritable、TwoDArrayWritable、SortedMapWritable。当中ArrayWritable是对同样Writable类型的数组的封装,也就是该类中Writable的类型必须同样,是IntWritable都是IntWritable,不能既有IntWritable也有LongWritable。TwoDArrayWritable是对二维数组即矩阵的封装,同样该类中Writable的类型也必须同样。EnumSetWritable是对EnumSet封装的Writable,MapWritable实现了Map<Writable,Writable>接口,SortedMapWritable实现了SortedMap<WritableComparable,Writable>接口,二者当然也都实现了Writable接口,在二者的内部实现中,使用Byte类型指示指定的类型,因此在一个Map实例中最多仅仅能有127个不同的类:
/* Class to id mappings */
@VisibleForTesting
Map<Class, Byte> classToIdMap = new ConcurrentHashMap<Class, Byte>();
/* Id to Class mappings */
@VisibleForTesting
Map<Byte, Class> idToClassMap = new ConcurrentHashMap<Byte, Class>();
如今通过分析IntWritable和Text的源码来学习怎样编写Writable以及WritableComparable,首先是IntWritable的源码:
public class IntWritable implements WritableComparable<IntWritable> {
private int value;
public IntWritable() {}
public IntWritable(int value) { set(value); }
/** Set the value of this IntWritable. */
public void set(int value) { this.value = value; }
/** Return the value of this IntWritable. */
public int get() { return value; }
@Override
//重写Writable中的readFields(DataInput in)
public void readFields(DataInput in) throws IOException {
value = in.readInt();
}
@Override
//重写Writable中的write(DataOutput out)
public void write(DataOutput out) throws IOException {
out.writeInt(value);
}
/** Returns true if <code>o</code> is a IntWritable with the same value. */
@Override
public boolean equals(Object o) {
if (!(o instanceof IntWritable))
return false;
IntWritable other = (IntWritable)o;
return this.value == other.value;
}
@Override
public int hashCode() {
return value;
}
/** Compares two IntWritables. */
@Override
//重写Comparable接口中的compareTo方法
public int compareTo(IntWritable o) {
int thisValue = this.value;
int thatValue = o.value;
return (thisValue<thatValue ? -1 : (thisValue==thatValue ? 0 : 1));
}
@Override
public String toString() {
return Integer.toString(value);
}
//此处省略了继承自WritableComparator的内部类Comparator
static { // register this comparator
WritableComparator.define(IntWritable.class, new Comparator());
}
}
IntWritable的源码相对来说还是比較简单的,除了实现接口中的方法外,还重写了hashCode、equals和toString方法,这也是要注意的一点。其次是Text类,Text将字符串存储为标准UTF8编码,提供了在字节层次序列化、反序列化和比較字符串的方法,比方decode(byte[]utf8)、encode(String string)、readFields(DataInput in)、write(DataOutput out)等。该类除了实现WritableComparable外,还继承自BinaryComparable抽象类,当中实现的方法例如以下:
private byte[] bytes;
private int length;
@Override
public void readFields(DataInput in) throws IOException {
//从输入流中读取整数值,很多其他工具方法可參考WritableUtils工具类
int newLength = WritableUtils.readVInt(in);
setCapacity(newLength, false);
//向bytes中读入长度为newLength的数据
in.readFully(bytes, 0, newLength);
length = newLength;
}
@Override
public void write(DataOutput out) throws IOException {
WritableUtils.writeVInt(out, length);
out.write(bytes, 0, length);
}
@Override
public int compareTo(BinaryComparable other) {
if (this == other)
return 0;
return WritableComparator.compareBytes(getBytes(), 0, getLength(),
other.getBytes(), 0, other.getLength());
}
总结IntWritable和Text类的实现,可以据此实现自定的WritableComparable,以下就是一个简单的演示样例。在该演示样例中使用name和age做为联合键,仅仅有在二者都同样的情况下才觉得是一个对象。
public class CompositeWritable implements WritableComparable<CompositeWritable>{
private String name;
private int age;
public CompositeWritable(){}
public CompositeWritable(String name, int age){
set(name, age);
}
@Override
public void readFields(DataInput in) throws IOException {
name = in.readUTF();
age = in.readInt();
}
@Override
public void write(DataOutput out) throws IOException {
out.writeUTF(name);
out.writeInt(age);
}
@Override
public int compareTo(CompositeWritable o) {
int cmp = name.compareTo(o.getName());
if(cmp != 0)
return cmp;
return age < o.getAge()? -1:(age == o.getAge()? 0 : 1);
}
@Override
public boolean equals(Object o) {
if(o instanceof CompositeWritable){
CompositeWritable other = (CompositeWritable)o;
return this.name.equals(other.name) && this.age == other.age;
}
return false;
}
@Override
public int hashCode() {
return name.hashCode() + age;
}
@Override
public String toString() {
return name + "\t" + age;
}
public void set(String name, int age){
this.name = name;
this.age = age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
}
Hadoop-2.4.1学习之Writable及事实上现的更多相关文章
- eclipse 提交作业到JobTracker Hadoop的数据类型要求必须实现Writable接口
问:在eclipse中的写的代码如何提交作业到JobTracker中的哪?答:(1)在eclipse中调用的job.waitForCompletion(true)实际上执行如下方法 connect() ...
- 开启Hadoop和Spark的学习之路
Hadoop Hadoop是一个由Apache基金会所开发的分布式系统基础架构. 用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力进行高速运算和存储. Hadoop实现了一个 ...
- Hadoop 2.2.0学习笔记20131210
伪分布式单节点安装执行pi失败: [root@server- ~]# ./bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples ...
- Hadoop 2.2.0学习笔记20131209
1.下载java 7并安装 [root@server- ~]# rpm -ivh jdk-7u40-linux-x64.rpm Preparing... ####################### ...
- hadoop自带TestDFSIO学习
hadoop系统中,包含了很多测试工具包,如测试mapreduce系统读写文件系统,有testDFSIO工具 首先安装好hadoop,配置好环境变量 进入share目录下的mapreduce目录下面, ...
- Hadoop学习---Hadoop的HBase的学习
Hbase Hbase的特点: Hbase是bigtable的开源的仿制版本 建立在HDFS之上 可靠性,靠性能 大:一个表可以有上亿行,上百万列 面向列:面向列(族)的存储和权限控制,列(族)独立检 ...
- MR hadoop streaming job的学习 combiner
代码已经拷贝到了公司电脑的: /Users/baidu/Documents/Data/Work/Code/Self/hadoop_mr_streaming_jobs 首先是主控脚本 main.sh 调 ...
- [Spring Data Repositories]学习笔记--使用现有的repository
以下内容是在学习Spring-Data-mongoDB中的Spring Data Repositories时做的一些笔记.备忘! 感觉学习还是看官方的资料比较透彻一些. Spring Data Rep ...
- [Hadoop] Hadoop学习历程 [持续更新中…]
1. Hadoop FS Shell Hadoop之所以可以实现分布式计算,主要的原因之一是因为其背后的分布式文件系统(HDFS).所以,对于Hadoop的文件操作需要有一套全新的shell指令来完成 ...
随机推荐
- iOS pragma mark要使用
郝萌主倾心贡献,尊重作者的劳动成果.请勿转载. 假设文章对您有所帮助.欢迎给作者捐赠.支持郝萌主,捐赠数额任意.重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 简单的来说 ...
- 【j2ee spring】30、巴巴荆楚网-综合hibernate4+spring4(5)分页
巴巴荆楚网-综合hibernate4+spring4(5)分页 1.图文项目 2.首先我们引入对应的jar包 3.我们配置一下数据库中对应的实体对象 ProductType.java /** * 功能 ...
- SDUT oj 3005 打怪升级(内存搜索)
当比赛一直纠缠骑2如何做一个非常大的数量,数组不开啊...后来他们发现自己很傻啊,该数不超过最大10什么,这个上限就是力量100什么.. .. 其它的就是记忆化搜索啊,还有就是加一点力量的瓶子当时就要 ...
- 开始的iOS编程之前的准备
原地址:http://www.appcoda.com/what-you-need-to-begin-ios-programming/ 1.准备一台苹果设备 这段基本是废话,我就不翻译了,IOS开发你懂 ...
- 开玩笑html5(五岁以下儿童)---绕地球月球,地球绕太阳运动(canvas实现,同样可以移动哦)
请珍惜劳动小编成果,这篇文章是原来小编,转载请注明出处. 速度的參数与真实速度有点差距.大家能够自行调整 <!DOCTYPE html> <html> <head> ...
- BZOJ 2947 Poi2000 促销 set
标题效果:特定n天,首先插入一些每天.然后去掉最高值和最低值,要付出最大的值-至少值价格.乞讨n总天数支付的价格 堆/段树/平衡树光秃秃的标题 #include <set> #includ ...
- whu oj 1551 Pairs (莫队算法)
problem_id=1551">题目链接 题目大意: 给出的询问,求出这个区间的里 差小于等于 2 的数字的对数. 思路分析: 莫队算法. 然后分析一下. 假设添加了一个数字.那么就 ...
- Rational Rose 2007使用小结
1.Rose怎样隐藏类的属性和操作? 右击类,选Options->Suppress Attributes/Suppress Operations 2.Rose怎样表示类的约束? 在工具箱中选AB ...
- 翻译器DIY它———算在英文文本中的单词数,字符和行数
咳咳.这部分应该是序列化编译器DIY的,然而,在这样做DIY第一次使用前flex 为了练练手,对于后者的理解是有帮助. 在word 我经常看到一个字计数功能,因此,它是如何实现,当然,首先想到的是要经 ...
- mysql子查询慢的问题
当你在用explain工具查看sql语句的运行计划时.若select_type 字段中出现"DEPENDENT SUBQUERY"时,你要注意了.你已经掉入了mysql子查询慢 ...