복붙노트

[HADOOP] 돼지 라틴어 : 날짜 범위에서 여러 파일로드 (디렉토리 구조의 일부)

HADOOP

돼지 라틴어 : 날짜 범위에서 여러 파일로드 (디렉토리 구조의 일부)

나는 다음과 같은 시나리오를 가지고있다.

돼지 버전 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>

위에 나열된 경로에서 볼 수 있듯이 디렉토리 이름 중 하나는 날짜 스탬프입니다.

문제점 : 20100810에서 20100813 사이의 날짜 범위에있는 파일을로드하고 싶습니다.

돼지 스크립트에 매개 변수로 날짜 범위의 '에서'및 '에서'를 전달할 수 있지만 어떻게 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://<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)

해당 범위의 모든 날짜 스탬프를 캡처하고이를 LOAD에 쉼표로 구분 된 목록으로 전달하려면 Python과 같은 상위 언어를 사용해야합니까?

건배

해결법

  1. ==============================

    1.돼지는 쉘의 glob 유틸리티가 아닌 hadoop 파일 glob 유틸리티를 사용하여 파일 이름 패턴을 처리하고 있습니다. 하둡은 여기에 문서화되어 있습니다. 보시다시피, hadoop은 범위에 대한 '..'연산자를 지원하지 않습니다. 아마도 두 가지 옵션이 있습니다. {date1, date2, date2, ..., dateN} 목록을 수동으로 작성하십시오.이 경우 드문 유스 케이스 인 경우 이동하는 것이 좋습니다. 또는 래퍼 스크립트를 작성하십시오. 그 목록을 생성합니다. 날짜 범위에서 그러한 목록을 작성하는 것은 원하는 스크립팅 언어에 대한 간단한 작업이어야합니다. 내 응용 프로그램의 경우 생성 된 목록 경로를 따라 갔으며 제대로 작동합니다 (CHD3 배포).

    돼지는 쉘의 glob 유틸리티가 아닌 hadoop 파일 glob 유틸리티를 사용하여 파일 이름 패턴을 처리하고 있습니다. 하둡은 여기에 문서화되어 있습니다. 보시다시피, hadoop은 범위에 대한 '..'연산자를 지원하지 않습니다. 아마도 두 가지 옵션이 있습니다. {date1, date2, date2, ..., dateN} 목록을 수동으로 작성하십시오.이 경우 드문 유스 케이스 인 경우 이동하는 것이 좋습니다. 또는 래퍼 스크립트를 작성하십시오. 그 목록을 생성합니다. 날짜 범위에서 그러한 목록을 작성하는 것은 원하는 스크립팅 언어에 대한 간단한 작업이어야합니다. 내 응용 프로그램의 경우 생성 된 목록 경로를 따라 갔으며 제대로 작동합니다 (CHD3 배포).

  2. ==============================

    2.zjffdu가 말했듯이, 경로 확장은 쉘에 의해 수행됩니다. 문제를 해결하는 일반적인 방법 중 하나는 돼지 매개 변수를 사용하는 것입니다 (스크립트를 더 쉽게 복원 할 수있는 좋은 방법입니다).

    zjffdu가 말했듯이, 경로 확장은 쉘에 의해 수행됩니다. 문제를 해결하는 일반적인 방법 중 하나는 돼지 매개 변수를 사용하는 것입니다 (스크립트를 더 쉽게 복원 할 수있는 좋은 방법입니다).

    껍질:

    pig -f script.pig -param input=/user/training/test/{20100810..20100812}
    

    script.pig :

    temp = LOAD '$input' USING SomeLoader() AS (...);
    
  3. ==============================

    3.스크립트에서 파일 glob을 만들고 돼지 스크립트에 매개 변수로 전달할 때 문제가 발생했을 때이 대답을 조사했습니다.

    스크립트에서 파일 glob을 만들고 돼지 스크립트에 매개 변수로 전달할 때 문제가 발생했을 때이 대답을 조사했습니다.

    현재 상황에 맞는 답변이 없지만 여기서 도움이 될만한 일반적인 답을 찾았습니다.

    제 경우에는 셸 확장이 일어나고 스크립트로 전달되어서 돼지 파서와 관련된 문제가 발생했습니다.

    따라서 glob를 큰 따옴표로 감싸는 것만으로 쉘에 의해 확장되지 않도록 보호하고 그대로 명령에 전달합니다.

    작동하지 않을 것입니다 :

    $ 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
    

    나는 이것이 누군가 고통과 고통을 덜어주기를 바랍니다.

  4. ==============================

    4.그래서 이것은 작동합니다 :

    그래서 이것은 작동합니다 :

    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')
    
  5. ==============================

    5.

    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
    

    변수가 파일 경로의 중간에 있으면 하위 폴더 이름을 연결하거나 모든 파일에 '*'를 사용하십시오.

  6. ==============================

    6.나는이 문제가 리눅스 껍질에 의해 발견 된 것을 발견했다. Linux 셸이 확장에 도움이됩니다.

    나는이 문제가 리눅스 껍질에 의해 발견 된 것을 발견했다. Linux 셸이 확장에 도움이됩니다.

     {20100810..20100812} 
    

      20100810 20100811 20100812, 
    

    당신은 실제로 명령을 실행합니다.

    bin/hadoop fs -ls 20100810 20100811 20100812
    

    그러나 hdfs api에서는 표현을 확장하는 데 도움이되지 않습니다.

  7. ==============================

    7.dave campbell에게 감사드립니다. 몇 가지 득표를 한 이후의 답변은 잘못되었습니다.

    dave campbell에게 감사드립니다. 몇 가지 득표를 한 이후의 답변은 잘못되었습니다.

    다음은 내 테스트 결과입니다.

  8. ==============================

    8.아마도 사용자 정의로드 UDF를 사용하여 수행 할 수 있습니다. 또는 디렉토리 구조를 다시 생각해보십시오. 범위가 거의 정적 인 경우이 방법이 유용합니다.

    아마도 사용자 정의로드 UDF를 사용하여 수행 할 수 있습니다. 또는 디렉토리 구조를 다시 생각해보십시오. 범위가 거의 정적 인 경우이 방법이 유용합니다.

    추가로 : 돼지는 매개 변수를 받아 들일 수 있습니다. 어쩌면 이것이 도움이 될 것입니다 (어쩌면 당신은 언젠가는 데이터를로드하여 결과 집합으로 합쳐주는 함수를 만들 수 있습니다. 그러나 가능한지 모르겠습니다)

    편집 : 아마도 날짜 (폴더)의 목록을 생성하는 간단한 파이썬이나 bash 스크립트를 작성하는 것이 가장 쉬운 해결책입니다. 단지 돼지에게 전달해야하는 것보다 훨씬 잘됩니다.

  9. ==============================

    9.Romain의 답변에 대해, 날짜를 매개 변수화하려는 경우 셸은 다음과 같이 실행됩니다.

    Romain의 답변에 대해, 날짜를 매개 변수화하려는 경우 셸은 다음과 같이 실행됩니다.

    pig -param input="$(echo {20100810..20100812} | tr ' ' ,)" -f script.pig
    

    돼지:

    temp = LOAD '/user/training/test/{$input}' USING SomeLoader() AS (...);
    

    따옴표를 유의하십시오.

  10. ==============================

    10.돼지 지원 글로브 상태 hdfs,

    돼지 지원 글로브 상태 hdfs,

    그래서 나는 돼지가 그 패턴을 다룰 수 있다고 생각한다.     / user / training / test / {20100810,20100811,20100812},

    오류 로그를 붙여 넣을 수 있습니까?

  11. from https://stackoverflow.com/questions/3515481/pig-latin-load-multiple-files-from-a-date-range-part-of-the-directory-structur by cc-by-sa and MIT license