在使用Pig的Hadoop中,我在几个单独的源中有大量字段,我加载,过滤,投影,分组,运行几个Java UDF,加入,项目和存储。 (这是Hadoop中的日常生活。)UDF不使用原始数据加载中的某些字段,直到最终存储才需要这些字段。
什么时候通过UDF传递未使用的字段比以后存储和加入它们更好?
一个简单的玩具示例是列name,weight,height
的数据源,我最终想要存储name,weight,heightSquared
。我的UDF将为我设定高度。哪个更好:
inputdata = LOAD 'data' AS name,weight,height;
outputdata = FOREACH inputdata
GENERATE myudf.squareHeight(name,weight,height)
AS (name,weight,heightSquared);
STORE outputdata INTO 'output';
或
inputdata = LOAD 'data' AS name,weight,height;
name_weight = FOREACH inputdata
GENERATE name,weight;
intdata1 = FOREACH inputdata
GENERATE myudf.squareHeight(name,height)
AS (iname,heightSquared);
intdata2 = JOIN intdata1 BY iname, name_weight BY name;
outputdata = FOREACH intdata2
GENERATE name,weight,heightSquared;
STORE outputdata INTO 'output';
在这种情况下,它看起来非常明显:第一种情况更好。但是UDF必须读取并存储和输出weight
字段。如果你有15个字段,而UDF并不关心它,那么第一个案例还是更好吗?
答案 0 :(得分:1)
如果UDF不关心15个字段,则不要将它们发送到UDF。在您的示例中,没有理由将UDF写入三个字段,如果它只使用第三个字段。您的示例的最佳脚本将是
inputdata = LOAD 'data' AS name,weight,height;
outputdata =
FOREACH inputdata
GENERATE
name,
weight,
myudf.squareHeight(height) AS heightSquared;
STORE outputdata INTO 'output';
这样就解决了UDF案例。如果你有一堆你想要存储的字段,但你不打算在接下来的几个map-reduce循环中使用它们,你可能希望立即存储它们然后重新加入它们。但是将根据经验测试哪种方法对您的具体情况更快。