我有一个mapreduce作业,映射器从几个HBase表中读取。它在我的集群上工作正常。我正在用MRUnit追溯写一些单元测试。我试图从手动实例化的KeyValue对象列表中组成一个Result对象,以用作map()方法的输入。当我随后尝试在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();
}
我是否错误地创建了Result对象?如上所述,映射器在我的集群上的真实HBase数据上运行良好,所以我认为这是我的测试设置有问题。
答案 0 :(得分:1)
与rowkey一样,HBase也以字典顺序存储列。所以你必须使用TreeSet<KeyValue> set = new TreeSet<KeyValue>(KeyValue.COMPARATOR);
ans将此set
传递给Result构造函数,例如Result(set)
。
TreeSet<KeyValue> set = new TreeSet<KeyValue>(KeyValue.COMPARATOR);
byte[] row = Bytes.toBytes("row01");
byte[] cf = Bytes.toBytes("cf");
set.add(new KeyValue(row, cf, "cone".getBytes(), Bytes.toBytes("row01_cone_one")));
set.add(new KeyValue(row, cf, "ctwo".getBytes(), Bytes.toBytes("row01_ctwo_two")));
set.add(new KeyValue(row, cf, "cthree".getBytes(), Bytes.toBytes("row01_cthree_three")));
set.add(new KeyValue(row, cf, "cfour".getBytes(), Bytes.toBytes("row01_cfour_four")));
set.add(new KeyValue(row, cf, "cfive".getBytes(), Bytes.toBytes("row01_cfive_five")));
set.add(new KeyValue(row, cf, "csix".getBytes(), Bytes.toBytes("row01_csix_six")));
KeyValue[] kvs = new KeyValue[set.size()];
set.toArray(kvs);
Result result = new Result(kvs);
mapDriver.withInput(key, result);
我也发布了我的回答here
答案 1 :(得分:0)
在最新的Hbase库中,不赞成使用Result方法,因此我们应该改用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功能编写单元测试。