Hadoop MRUnit正确创建HBase结果

Hadoop MRUnit正确创建HBase结果,hadoop,map,hbase,mrunit,Hadoop,Map,Hbase,Mrunit,我有一个mapreduce作业,映射器从几个HBase表中读取数据。它在我的集群上运行良好。我正在用MRUnit编写一些单元测试。我试图从手动实例化的KeyValue对象列表中合成一个结果对象,用作映射方法的输入。当我随后尝试读取map方法中的几列时,似乎只有列表中的第一个KeyValue对象保留在Result对象中,其他的都为null。在下面的列表中,我有一个名为0的单列族 private MapDriver<ImmutableBytesWritable, Result, Text, T

我有一个mapreduce作业,映射器从几个HBase表中读取数据。它在我的集群上运行良好。我正在用MRUnit编写一些单元测试。我试图从手动实例化的KeyValue对象列表中合成一个结果对象,用作映射方法的输入。当我随后尝试读取map方法中的几列时,似乎只有列表中的第一个KeyValue对象保留在Result对象中,其他的都为null。在下面的列表中,我有一个名为0的单列族

private MapDriver<ImmutableBytesWritable, Result, Text, Text> mapDriver;
private HopperHbaseMapper hopperHbaseMapper;

@Before
public void setUp() {    
  hopperHbaseMapper = new HopperHbaseMapper();
  mapDriver = MapDriver.newMapDriver(hopperHbaseMapper);    
}

@Test
public void testMapHbase() throws Exception {    
  String testKey = "123";
  ImmutableBytesWritable key = new ImmutableBytesWritable(testKey.getBytes());    
  List<KeyValue> keyValues = new ArrayList<KeyValue>();
  KeyValue keyValue1 = new KeyValue(testKey.getBytes(), "0".getBytes(), "first_name".getBytes(), "Joe".getBytes());
  KeyValue keyValue2 = new KeyValue(testKey.getBytes(), "0".getBytes(), "last_name".getBytes(), "Blow".getBytes());
  keyValues.add(keyValue1);
  keyValues.add(keyValue2);
  Result result = new Result(keyValues);
  mapDriver.withInput(key, result);
  mapDriver.withOutput(new Text(testKey), new Text(testKey + "\tJoe\tBlow"));
  mapDriver.runTest();
}

我是否错误地创建了结果对象?如前所述,映射器在集群上的真实HBase数据上运行良好,因此我认为是我的测试设置出了问题。

与rowkey一样,HBase也以字典顺序存储列。因此,您必须使用TreeSet set=newtreesetkeyvalue.COMPARATOR; ans将此集合传递给结果构造函数,如Resultset


我还在最新的Hbase库中发布了我的答案,结果方法已被弃用,因此我们应该改用Result.create方法。在撰写我的解决方案时,我面临着与问题作者相同的问题。Sakthivel的评论中找到了解决方案。下面是用Scala语言实现的Sakthivel解决方案

import org.apache.hadoop.hbase.{CellUtil, KeyValue}
import scala.collection.immutable.TreeSet


implicit val ordering =  KeyValue.COMPARATOR

val cells = TreeSet(
      CellUtil.createCell(toBytes("myRowKey"), toBytes("myColumnFamily"),toBytes("myQualifier1"), 1000L, KeyValue.Type.Minimum.getCode, toBytes("myValue1")),
      CellUtil.createCell(toBytes("myRowKey"), toBytes("myColumnFamily"),toBytes("myQualifier2"), 1000L, KeyValue.Type.Minimum.getCode, toBytes("myValue2")),
      CellUtil.createCell(toBytes("myRowKey"), toBytes("myColumnFamily"),toBytes("myQualifier3"), 1000L, KeyValue.Type.Minimum.getCode, toBytes("myValue3")),
      CellUtil.createCell(toBytes("myRowKey"), toBytes("myColumnFamily"),toBytes("myQualifier4"), 1000L, KeyValue.Type.Minimum.getCode, toBytes("myValue4")),
      CellUtil.createCell(toBytes("myRowKey"), toBytes("myColumnFamily"),toBytes("myQualifier5"), 1000L, KeyValue.Type.Minimum.getCode, toBytes("myValue5"))
    )

val result = Result.create(cells.toArray)

希望它能帮助编写hbase功能单元测试的人

我发现了这个问题。似乎是org.apache.hadoop.hbase.client.Result.getValue中的一个bug。似乎只有在MRUnit下本地运行时才显示,而不是在集群中。我在这里作了更充分的回答:
import org.apache.hadoop.hbase.{CellUtil, KeyValue}
import scala.collection.immutable.TreeSet


implicit val ordering =  KeyValue.COMPARATOR

val cells = TreeSet(
      CellUtil.createCell(toBytes("myRowKey"), toBytes("myColumnFamily"),toBytes("myQualifier1"), 1000L, KeyValue.Type.Minimum.getCode, toBytes("myValue1")),
      CellUtil.createCell(toBytes("myRowKey"), toBytes("myColumnFamily"),toBytes("myQualifier2"), 1000L, KeyValue.Type.Minimum.getCode, toBytes("myValue2")),
      CellUtil.createCell(toBytes("myRowKey"), toBytes("myColumnFamily"),toBytes("myQualifier3"), 1000L, KeyValue.Type.Minimum.getCode, toBytes("myValue3")),
      CellUtil.createCell(toBytes("myRowKey"), toBytes("myColumnFamily"),toBytes("myQualifier4"), 1000L, KeyValue.Type.Minimum.getCode, toBytes("myValue4")),
      CellUtil.createCell(toBytes("myRowKey"), toBytes("myColumnFamily"),toBytes("myQualifier5"), 1000L, KeyValue.Type.Minimum.getCode, toBytes("myValue5"))
    )

val result = Result.create(cells.toArray)