1

首先,我正在根据集群运行 Apache Pig 版本 0.11.0-cdh4.3.0(重新导出)。但是,我的构建使用 0.11.0-cdh4.5.0 我知道这不是一个明智的决定,但我认为这与我在这里遇到的问题无关,因为它都是 Pig v0.11.0

我有一个结构看起来像这样的脚本(两个自定义 udf 都返回 DataByteArray 类型,这是一个有效的 Pig 类型 afaik):

LOAD USING parquet.pig.ParquetLoader();

FOREACH GENERATE some of the fields

GROUP BY (a,b,c)

FOREACH GENERATE FLATTEN(group) AS (a,b,c), CustomUDF1(some_value) AS d

FOREACH GENERATE FLATTEN(CubeDimensions(a,b,c)) AS (a,b,c) , d

GROUP BY (a,b,c)

FOREACH GENERATE FLATTEN(group) AS (a,b,c), SUM(some_value), CustomUDF2(some_value)

STORE USING parquet.pig.ParquetStorer();

Pig 将其拆分为两个 mapreduce 作业。我不确定 CubeDimensions 是发生在第一个还是第二个,但我怀疑它发生在第一个工作的 reduce 阶段。

所以第二个工作的映射阶段只不过是读取中间数据,这就是发生这种情况的地方:

“在流中发现意外的数据类型 49。” @ org.apache.pig.data.BinInterSedes:422

我已经看到数字是 48 和 49 并且在 BinInterSedes 类中都不存在:

http://grepcode.com/file/repository.cloudera.com/content/repositories/releases/org.apache.pig/pig/0.11.0-cdh4.3.0/org/apache/pig/data/BinInterSedes.java? av=f

但由于这是猪自己的中间输出,我不太明白它可能出错的地方。我的自定义 UDF 都返回一个有效类型,我希望 Pig 肯定只使用它知道的类型进行存储。

任何帮助将不胜感激。

4

1 回答 1

1

巧合的是,在 Pig 的中间存储中用于行拆分的序列也出现在自定义 UDF 返回的字节数组之一中。这会导致 pig 在中间某处断开线,并开始寻找数据类型指示。由于它只是在该行的中间,因此没有有效的数据类型指示,因此出现错误。

我还不完全确定我将如何解决这个问题。@WinnieNicklaus 已经提供了一个很好的解决方案,将脚本分成两部分并存储在两者之间。另一种选择是让 UDF 返回一个 Base64 编码的字节数组。这样就不会与 PIG 中间存储发生冲突,因为它使用 CTRL-A、CTRL-B、CTRL-C、TUPLE-INDICATOR,它们都不是字母数字字符。

于 2014-05-15T08:35:44.917 回答