Hadoop Pig Latin:从日期范围(目录结构的一部分)加载多个文件

Hadoop Pig Latin:从日期范围(目录结构的一部分)加载多个文件,hadoop,apache-pig,Hadoop,Apache Pig,我有下面的场景- 清管器版本使用0.70 HDFS目录结构示例: /user/training/test/20100810/<data files> /user/training/test/20100811/<data files> /user/training/test/20100812/<data files> /user/training/test/20100813/<data files> /user/training/test/20100

我有下面的场景-

清管器版本使用0.70

HDFS目录结构示例:

/user/training/test/20100810/<data files>
/user/training/test/20100811/<data files>
/user/training/test/20100812/<data files>
/user/training/test/20100813/<data files>
/user/training/test/20100814/<data files>
以下内容适用于hadoop:

hadoop fs -ls /user/training/test/{20100810..20100813}
但当我尝试在pig脚本中加载相同内容时,它失败了。如何利用传递给Pig脚本的参数从日期范围加载数据

错误日志如下:

Backend error message during job submission
-------------------------------------------
org.apache.pig.backend.executionengine.ExecException: ERROR 2118: Unable to create input splits for: hdfs://<ServerName>.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://<ServerName>.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://<ServerName>.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://<ServerName>.com/user/training/test/{20100810..20100813}
        at org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.Launcher.getStats(Launcher.java:169)
作业提交期间的
后端错误消息
-------------------------------------------
org.apache.pig.backend.executionengine.ExecutionException:错误2118:无法为以下对象创建输入拆分:hdfs://.com/user/training/test/{20100810..20100813}
位于org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigInputFormat.getSplits(PigInputFormat.java:269)
位于org.apache.hadoop.mapred.JobClient.writeNewSplits(JobClient.java:858)
位于org.apache.hadoop.mapred.JobClient.writeSplits(JobClient.java:875)
位于org.apache.hadoop.mapred.JobClient.access$500(JobClient.java:170)
位于org.apache.hadoop.mapred.JobClient$2.run(JobClient.java:793)
位于org.apache.hadoop.mapred.JobClient$2.run(JobClient.java:752)
位于java.security.AccessController.doPrivileged(本机方法)
位于javax.security.auth.Subject.doAs(Subject.java:396)
位于org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1062)
位于org.apache.hadoop.mapred.JobClient.submitJobInternal(JobClient.java:752)
位于org.apache.hadoop.mapred.JobClient.submitJob(JobClient.java:726)
位于org.apache.hadoop.mapred.jobcontrol.Job.submit(Job.java:378)
位于org.apache.hadoop.mapred.jobcontrol.jobcontrol.startReadyJobs(jobcontrol.java:247)
位于org.apache.hadoop.mapred.jobcontrol.jobcontrol.run(jobcontrol.java:279)
运行(Thread.java:619)
原因:org.apache.hadoop.mapreduce.lib.input.InvalidInputException:输入模式hdfs://.com/user/training/test/{20100810..20100813}与0个文件匹配
位于org.apache.hadoop.mapreduce.lib.input.FileInputFormat.listStatus(FileInputFormat.java:231)
位于org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigTextInputFormat.listStatus(PigTextInputFormat.java:36)
位于org.apache.hadoop.mapreduce.lib.input.FileInputFormat.getSplits(FileInputFormat.java:248)
位于org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigInputFormat.getSplits(PigInputFormat.java:258)
... 14多
清管器堆迹
---------------
错误2997:无法从后端重新创建异常错误:org.apache.pig.backend.executionengine.executeException:错误2118:无法为以下对象创建输入拆分:hdfs://.com/user/training/test/{20100810..20100813}
org.apache.pig.impl.logicalLayer.FrontendException:错误1066:无法打开别名测试的迭代器
位于org.apache.pig.PigServer.openIterator(PigServer.java:521)
位于org.apache.pig.tools.grunt.GruntParser.processDump(GruntParser.java:544)
位于org.apache.pig.tools.pigscript.parser.PigScriptParser.parse(PigScriptParser.java:241)
位于org.apache.pig.tools.grunt.GruntParser.parsetoponerror(GruntParser.java:162)
位于org.apache.pig.tools.grunt.GruntParser.parsetoponerror(GruntParser.java:138)
位于org.apache.pig.tools.grunt.grunt.run(grunt.java:75)
位于org.apache.pig.Main.Main(Main.java:357)
原因:org.apache.pig.backend.executionengine.ExecutionException:错误2997:无法从后端重新创建异常错误:org.apache.pig.backend.executionengine.ExecutionException:错误2118:无法为以下对象创建输入拆分:hdfs://.com/user/training/test/{20100810..20100813}
位于org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.Launcher.getStats(Launcher.java:169)
我是否需要使用Python之类的高级语言来捕获范围内的所有日期戳,并将它们作为逗号分隔的列表传递给LOAD

干杯

我是否需要使用Python之类的高级语言来捕获范围内的所有日期戳,并将它们作为逗号分隔的列表传递给LOAD

可能您不需要-这可以使用自定义加载UDF来完成,或者尝试重新考虑目录结构(如果您的范围基本上是静态的,这将很好)

另外:Pig接受参数,也许这会对您有所帮助(也许您可以执行一个函数,从一天开始加载数据并将其合并到结果集,但我不知道这是否可行)


编辑:可能编写简单的python或bash脚本来生成日期(文件夹)列表是最简单的解决方案,而不仅仅是将其传递给Pig,这应该可以很好地工作

Pig
支持
hdfs
的全局状态

所以我认为猪可以处理这种模式
/user/training/test/{201008102010081120100812}


你能粘贴错误日志吗?

我发现这个问题是由linux shell引起的。Linux shell将帮助您扩展

 {20100810..20100812} 

然后实际运行命令

bin/hadoop fs-ls 20100810 20100811 20100812

但是在
hdfsapi
中,它不会帮助您扩展表达式。

正如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}
列表,如果这是一个罕见的用例,那么这可能是最好的选择,要么编写一个包装器脚本为你生成该列表。对于您所选择的脚本语言来说,从日期范围构建这样一个列表应该是一项简单的任务。对于我的申请,我选择了t
pig -f script.pig -param input=/user/training/test/{20100810..20100812}
temp = LOAD '$input' USING SomeLoader() AS (...);
temp = LOAD '/user/training/test/2010081*/*' USING SomeLoader() AS (...);
load 20100810~20100819 data
temp = LOAD '/user/training/test/2010081{0,1,2}/*' USING SomeLoader() AS (...);
load 20100810~2010812 data
temp = LOAD '/user/training/test/{20100810,20100811,20100812}' USING SomeLoader()
temp = LOAD '/user/training/test/{20100810..20100812}' USING SomeLoader()
temp = LOAD '/user/training/test/{201210*,201211*,201212,2013*}' USING SomeLoader()
filtered = FILTER temp BY (the_date>='2012-10-08')
pig -param input="$(echo {20100810..20100812} | tr ' ' ,)" -f script.pig
temp = LOAD '/user/training/test/{$input}' USING SomeLoader() AS (...);
DT=20180101
DT_LIST=''
for ((i=0; i<=$DAYS; i++))
do
    d=$(date +%Y%m%d -d "${DT} +$i days");
    DT_LIST=${DT_LIST}$d','
done

size=${#DT_LIST}
DT_LIST=${DT_LIST:0:size-1}


pig -p input_data=xxx/yyy/'${DT_LIST}' script.pig