我让 Pig (0.10) 将数据从 hdfs 加载到 hbase 中。原始记录没有唯一的行键,所以我有一个 UDF 构造:
public class Foo extends EvalFunc<Tuple> {
// FIXME: If there are multiple map jobs for the same batch,
// they will reuse the serial numbers.
// Need to add something to figure out a distinct per task #
private int task_id=0;
private long serial=0L;
public Tuple exec(Tuple input) throws IOException {
if (input == null || input.size() == 0)
return null;
try {
Integer batch_id=(Integer)input.get(0);
String rowkey=String.format("%7d%3d%9d", batch_id, task_id, serial++);
// ... compute other values for the return Tuple.
}
}
}
我的理解是,如果 pig 为同一个输入数据集启动两个不同的映射作业(由于超出块大小或从目录加载时具有多个输入文件),每个都将是一个单独的 Java 实例,因此Foo.serial 会有多个独立的副本;我的 rowkeys 不会是唯一的,我将覆盖我试图加载到 HBase 中的许多记录。
如果我的 UDF 可以确定它属于哪个映射器,那么冲突就会消失。我可以回退到 IP 地址 + 进程 ID,但这相当浪费。