分享

hbase-0.96.x相对hbase-0.94.x的改变

xioaxu790 2014-5-25 10:29:29 发表于 总结型 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 0 11183
本帖最后由 pig2 于 2014-5-25 12:33 编辑
问题导读
1、hbase-0.96.x和hbase-0.94.x的改变有哪些 ?
2、这些改变,我们该如何去解决 ?





环境:
hadoop:hadoop-2.2.0
hbase:hbase-0.96.0

1.org.apache.hadoop.hbase.client.Put
    <1>取消了无参的构造方法
    <2>Put类不再继承Writable类     
        0.94.6时public class Put extends Mutation implements HeapSize, Writable, Comparable<Row>
        0.96.0时public class Put extends Mutation implements HeapSize, Comparable<Row>
解决方法:
        由public class MonthUserLoginTimeIndexReducer extends Reducer<BytesWritable,MonthUserLoginTimeIndexWritable, ImmutableBytesWritable, Writable>
改public class MonthUserLoginTimeIndexReducer extends Reducer<BytesWritable,MonthUserLoginTimeIndexWritable, ImmutableBytesWritable, Put>

2.org.apache.hadoop.hbase.client.Mutation.familyMap
  1. org.apache.hadoop.hbase.client.Mutation.familyMap类型改变:
  2.      /**
  3.      * 0.94.6
  4.      * protected Map<byte[],List<KeyValue>> familyMap
  5.      *
  6.      * 0.96.*
  7.      * protected NavigableMap<byte[],List<Cell>> familyMap
  8.      * org.apache.hadoop.hbase.Cell hbase-0.94.*中是没有的
  9.      */   
  10.      org.apache.hadoop.hbase.KeyValue的改变:
  11.      /**
  12.      * 0.94.*
  13.      * public class KeyValue extends Object implements Writable, HeapSize
  14.      *
  15.      * 0.96.0
  16.      * public class KeyValue extends Object implements Cell, HeapSize, Cloneable
  17.      */
复制代码

解决方法:将代码中的List<KeyValue>改成List<Cell>


3. org.apache.hadoop.hbase.KeyValue
     0.96.0中方法getFamily已被弃用(Deprecated),改成方法getFamilyArray()

4.org.apache.hadoop.hbase.HTableDescriptor   
     类org.apache.hadoop.hbase.HTableDescriptor的构造方法public HTableDescriptor(String name)已被弃用(Deprecated)
     解决方法:使用public HTableDescriptor(TableName name)
     旧:HTableDescriptor tableDesc = new HTableDescriptor(tableName);
     新:HTableDescriptor tableDesc = new HTableDescriptor(TableName.valueOf(tableName));

5.org.apache.hadoop.hbase.client.HTablePool
     类org.apache.hadoop.hbase.client.HTablePool整个被弃用(Deprecated)
     解决方法:使用HConnection.getTable(String)代替,HConnection是个接口,类CoprocessorHConnection是它唯一的实现类:
     
  1. HRegionServer hRegionServer = new HRegionServer(conf) ;
  2.      HConnection connection = HConnectionManager.createConnection(conf);
  3.      hConnection = new CoprocessorHConnection(connection,hRegionServer);
复制代码



