Pig 无法读取自己的中间数据
Posted
技术标签:
【中文标题】Pig 无法读取自己的中间数据【英文标题】:Pig cannot read its own intermediate data 【发布时间】:2014-05-14 11:44:08 【问题描述】:首先,我正在根据集群运行 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
但由于这是 pig 自己的中间输出,我不太明白它可能出错的地方。我的自定义 UDF 都返回一个有效类型,我希望 Pig 肯定只使用它知道的类型进行存储。
任何帮助将不胜感激。
【问题讨论】:
您是否尝试在CustomUDF1
行之后存储您的数据?
我考虑过这一点,但我认为 Pigs BinStorage 对于中间日期会比我们使用的 ParquetStorage 更有效。我会试一试,然后在这里报告。
数据集非常大,所以这可能需要一段时间。如果 DataByteArray 包含指示新记录开始的字节序列(我收集的 0x01 0x02 0x03),这会导致文件损坏吗?
这是个好主意。我不熟悉 Parquet 或 Hadoop 的序列文件,所以我不会有太多帮助。但希望如果您可以检查中间数据,您会发现问题所在。
【参考方案1】:
巧合的是,在 Pig 的中间存储中用于行拆分的序列也出现在自定义 UDF 返回的字节数组之一中。这会导致 pig 在中间某处断开线,并开始寻找数据类型指示。由于它只是在行的中间,因此没有有效的数据类型指示,因此出现错误。
我还不完全确定我将如何解决这个问题。 @WinnieNicklaus 已经提供了一个很好的解决方案,将脚本分成两部分并存储在两者之间。另一种选择是让 UDF 返回一个 Base64 编码的字节数组。这样就不会与 PIG 中间存储发生冲突,因为它使用 CTRL-A、CTRL-B、CTRL-C、TUPLE-INDICATOR,它们都不是字母数字字符。
【讨论】:
以上是关于Pig 无法读取自己的中间数据的主要内容,如果未能解决你的问题,请参考以下文章