在过去一周左右的时间里,我们获得了一些新数据,必须快速处理。 有很多技术可以快速在Hadoop上减少地图/减少工作( 级联 , Hive , Crunch , Jaql等),我个人最喜欢的是Apache Pig 。 我发现猪的当务之急是,相对容易理解正在发生的事情以及数据将要去往何处,并且它可以产生足够有效的地图/缩减图。 不利的一面是,pig缺乏控制结构,因此使用pig也意味着您需要使用用户定义的函数(UDF)或Hadoop流对其进行扩展。 通常,我使用Java或Scala编写UDF,但是尝试一些新的东西总是很不错的,所以我们决定签出其他一些技术,即perl和python。 这篇文章重点介绍了我们遇到的一些陷阱以及如何解决这些陷阱。
在这个小型项目上与我合作的Yuval喜欢perl(我想每个人都喜欢),因此我们从此开始。 在搜索pig和perl示例时,我们发现了以下内容:
A = LOAD 'data';
B = STREAM A THROUGH `stream.pl`;
这里的第一个陷阱是,perl脚本名称被反引号(波浪号(〜)键上的字符)包围,而不是单引号(因此,在上面的脚本中,“数据”被单引号和`stream.pl包围) `被反引号包围)。 第二个陷阱是,当您在本地模式下使用pig(pig -x local)时,上面的代码可以很好地工作,但是当我们尝试在集群上运行它时,它失败了。 它花费了一些时间来抓挠和反复试验,但最终Yuval附带了以下内容:
DEFINE CMD `perl stream.pl` ship ('/PATH/stream.pl');
A = LOAD 'data'
B = STREAM A THROUGH CMD;
基本上,我们告诉Pig将Pig脚本复制到HDFS,以便可以在所有节点上访问它。 因此,perl运作良好,但是由于我们使用的是Hadoop Streaming并通过stdin获取数据,所以我们丢失了Pig知道的所有数据上下文。 我们还需要模拟袋子和元组的文本表示,以便将返回的数据提供给Pig进行进一步的工作。 这都是可行的,但与它一起工作并不有趣(无论如何,我认为)。 我决定用python编写Pig UDF。 python可以与Apache流一起使用,就像上面的perl一样,但是它也可以通过jython与Pig紧密集成(即python UDF被编译成java并作为生成的map / reduce jar jar生成罐的一部分发运到集群) 。
Pig的UDF比流式的更好,因为您可以获得参数的Pig架构,并且可以告诉Pig为输出返回的架构。 python中的UDF特别好,因为代码几乎是100%常规的python,而Pig为您进行了映射(例如,pig中的一包元组会转换为python中的元组列表等)。 实际上,唯一的区别是,如果您希望Pig知道从python代码返回的数据类型,则需要使用@outputSchema注释该方法,例如,一个简单的UDF从YYYY格式的日期字符串中获取月份作为整数。 -MM-DD HH:MM:SS
@outputSchema('num:int')
def getMonth(strDate):
try:
dt, _, _ = strDate.partition('.')
return datetime.strptime(dt, '%Y-%m-%d %H:%M:%S').month
except AttributeError:
return 0
except IndexError:
return 0
except ValueError:
return 0
使用PDF就像声明定义UDF的python文件一样简单。 假设我们的UDF在名为utils.py的文件中,则将声明如下:
Register utils.py using jython as utils;
然后使用该UDF会像这样:
A = LOAD 'data' using PigStorage('|') as (dateString:chararray);
B = FOREACH A GENERATE utils.getMonth(dateString) as month;
再次,就像在perl案例中一样,这里有一些陷阱。 对于一个,python脚本和pig脚本需要在同一目录中(相对路径仅在本地模式下起作用)。 当我想导入一些python库时(例如,示例中的datetime是使用“ from datetime import datetime”导入的),更烦人的陷阱袭来了。 我没有办法提出这项工作。 我最终想到的解决方案是采用一个jyhton独立.jar(一个包含普通python库的jar),并用stanalone替换Pig的jython Jar(在pig lib目录中)。 也许有更好的方法可以做到这一点(我很乐意听到),但这对我有用。 只需在运行Pig脚本的机器上完成,因为python代码会被编译并作为Pig生成的jar文件的一部分传送到集群中。
使用Pig和python确实很棒。 我更喜欢用python编写猪UDF,而不是用Java或Scala编写它们。 造成这种情况的两个主要原因是,没有很多与Pig集成的Java组件,因此我只能专注于解决业务问题,另一个原因是Pig和Python都是“脚本”,因此反馈循环改变它的工作原理要短得多。 无论如何,Pig也支持Javascript和Ruby UDF,但是它们必须等待下一次。
参考:“ 放牧Apache Pig” – Cirrus Minor博客上的JCG合作伙伴 Arnon Rotem-Gal-Oz 使用Pig与Perl和Python结合使用 。
翻译自: https://www.javacodegeeks.com/2013/03/herding-apache-pig-using-pig-with-perl-and-python.html