携带田地,或存储和加入?

时间:2014-02-05 21:47:20

标签: hadoop apache-pig hadoop-streaming

在使用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并不关心它,那么第一个案例还是更好吗?

1 个答案:

答案 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循环中使用它们,你可能希望立即存储它们然后重新加入它们。但是将根据经验测试哪种方法对您的具体情况更快。