我有以下情况 -
猪版使用0.70
HDFS目录结构示例:
/user/training/test/20100810/ /user/training/test/20100811/ /user/training/test/20100812/ /user/training/test/20100813/ /user/training/test/20100814/
正如您在上面列出的路径中看到的,其中一个目录名称是日期戳.
问题:我想从20100810到20100813之间的日期范围加载文件.
我可以将日期范围的'from'和'to'作为参数传递给Pig脚本,但是如何在LOAD语句中使用这些参数.我能够做到以下几点
temp = LOAD '/user/training/test/{20100810,20100811,20100812}' USING SomeLoader() AS (...);
以下适用于hadoop:
hadoop fs -ls /user/training/test/{20100810..20100813}
但是当我在猪脚本中尝试使用LOAD时它失败了.如何利用传递给Pig脚本的参数从日期范围加载数据?
错误日志如下:
Backend error message during job submission ------------------------------------------- org.apache.pig.backend.executionengine.ExecException: ERROR 2118: Unable to create input splits for: hdfs://.com/user/training/test/{20100810..20100813} at org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigInputFormat.getSplits(PigInputFormat.java:269) at org.apache.hadoop.mapred.JobClient.writeNewSplits(JobClient.java:858) at org.apache.hadoop.mapred.JobClient.writeSplits(JobClient.java:875) at org.apache.hadoop.mapred.JobClient.access$500(JobClient.java:170) at org.apache.hadoop.mapred.JobClient$2.run(JobClient.java:793) at org.apache.hadoop.mapred.JobClient$2.run(JobClient.java:752) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:396) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1062) at org.apache.hadoop.mapred.JobClient.submitJobInternal(JobClient.java:752) at org.apache.hadoop.mapred.JobClient.submitJob(JobClient.java:726) at org.apache.hadoop.mapred.jobcontrol.Job.submit(Job.java:378) at org.apache.hadoop.mapred.jobcontrol.JobControl.startReadyJobs(JobControl.java:247) at org.apache.hadoop.mapred.jobcontrol.JobControl.run(JobControl.java:279) at java.lang.Thread.run(Thread.java:619) Caused by: org.apache.hadoop.mapreduce.lib.input.InvalidInputException: Input Pattern hdfs:// .com/user/training/test/{20100810..20100813} matches 0 files at org.apache.hadoop.mapreduce.lib.input.FileInputFormat.listStatus(FileInputFormat.java:231) at org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigTextInputFormat.listStatus(PigTextInputFormat.java:36) at org.apache.hadoop.mapreduce.lib.input.FileInputFormat.getSplits(FileInputFormat.java:248) at org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigInputFormat.getSplits(PigInputFormat.java:258) ... 14 more Pig Stack Trace --------------- ERROR 2997: Unable to recreate exception from backend error: org.apache.pig.backend.executionengine.ExecException: ERROR 2118: Unable to create input splits for: hdfs:// .com/user/training/test/{20100810..20100813} org.apache.pig.impl.logicalLayer.FrontendException: ERROR 1066: Unable to open iterator for alias test at org.apache.pig.PigServer.openIterator(PigServer.java:521) at org.apache.pig.tools.grunt.GruntParser.processDump(GruntParser.java:544) at org.apache.pig.tools.pigscript.parser.PigScriptParser.parse(PigScriptParser.java:241) at org.apache.pig.tools.grunt.GruntParser.parseStopOnError(GruntParser.java:162) at org.apache.pig.tools.grunt.GruntParser.parseStopOnError(GruntParser.java:138) at org.apache.pig.tools.grunt.Grunt.run(Grunt.java:75) at org.apache.pig.Main.main(Main.java:357) Caused by: org.apache.pig.backend.executionengine.ExecException: ERROR 2997: Unable to recreate exception from backend error: org.apache.pig.backend.executionengine.ExecException: ERROR 2118: Unable to create input splits for: hdfs:// .com/user/training/test/{20100810..20100813} at org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.Launcher.getStats(Launcher.java:169)
我是否需要使用像Python这样的更高语言来捕获范围内的所有日期戳,并将它们作为逗号分隔列表传递给LOAD?
干杯
正如zjffdu所说,路径扩展是由shell完成的.解决问题的一种常见方法是简单地使用Pig参数(这是使脚本更加可恢复的好方法):
贝壳:
pig -f script.pig -param input=/user/training/test/{20100810..20100812}
script.pig:
temp = LOAD '$input' USING SomeLoader() AS (...);
Pig正在使用hadoop文件glob实用程序处理你的文件名模式,而不是shell的glob实用程序.这里记录了 Hadoop .如您所见,hadoop不支持范围的'..'运算符.在我看来,你有两个选择 - 要么{date1,date2,date2,...,dateN}
手工写出列表,如果这是一个罕见的用例可能是要走的路,或者写一个包装脚本为你生成该列表.从日期范围构建这样的列表对于您选择的脚本语言来说应该是一项微不足道的任务.对于我的应用程序,我已经使用生成的列表路径,它工作正常(CHD3分发).
当我在尝试在脚本中创建文件glob然后将其作为参数传递到pig脚本时,我遇到了这个答案.
目前的答案都没有适用于我的情况,但我确实找到了一个可能有用的一般答案.
在我的情况下,shell扩展正在发生,然后将其传递到脚本中 - 导致猪解析器完全出现问题,这是可以理解的.
因此,通过简单地用双引号包围glob来保护它不被shell扩展,并将其原样传递给命令.
不会工作:
$ pig -f my-pig-file.pig -p INPUTFILEMASK='/logs/file{01,02,06}.log' -p OTHERPARAM=6
将工作
$ pig -f my-pig-file.pig -p INPUTFILEMASK="/logs/file{01,02,06}.log" -p OTHERPARAM=6
我希望这可以为某些人带来痛苦和痛苦.
所以,因为这工作:
temp = LOAD '/user/training/test/{20100810,20100811,20100812}' USING SomeLoader()
但这不起作用:
temp = LOAD '/user/training/test/{20100810..20100812}' USING SomeLoader()
但是如果你想要一个跨越300天的日期范围并且将完整列表传递给LOAD则至少可以说是不优雅的.我想出了这个并且它有效.
假设您要将数据从2012-10-08加载到今天2013-02-14,您可以做的是
temp = LOAD '/user/training/test/{201210*,201211*,201212,2013*}' USING SomeLoader()
然后在那之后做一个过滤器
filtered = FILTER temp BY (the_date>='2012-10-08')