6.org.apache.hadoop.hbase.client.Result
     方法public KeyValue[] raw()被弃用(Deprecated),建议使用public Cell[] rawCells()
     方法getRow被弃用(Deprecated)
     方法getFamily被弃用(Deprecated)
     方法getQualifier被弃用(Deprecated)
     方法getValue被弃用(Deprecated)
     方法public List<KeyValue> getColumn(byte[] family,byte[] qualifier)被弃用(Deprecated)
     方法public KeyValue getColumnLatest(byte[] family,byte[] qualifier)被弃用(Deprecated)
     Cell中:改成以下方法
     getRowArray()
     getFamilyArray()
     getQualifierArray()
     getValueArray()
     Result中:增加如下方法
     public List<KeyValue> getColumnCells(byte[] family,byte[] qualifier)
     public KeyValue getColumnLatestCell(byte[] family,byte[] qualifier)
     改动:所有ipeijian_data中凡是和【新增用户活跃用户流失用户】相关的都做如下变化:
     旧代码:if (value.raw().length == 1
     新代码:if (value.rawCells().length == 1

7.job中设置TableInputFormat.SCAN
     0.96.0中去掉了方法:public void write(DataOutput out)throws IOException
     之前版本使用conf.set(TableInputFormat.SCAN, StatUtils.convertScanToString(scan));进行设置
     StatUtils.convertScanToString的具体实现为:
   
  1. public static String convertScanToString(Scan scan) throws IOException {
  2.             ByteArrayOutputStream out = new ByteArrayOutputStream();
  3.             DataOutputStream dos = new DataOutputStream(out);
  4.             scan.write(dos);
  5.             return Base64.encodeBytes(out.toByteArray());
  6.      }
复制代码


     该方法的实现与TableMapReduceUtil.convertScanToString(Scan scan)是一样的。
     但是当hbase升级到了0.96.*是对于类Scan弃用(不仅仅是Deprecated,而是Deleted)了方法write,所以上面
     的实现变为不正确
     hbase0.96.*中对该方法进行了重新的实现:
     
  1. public static String convertScanToString(Scan scan) throws IOException {
  2.             ClientProtos.Scan proto = ProtobufUtil.toScan(scan);
  3.             return Base64.encodeBytes(proto.toByteArray());
  4.      }
复制代码


     所以做如下更改:
     StatUtils类中方法convertScanToString的实现做如上更改以适配hbase0.96.*

8.cn.m15.ipj.db.hbase.MyPut
    自定义的Put类,比传统的Put类多一个length,原版和新版代码比较:
    原版:(红色字体为API变为新版时报错的地方)
  1. public class MyPut extends Put {
  2.      public MyPut(byte[] row, int length) {                                    
  3.      //原因是put的无参构造方法已经在新本中消失
  4.           if (row == null || length > HConstants.MAX_ROW_LENGTH) {
  5.                throw new IllegalArgumentException(“Row key is invalid”);
  6.           }
  7.           this.row = Arrays.copyOf(row, length);
  8.           this.ts = HConstants.LATEST_TIMESTAMP;
  9.      }   
  10.      public MyPut add(byte[] family, byte[] qualifier, long ts, byte[] value,int length) {
  11.           List<KeyValue> list = getKeyValueList(family);
  12.           KeyValue kv = createPutKeyValue(family, qualifier, ts, value, length);
  13.           list.add(kv);
  14.           familyMap.put(kv.getFamily(), list);                                   
  15.           //familyMap的类型已经改变
  16.           return this;
  17.       }
  18.      private List<KeyValue> getKeyValueList(byte[] family) {
  19.           List<KeyValue> list = familyMap.get(family);                     
  20.           //familyMap的类型已经改变
  21.           if (list == null) {
  22.                list = new ArrayList<KeyValue>(0);
  23.           }
  24.           return list;
  25.      }
  26.      private KeyValue createPutKeyValue(byte[] family, byte[] qualifier,long ts, byte[] value, int length) {
  27.           return new KeyValue(this.row, 0, this.row.length, family, 0,
  28.           family.length, qualifier, 0, qualifier.length, ts,
  29.           KeyValue.Type.Put, value, 0, length);
  30.      }
  31. }
复制代码

更改之后:

  1. public MyPut(byte[] row, int length) {
  2.      super(row,length);                                                                     
  3.      //新增加
  4.      if (row == null || length > HConstants.MAX_ROW_LENGTH) {
  5.           throw new IllegalArgumentException(“Row key is invalid”);
  6.      }
  7.      this.row = Arrays.copyOf(row, length);
  8.      this.ts = HConstants.LATEST_TIMESTAMP;
  9.      }
  10.      public MyPut add(byte[] family, byte[] qualifier, long ts, byte[] value,int length) {
  11.           List<Cell> list = getCellsList(family);
  12.           KeyValue kv = createPutKeyValue(family, qualifier, ts, value, length);
  13.           list.add(kv);
  14.           familyMap.put(CellUtil.cloneFamily(kv), list);
  15.           return this;
  16.      }   
  17.      private List<Cell> getCellsList(byte[] family) {
  18.           List<Cell> list = familyMap.get(family);
  19.           if (list == null) {
  20.               list = new ArrayList<Cell>(0);
  21.           }
  22.           return list;
  23.      }
  24.      private KeyValue createPutKeyValue(byte[] family, byte[] qualifier,long ts, byte[] value, int length) {
  25.           return new KeyValue(this.row, 0, this.row.length, family, 0,family.length, qualifier, 0, qualifier.length, ts,
  26.                     KeyValue.Type.Put, value, 0, length);
  27.      }
  28. }
复制代码


最后,感谢原作者的分享: mark的专栏

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

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

本版积分规则

关闭

推荐上一条 /2 下一条