2

我有一个复杂的 Avro 记录(嵌套记录、联合类型),我将其作为值存储在 HBase 中。我使用当前与文件的编写器模式和 HBase 中的记录匹配的模式读取 Avro 数据文件:

Schema schema = new Schema.Parser().parse(schema_file);
DatumReader<GenericRecord> datumReader = new SpecificDatumReader<GenericRecord>(schema);
DataFileReader<GenericRecord> dataFileReader = new DataFileReader<GenericRecord>(avro_file, datumReader);
GenericRecord record = null;
record = dataFileReader.next(record);

然后我检查 HBase 以查看是否已经存在具有相同 rowkey 的记录。我的 get 返回的 val 是 Avro 记录的字节数组表示:

Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "table");
String pk = new String(record.get("x").toString()+record.get("y").toString());
Get get = new Get(Bytes.toBytes(pk));
Result result = table.get(get);
byte[] val = result.getValue(Bytes.toBytes("c"),Bytes.toBytes("c"));

如果 HBase 中没有具有相同 rowkey 的记录,我将记录放入:

if (val == null) {
  System.out.println("pk: "+pk+" does not exist");
  Put put = new Put(Bytes.toBytes(pk));
  put.add(Bytes.toBytes("c"), Bytes.toBytes("c"), Bytes.toBytes(record.toString()));
  try {
    table.put(put);
  } catch (Exception e) {
    System.err.println("Can't put to table: " + e);
  }
}
else {
  System.out.println("pk: "+pk+" does exist");
  //help me!
}

如果 HBase 中有一条记录具有相同的行键,我想将 HBase 结果的字节数组转换回 Avro 模式,然后比较几个字段以查看哪个记录“更好”。我想将“更好”的记录放入 HBase,但我被卡住了。如何将字节数组从 HBase 转换为 GenericRecord,以便比较文件记录和 HBase 之间的字段?

4

1 回答 1

4

我想到了。我需要将我的记录作为序列化字节数组而不是转换为字节数组的字符串写入 HBase。

放变成:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
DatumWriter<GenericRecord> writer = new GenericDatumWriter<GenericRecord>(schema);
DataFileWriter<GenericRecord> dfw = new DataFileWriter<GenericRecord>(writer);
dfw.create(schema, baos);
dfw.append(record);
dfw.close();
Put put = new Put(Bytes.toBytes(pk));
put.add(Bytes.toBytes("c"), Bytes.toBytes("c"), baos.toByteArray());

这得到:

 GenericRecord hrecord = null;
    ByteArrayInputStream bais = new ByteArrayInputStream(val);
    DataFileStream<GenericRecord> dfs = new DataFileStream<GenericRecord>(bais, datumReader);
    hrecord = dfs.next(hrecord);
于 2013-06-29T11:46:11.407 回答