在 Python 中绑定到 Pig STORE 或 DUMP 输出
Posted
技术标签:
【中文标题】在 Python 中绑定到 Pig STORE 或 DUMP 输出【英文标题】:Binding to Pig STORE or DUMP output in Python 【发布时间】:2012-01-12 23:53:25 【问题描述】:我正在寻找“正确”的方式来编写可以处理 Pig 作业输出的 Python 代码。
这是我的情况。我编写了一个 Pig 脚本来处理大量数据并输出一小部分关系。输出数据量小到可以直接DUMP到控制台。例如:
grunt> DUMP results
(Control, column1, column2, column3, column4, column5, column6)
(Treatment1, column1, column2, column3, column4, column5, column6)
(Treatment2, column1, column2, column3, column4, column5, column6)
(Treatment3, column1, column2, column3, column4, column5, column6)
grunt>
下一步,我想对跨关系的数字进行一些数字运算,例如计算观察到的处理结果的显着性的 p-vals。我真的很想为此使用 Python:Pig 本身显然不适合这种任务,我宁愿不要用 Java 重写现有代码。所以我想做的是以某种方式从 python 绑定到 STORE 或 DUMP 命令的输出,然后继续。我的问题是找出前进的最佳方式。以下是我可以看到的方式:
-
使用 Python 编写将执行计算的 UDF。我可以做这个;事实上,我的 Pig 脚本已经调用了几个 Python UDF。但是,我的印象是 UDF 旨在一次处理一个关系/输入行,我需要从多个关系中获取数据以实现我的目标。我可以在调用之间的 UDF 中整合某种状态存储,但这似乎不是正确的解决方案。
在 Pig 0.9.1 中通过 Jython 使用嵌入式 Python。我对这种方法寄予厚望,但从我在该功能上找到的有限文档来看,它似乎主要用于控制工作流程(典型示例是检测交互算法中的收敛),而不是直接处理输出。具体来说,我看到了有关如何绑定到作业元数据的文档,例如它是成功还是失败,但没有看到如何绑定到输出。希望在这件事上被证明是错误的。
让 Python 脚本调用 Pig 并将所需输出位置的本地或 HDFS 路径传递给它,等待作业完成,然后使用 Python 从该路径读取/解析关系。看起来很老套。
我是否缺少一个明显的选项,或者我对上述选项的理解存在很大差距?非常欢迎您的反馈!
【问题讨论】:
我不知道如何对 pig 执行此操作,但 yelp 的 mrjob 正是您在 hadoop 流中的#3 上所要求的。它也可能以某种方式使用猪。谷歌显示了一些人们要求这个的结果。不过,唐纳德矿工的例子对我来说似乎更简单。 【参考方案1】:我从个人经历中理解您的沮丧。 #3 实际上是一种非常合理的方法,但是,我建议稍微不同。相反,使用 bash 脚本包装器来执行两者。这有一个不错的功能,您不必通过 python 进行所有尴尬的 shell 调用。
类似:
pig mypigscript.pig ...
mkdir /tmp/pigout/
hadoop fs -get output/part* /tmp/pigout/
cat /tmp/pigout/* | python mypostprocessing.py
这种方法的好处是您可以非常喜欢参数、日志记录等。在生产中,我通常会将所有不同的阶段写入日志文件、检查阶段是否出错等。
只是为了让您相信这是正确的方法——您不希望在 reducer 中对多条记录进行少量处理。如果您有多个减速器并且没有真正给您任何东西,这将不起作用,因为您没有使用并行性。我认为人们倾向于尝试将过多的计算集中到 Hadoop 中,而不是在外面做一些简单明了的事情。
【讨论】:
感谢您的深刻回答。我完全意识到在 Hadoop 减速器中进行小鱼处理是愚蠢的,而不是将结果提取到更通用的计算环境中。我一直希望找到一种更合理的方式来连接两者;正如您指出的那样,#3 可能是最好的,尽管远非理想。也感谢您建议将 shell 脚本包裹在两者周围 - 这是一个好主意,并且会使事情变得更简单和更容易理解。以上是关于在 Python 中绑定到 Pig STORE 或 DUMP 输出的主要内容,如果未能解决你的问题,请参考以下文章