分享

hadoop中实现定制Writable类

nettman 2015-3-14 14:28:44 发表于 实操演练 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 0 11644
问题导读

1.为什么定制Writable类?
2.如何定制一个Writable类?






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

为了演示如何新建一个定制的writable类型,我们需要写一个表示一对字符串的实现:
  1. blic class TextPair implements WritableComparable<TextPair> {
  2.     private Text first;
  3.     private Text second;
  4.    
  5.     public TextPair() {
  6.         set(new Text(), new Text());
  7.     }
  8.    
  9.     public TextPair(String first, String second) {
  10.         set(new Text(first), new Text(second));
  11.     }
  12.    
  13.     public TextPair(Text first, Text second) {
  14.         set(first, second);
  15.     }
  16.    
  17.     public void set(Text first, Text second) {
  18.         this.first = first;
  19.         this.second = second;
  20.     }
  21.    
  22.     public Text getFirst() {
  23.         return first;
  24.     }
  25.    
  26.     public Text getScond() {
  27.         return second;
  28.     }
  29.    
  30.     public void write(DataOutput out) throws IOException {
  31.         first.write(out);
  32.         second.write(out);
  33.     }
  34.    
  35.     public void readFields(DataInput in) throws IOException {
  36.         first.readFields(in);
  37.         second.readFields(in);
  38.     }
  39.    
  40.     public int hashCode() {
  41.         return first.hashCode() * 163 + second.hashCode();
  42.     }
  43.    
  44.     public boolean equals(Object o) {
  45.         if(o instanceof TextPair) {
  46.             TextPair tp = (TextPair)o;
  47.             return first.equals(tp.first) && second.equals(tp.second);
  48.         }
  49.         return false;
  50.     }
  51.    
  52.     public String toString() {
  53.         return first + "\t" + second;
  54.     }
  55.    
  56.     public int compareTo(TextPair tp) {
  57.         int cmp = first.compareTo(tp.first);
  58.         if(cmp != 0) {
  59.             return cmp;
  60.         }
  61.         return second.compareTo(tp.second);
  62.     }   
  63. }
复制代码
为速度实现一个RawComparator
还可以进一步的优化,当作为MapReduce里的key,需要进行比较时,因为他已经被序列化,想要比较他们,那么首先要先反序列化成一个对象,然后再调用compareTo对象进行比较,但是这样效率太低了,有没有可能可以直接比较序列化后的结果呢,答案是肯定的,可以。

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

  1. class Comparator extends WritableComparator {
  2.     private static final Text.Comparator TEXT_COMPARATOR = new Text.Comparator();
  3.     public Comparator() {
  4.         super(TextPair.class);
  5.     }
  6.     public int compara(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
  7.         try {
  8.             int firstL1 = WritableUtils.decodeVIntSize(b1[s1]) + readVInt(b1, s1);
  9.             int firstL2 = WritableUtils.decodeVIntSize(b2[s2]) + readVInt(b2, s2);
  10.             int cmp = TEXT_COMPARATOR.compare(b1, s1, firstL1, b2, s2, firstL2);
  11.             if(cmp != 0) {
  12.                 return cmp;
  13.             }
  14.             return TEXT_COMPARATOR.compare(b1, s1 + firstL1, l1 - firstL1, b2, s2 + firstL2, l2 -  firstL2);
  15.         } catch(IOException e) {
  16.             throw new IllegalArgumentException(e);
  17.         }
  18.     }
  19. }
复制代码
定制comparators有时候,除了默认的comparator,你可能还需要一些自定义的comparator来生成不同的排序队列,看一下下面这个示例:
  1. public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
  2.         try {
  3.             int firstL1 = WritableUtils.decodeVIntSize(b1[s1])+ readVInt(b1, s1);
  4.             int firstL2 = WritableUtils.decodeVIntSize(b2[s2])+ readVInt(b2, s2);
  5.             return TEXT_COMPARATOR.compare(b1, s1, firstL1, b2, s2, firstL2);
  6.         } catch (IOException e) {
  7.             throw new IllegalArgumentException(e);
  8.         }
  9.     }
  10.    
  11.     public int compare(WritableComparable a, WritableComparable b) {
  12.         if(a instanceof Textpair && b instanceof TextPair) {
  13.             return ((TextPair) a).first.compareTo(((TextPair) b).first);
  14.         }
  15.         return super.compare(a, b);
  16.     }
复制代码



作者:archimedes
出处:http://www.cnblogs.com/archimedes/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.


加微信w3aboutyun,可拉入技术爱好者群

没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条