我有猪(0.10)从hdfs加载数据到hbase。原始记录没有唯一的rowkeys,所以我有一个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为相同的输入数据集启动了两个不同的map作业(由于超出了chunksize或者从目录中加载时有多个输入文件),每个作为一个单独的Java实例,因此会有多个独立的Foo.serial副本;我的rowkeys不会是唯一的,我将覆盖我尝试加载到HBase中的许多记录。
如果我的UDF可以确定它所属的映射器中的哪一个,则冲突就会消失。我可以回退到IP地址+进程ID,但这是相当浪费的。
答案 0 :(得分:0)
查看DataFu集合中的Enumerate UDF。这将需要一个包,并为每个元素分配一个数字1到N,其中N是包的大小。这种不幸的副作用是我相信你的所有数据都必须通过一个减速器。但是根据你的描述,听起来这可能不是一个大问题。 (听起来有时数据有时足够大,需要在多个映射器之间进行拆分。)
您可以简单地将所有数据分组到一个包含GROUP ... ALL
的包中,然后枚举此包。然后,您可以使用此编号构建自定义行键,该编号对于包中的每个记录都是唯一的。