Hadoop中有一套Writable实现可以满足大部分需求,但是在有些情况下,我们需要根据自己的需要构造一个新的实现,有了定制的Writable,我们就可以完全控制二进制表示和排序顺序。

为了演示如何新建一个定制的writable类型,我们需要写一个表示一对字符串的实现:

blic class TextPair implements WritableComparable<TextPair> {private Text first;private Text second;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 getScond() {return second;}public void write(DataOutput out) throws IOException {first.write(out);second.write(out);}public void readFields(DataInput in) throws IOException {first.readFields(in);second.readFields(in);}public int hashCode() {return first.hashCode() * 163 + second.hashCode();}public boolean equals(Object o) {if(o instanceof TextPair) {TextPair tp = (TextPair)o;return first.equals(tp.first) && second.equals(tp.second);}return false;}public String toString() {return first + "\t" + second;}public int compareTo(TextPair tp) {int cmp = first.compareTo(tp.first);if(cmp != 0) {return cmp;}return second.compareTo(tp.second);}
}

为速度实现一个RawComparator

还可以进一步的优化,当作为MapReduce里的key,需要进行比较时,因为他已经被序列化,想要比较他们,那么首先要先反序列化成一个对象,然后再调用compareTo对象进行比较,但是这样效率太低了,有没有可能可以直接比较序列化后的结果呢,答案是肯定的,可以。

RawComparator接口允许执行者比较流中读取的未被反序列化为对象的记录,从而省去了创建对象的所有的开销,其中,compare() 比较时需要的两个参数所对应的记录位于字节数组b1和b2指定开始位置s1和s2,记录长度为l1和l2,代码如下:

public interface RawComparator<T> extends Comparator<T> {public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2);
}

以IntWritable为例,它的RawComparator实现中,compare() 方法通过readInt()直接在字节数组中读入需要比较的两个整数,然后输出Comparable接口要求的比较结果。

值得注意的是,该过程中compare()方法避免使用IntWritable对象,从而避免了不必要的对象分配,相关代码如下:

  /** A Comparator optimized for IntWritable. */ public static class Comparator extends WritableComparator {public Comparator() {super(IntWritable.class);}public int compare(byte[] b1, int s1, int l1,byte[] b2, int s2, int l2) {int thisValue = readInt(b1, s1);int thatValue = readInt(b2, s2);return (thisValue<thatValue ? -1 : (thisValue==thatValue ? 0 : 1));}}

Writablecomparator是RawComparator对WritableComparable类的一个通用实现,它提供两个主要功能:

1、提供了一个RawComparator的compare()默认实现,该实现从数据流中反序列化要进行比较的对象,然后调用对象的compare()方法进行比较

2、它充当了RawComparator实例的一个工厂方法。例如,可以通过下面的代码获得IntWritable的RawComparator:

RawComparator<IntWritable> comparator = WritableComparator.get(IntWritable.class);

我们只需要把EmploeeWritable的序列化后的结果拆成成员对象,然后比较成员对象即可:

class Comparator extends WritableComparator {private static final Text.Comparator TEXT_COMPARATOR = new Text.Comparator();public Comparator() {super(TextPair.class);}public int compara(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);}}
}

定制comparators

有时候,除了默认的comparator,你可能还需要一些自定义的comparator来生成不同的排序队列,看一下下面这个示例:

    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);}}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);}

转载于:https://www.cnblogs.com/wuyudong/p/4332080.html

hadoop中实现定制Writable类相关推荐

  1. hadoop中的序列化与Writable类

    本文地址:http://www.cnblogs.com/archimedes/p/hadoop-writable-class.html,转载请注明源地址. hadoop中自带的org.apache.h ...

  2. Hadoop中Writable类

    1.Writable简单介绍 在前面的博客中,经常出现IntWritable,ByteWritable.....光从字面上,就可以看出,给人的感觉是基本数据类型 和 序列化!在Hadoop中自带的or ...

  3. python中的定制类(转载)

    python中的定制类(转载)<?xml version="1.0" encoding="UTF-8"?> 看到类似__slots__这种形如__x ...

  4. Hadoop中Context类的作用和Mapper<LongWritable, Text, Text, LongWritable>.Context context是怎么回事【笔记自用】

    问题导读: 1.Context能干什么? 2.你对Context类了解多少? 3.Context在mapreduce中的作用是什么? 下面我们通过来源码,来得到Context的作用: 下面主要对Set ...

  5. Hadoop中Context类的作用

    问题导读: 1.Context能干什么? 2.你对Context类了解多少? 3.Context在mapreduce中的作用是什么? 下面我们通过来源码,来得到Context的作用: 下面主要对Set ...

  6. Hadoop中RPC机制详解之Server端

    2019独角兽企业重金招聘Python工程师标准>>> Hadoop 中 RPC 机制详解之 Client 端 1. Server.Listener RPC Client 端的 RP ...

  7. Hadoop中RPC机制

    Hadoop中RPC机制 RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议.Hadoo ...

  8. Hadoop中Partition解析

    1.解析Partition Map的结果,会通过partition分发到Reducer上,Reducer做完Reduce操作后,通过OutputFormat,进行输出,下面我们就来分析参与这个过程的类 ...

  9. hadoop 中各种概念解释记忆

    https://blog.csdn.net/marvel_cheng/article/details/45480521 https://blog.csdn.net/qq_26437925/articl ...

最新文章

  1. Buttomsheetdialog的简单实用
  2. 使用VMware Workstation搭建基于Linux的Oracle 10g RAC
  3. [reference]-ARM Term术语汇总
  4. Wifi模块—源码分析Wifi热点扫描(Android P)
  5. JS - 讨论 - 编码习惯 - JavaScript代码到底要不要写分号?
  6. Nginx的官方简介
  7. 论文阅读笔记(四)【ACL 2021】FEW-NERD: A Few-shot Named Entity Recognition Dataset
  8. 安卓 监听 mysql_Android监听数据库的值改变与否
  9. Javascript原型钩沉
  10. WebAssembly 将成为互联网的终结?
  11. morphia查询Mongo数据库通过ReadPreference主从数据库查询切换方法
  12. 邢波老师致广大学员的一封信(2010-10-26)
  13. 整体大于部分_整体叶盘球头鼓锥形铣刀五轴加工技术
  14. 使用HBuilder mui将图片保存到手机相册(移动端将图片、文件保存至手机相册)
  15. 《黑客与画家》-1 为什么书呆子不受欢迎?
  16. DNS这位“翻译官”是如何转换域名和IP地址的?
  17. 重新定义流媒体服务器
  18. 桃词典 Peach Dictionary 简易英语词典app开发 安卓软件开发 Part 8
  19. 【UPCOJ】10155问题 S: 近似排序
  20. 积分换元法中换元单调性问题的讨论

热门文章

  1. 怎么做蒙特卡洛计算npv_PowerBI非标准日历下的同比环比计算,你知道怎么做吗?...
  2. matlab用for编写乘法表,实验二 Matlab程序设计基本方法1
  3. wamp的mysql触发器教程_wamp里的mysql怎么做出这个
  4. 采油工计算机试题库,数字化采油工试题库.doc
  5. linux系统基础与应用,Linux操作系统:基础、原理与应用
  6. matlab 排序点,matlab如何进行排序?
  7. 命名管道实现进程的信息传递【mkfifo函数、open函数】
  8. leetcode147 对链表进行插入排序
  9. C++primer 第 3 章 字符串、向量和数组 3 . 4 迭代器介绍
  10. MySQL Mac安装教程