Hadoop Serialization -- hadoop序列化详解 (3)【ObjectWritable,集合Writable以及自定义的Writable】
回顾:
woDArrayWritable 的使用都必须实例化相同的类,这是在构造时指定的,如下所示:
ArrayWritable 足够了,但是存储不间的类型在一个单列表中,可以使用GenericWritable 封装到ArrayWritable 中。同时,也可以用MapWritable 的思路写一个通用的ListWritable。
Writable 应用已得到很好的优化,但为了对付更复杂的结构, 最好创建一个新的Writable 类型,而不是使用已有的类型。为了横示如何创建一个自定义的Writable ,我们编写了一个表示一对字符串的实现,名为TextPair:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
// cc TextPair A Writable implementation that stores a pair of Text objects// cc TextPairComparator A RawComparator for comparing TextPair byte representations// cc TextPairFirstComparator A custom RawComparator for comparing the first field of TextPair byte representations// vv TextPairimport java.io.*;import org.apache.hadoop.io.*;public class TextPair implements WritableComparable<TextPair> { private Text first; private Text second; //* 必须有默认的构造器皿,这样Mapreduce方法才能创建对象,然后通过readFields方法从序列化的数据流中读出进行赋值 public TextPair() { set(new Text(), new Text()); } public TextPair(String first, String second) { set(new Text(first), new Text(second)); } public TextPair(Text first, Text second) { set(first, second); } public void set(Text first, Text second) { this.first = first; this.second = second; } public Text getFirst() { return first; } public Text getSecond() { return second; }/** @Override public void write(DataOutput out) throws IOException { first.write(out); second.write(out); } //同上调用成员对象本身的readFields方法,从输入流中反序列化每一个成员对象
@Override public void readFields(DataInput in) throws IOException { first.readFields(in); second.readFields(in); } /*MapReduce需要一个分割者(Partitioner)把map的输出作为输入分成一块块的喂给多个reduce)
* 默认的是HashPatitioner,他是通过对象的hashcode函数进行分割,所以hashCode的好坏决定 * 了分割是否均匀,他是一个很关键性的方法。 /
@Override public int hashCode() { return first.hashCode() * 163 + second.hashCode(); } @Override public boolean equals(Object o) { if (o instanceof TextPair) { TextPair tp = (TextPair) o; return first.equals(tp.first) && second.equals(tp.second); } return false; } //* 如果你想自定义TextOutputformat作为输出格式时的输出,你需要重写toString方法
@Override public String toString() { return first + "\t" + second; } // * implements WritableComparable必须要实现的方法,用于比较 排序 @Override public int compareTo(TextPair tp) { int cmp = first.compareTo(tp.first); if (cmp != 0) { return cmp; } return second.compareTo(tp.second); } } |
是易变的、经常重用的,所以我们应该尽量避免在write() 或readFields ()方法中分配对象。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
public static class Comparator extends WritableComparator {private static final Text.Comparator TEXT_COMPARATOR = new Text.Comparator();public Comparator() { super(TextPair.class);}@Overridepublic int compare(byte[] b1, int s1, int l1,byte[] b2, int s2, int l2) {try { /**
* Text是标准的UTF-8字节流,
* 由一个变长整形开头表示Text中文本所需要的长度,接下来就是文本本身的字节数组
* decodeVIntSize返回变长 整形的长度,readVInt 表示 文本字节数组的长度,加起来就是第一个成员first的长度
*/
int firstL1 = WritableUtils.decodeVIntSize(b1[s1]) + readVInt(b1, s1);int firstL2 = WritableUtils.decodeVIntSize(b2[s2]) + readVInt(b2, s2);int cmp = TEXT_COMPARATOR.compare(b1, s1, firstL1, b2, s2, firstL2);//首先比较first if (cmp != 0) { return cmp; }//如果first一样,那就比较second second的位置要在s1的位置上加firstL1,长度要总长度减去第一个first的长度
return TEXT_COMPARATOR.compare(b1, s1 + firstL1, l1 - firstL1, b2, s2 + firstL2, l2 - firstL2);} catch (IOException e) { throw new IllegalArgumentException(e);}}}static { WritableComparator.define(TextPair.class, new Comparator());//定义我们compare用哪个} |
画了一个简图帮助大家理解:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
// cc TextPair A Writable implementation that stores a pair of Text objects// cc TextPairComparator A RawComparator for comparing TextPair byte representations// cc TextPairFirstComparator A custom RawComparator for comparing the first field of TextPair byte representations// vv TextPairimport java.io.*;import org.apache.hadoop.io.*;public class TextPair implements WritableComparable<TextPair> { private Text first; private Text second; //* 必须有默认的构造器皿,这样Mapreduce方法才能创建对象,然后通过readFields方法从序列化的数据流中读出进行赋值 public TextPair() { set(new Text(), new Text()); } public TextPair(String first, String second) { set(new Text(first), new Text(second)); } public TextPair(Text first, Text second) { set(first, second); } public void set(Text first, Text second) { this.first = first; this.second = second; } public Text getFirst() { return first; } public Text getSecond() { return second; }/** * 通过成员对象本身的write方法,序列化每一个成员对象到输出流中 @Override public void write(DataOutput out) throws IOException { first.write(out); second.write(out); } //同上调用成员对象本身的readFields方法,从输入流中反序列化每一个成员对象
@Override public void readFields(DataInput in) throws IOException { first.readFields(in); second.readFields(in); } /*MapReduce需要一个分割者(Partitioner)把map的输出作为输入分成一块块的喂给多个reduce)
* 默认的是HashPatitioner,他是通过对象的hashcode函数进行分割,所以hashCode的好坏决定 * 了分割是否均匀,他是一个很关键性的方法。 /
@Override public int hashCode() { return first.hashCode() * 163 + second.hashCode(); } @Override public boolean equals(Object o) { if (o instanceof TextPair) { TextPair tp = (TextPair) o; return first.equals(tp.first) && second.equals(tp.second); } return false; } //* 如果你想自定义TextOutputformat作为输出格式时的输出,你需要重写toString方法
@Override public String toString() { return first + "\t" + second; } // * implements WritableComparable必须要实现的方法,用于比较 排序 @Override public int compareTo(TextPair tp) { int cmp = first.compareTo(tp.first); if (cmp != 0) { return cmp; } return second.compareTo(tp.second); } // ^^ TextPair // vv TextPairComparator public static class Comparator extends WritableComparator { private static final Text.Comparator TEXT_COMPARATOR = new Text.Comparator(); public Comparator() { super(TextPair.class); } @Override public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) { try { int firstL1 = WritableUtils.decodeVIntSize(b1[s1]) + readVInt(b1, s1); int firstL2 = WritableUtils.decodeVIntSize(b2[s2]) + readVInt(b2, s2); int cmp = TEXT_COMPARATOR.compare(b1, s1, firstL1, b2, s2, firstL2); if (cmp != 0) { return cmp; } return TEXT_COMPARATOR.compare(b1, s1 + firstL1, l1 - firstL1, b2, s2 + firstL2, l2 - firstL2); } catch (IOException e) { throw new IllegalArgumentException(e); } } } static { WritableComparator.define(TextPair.class, new Comparator());//注册WritableComparator } // ^^ TextPairComparator // vv TextPairFirstComparator自定义实现的comparator public static class FirstComparator extends WritableComparator { private static final Text.Comparator TEXT_COMPARATOR = new Text.Comparator(); public FirstComparator() { super(TextPair.class); } @Override public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) { try { int firstL1 = WritableUtils.decodeVIntSize(b1[s1]) + readVInt(b1, s1); int firstL2 = WritableUtils.decodeVIntSize(b2[s2]) + readVInt(b2, s2); return TEXT_COMPARATOR.compare(b1, s1, firstL1, b2, s2, firstL2); } catch (IOException e) { throw new IllegalArgumentException(e); } } @Override public int compare(WritableComparable a, WritableComparable b) { if (a instanceof TextPair && b instanceof TextPair) { return ((TextPair) a).first.compareTo(((TextPair) b).first); } return super.compare(a, b); } } // ^^ TextPairFirstComparator // vv TextPair}// ^^ TextPair |
Hadoop Serialization -- hadoop序列化详解 (3)【ObjectWritable,集合Writable以及自定义的Writable】的更多相关文章
- hadoop应用开发技术详解
<大 数据技术丛书:Hadoop应用开发技术详解>共12章.第1-2章详细地介绍了Hadoop的生态系统.关键技术以及安装和配置:第3章是 MapReduce的使用入门,让读者了解整个开发 ...
- 《Hadoop应用开发技术详解》
<Hadoop应用开发技术详解> 基本信息 作者: 刘刚 丛书名: 大数据技术丛书 出版社:机械工业出版社 ISBN:9787111452447 上架时间:2014-1-10 出版日期:2 ...
- Hadoop Hive sql语法详解
Hadoop Hive sql语法详解 Hive 是基于Hadoop 构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据,可以将结构 化的数据文件 ...
- Hadoop生态圈-Kafka配置文件详解
Hadoop生态圈-Kafka配置文件详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.默认kafka配置文件内容([yinzhengjie@s101 ~]$ more /s ...
- Hadoop基础-Idea打包详解之手动添加依赖(SequenceFile的压缩编解码器案例)
Hadoop基础-Idea打包详解之手动添加依赖(SequenceFile的压缩编解码器案例) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.编辑配置文件(pml.xml)(我 ...
- 详解如何在Laravel中增加自定义全局函数
http://www.php.cn/php-weizijiaocheng-383928.html 如何在Laravel中增加自定义全局函数?在我们的应用里经常会有一些全局都可能会用的函数,我们应该怎么 ...
- Hadoop MapReduce执行过程详解(带hadoop例子)
https://my.oschina.net/itblog/blog/275294 摘要: 本文通过一个例子,详细介绍Hadoop 的 MapReduce过程. 分析MapReduce执行过程 Map ...
- 【大数据】Linux下安装Hadoop(2.7.1)详解及WordCount运行
一.引言 在完成了Storm的环境配置之后,想着鼓捣一下Hadoop的安装,网上面的教程好多,但是没有一个特别切合的,所以在安装的过程中还是遇到了很多的麻烦,并且最后不断的查阅资料,终于解决了问题,感 ...
- hadoop之hdfs命令详解
本篇主要对hadoop命令和hdfs命令进行阐述,yarn命令会在之后的文章中体现 hadoop fs命令可以用于其他文件系统,不止是hdfs文件系统内,也就是说该命令的使用范围更广可以用于HDFS. ...
随机推荐
- Electron中git, npm,webpack使用
开始学习Electron的时候用到git, 记录学习一下, 学习地址是: https://zhuanlan.zhihu.com/p/20225295?columnSlug=FrontendMagazi ...
- Unity3D开发之Matrix4x4矩阵变换
在Unity开发中时常会用到Matrix4x4矩阵来变换场景中对象的位置.旋转和缩放.但是很多人都不太理解这儿Matrix4x4变换矩阵.通过DX中的变换矩阵我来讲一讲在unity中这个变换矩阵是怎么 ...
- JavaScript test//href
目录 JavaScript test//href JavaScript test//href href 其实这个问题并不属于这里的.但是呢,由于一天晚上因为这个问题扰我"一夜不能眠" ...
- xcode加载静态链接库.a文件总是失败
明明项目是对的,代码没有问题,并且把项目作为库项目引入到新项目中没问题,可是一旦把项目编译出.a文件,引入到新项目中不知为何会有几率出现一大堆错误,其实是xcode的缓存机制在作怪,去这个目录: /U ...
- Python基本特殊方法之__new__
__new__()和不可变对象 __new__方法的一个用途是初始化不可变对象,__new()__方法中允许创建未初始化的对象,这允许我们在__init__()方法被调用之前先设置对象的属性 例:为f ...
- asp.net core mcroservices 架构之 分布式日志(三):集成kafka
一 kafka介绍 kafka是基于zookeeper的一个分布式流平台,既然是流,那么大家都能猜到它的存储结构基本上就是线性的了.硬盘大家都知道读写非常的慢,那是因为在随机情况下,线性下,硬盘的读写 ...
- ajax传递数组后台接收不到值的问题
背景: JQGrid需要进行批量删除操作传给后台的是数组,结果后台接收不到值. 后台语言:java 原因: ajax传递参数时,traditional 默认为false,JQuery会深度序列化参数对 ...
- 剑指offer-第五章优化时间和空间效率(从1到n的整数中1出现的次数)
题目:输入一个整数n,从1到n这n个十进制整数中1出现的次数. 思路1:对1到n中的任意一个数i对其进行求余数来判断个位是否为1,然后再求除数,判断十位是否为1.统计出1的个数.然后对1到n用一个循环 ...
- SharePoint 创建列表并使用Windows Presentation Foundation应用程序管理列表
SharePoint创建列表并使用程序管理列表 列表是SharePoint开发者输入数据的方式之中的一个.使用Web界面创建一个列表并加入一些数据.过程例如以下: 1. 打开站点. 2 ...
- bzoj 4453 cys就是要拿英魂!——后缀数组+单调栈+set
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4453 询问离线,按R排序. 发现直接用 rk[ ] 的错误情况就是前面的某个位置 j 和自己 ...