首先,我根据群集运行Apache Pig版本0.11.0-cdh4.3.0(rexported)。然而,我的构建使用了0.11.0-cdh4.5.0,我知道这不是一个明智的决定,但我不认为这与我在这里遇到的问题有关,因为它都是Pig v0.11.0
我有一个结构看起来像这样的脚本(两个自定义udf返回DataByteArray类型,这是一个有效的猪类型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类中都不存在:
但由于这是猪自己的中间产量,我不太明白它可能出错的地方。我的自定义UDF都返回一个有效的类型,我希望Pig只能使用它知道的类型存储。
非常感谢任何帮助。
答案 0 :(得分:1)
似乎巧合的是,在Pig的中间存储中用于行分割的序列也发生在自定义UDF返回的一个字节数组中。这会导致猪在中间某处打破这条线,并开始寻找数据类型指示。因为它只是在行的中间,所以没有有效的数据类型指示,因此错误。
我还不完全确定如何解决这个问题。 @WinnieNicklaus已经提供了一个很好的解决方案,将脚本分成两部分并存储在两者之间。另一种选择是让UDF返回Base64编码的字节数组。这样就永远不会与PIG中间存储冲突,因为它使用CTRL-A,CTRL-B,CTRL-C,TUPLE-INDICATOR,其中没有一个是字母数字字符。