Pig Latin: Charger plusieurs fichiers à partir d'une plage de dates (partie de la structure de répertoire)

StackOverflow https://stackoverflow.com/questions/3515481

  •  29-09-2019
  •  | 
  •  

Question

J'ai le scénario suivant -

Version Pig utilisé 0,70

Exemple structure de répertoire 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>

Comme vous pouvez le voir dans les chemins indiqués ci-dessus, l'un des noms de répertoire est un horodatage.

Problème:. Je veux charger des fichiers à partir d'une plage de dates dire 20100810-20100813

Je peux passer le « de » et « à » de la plage de dates en tant que paramètres du script de porc, mais comment puis-je utiliser ces paramètres dans l'instruction LOAD. Je suis en mesure de faire ce qui suit

temp = LOAD '/user/training/test/{20100810,20100811,20100812}' USING SomeLoader() AS (...);

Les travaux suivants avec Hadoop:

hadoop fs -ls /user/training/test/{20100810..20100813}

Mais il échoue lorsque je tente la même chose avec charge à l'intérieur du script de porc. Comment puis-je utiliser les paramètres passés au script de porc aux données de charge à partir d'une plage de dates?

log d'erreur suivant:

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)

Dois-je faire usage d'un langage plus comme Python pour capturer tous les timbres de date dans la gamme et les transmettre à charge en liste séparée par des virgules?

hourras

Était-ce utile?

La solution

Pig est le traitement de votre modèle de nom de fichier en utilisant les utilitaires de fichiers Hadoop glob, pas les services publics glob de la coquille. de Hadoop sont documentés ici . Comme vous pouvez le voir, Hadoop ne supporte pas l'opérateur « .. » pour une gamme. Il me semble que vous avez deux options - soit écrire la liste des {date1,date2,date2,...,dateN} à la main, qui, si cela est un cas rare d'utilisation est sans doute la voie à suivre, ou écrire un script d'emballage qui génère cette liste pour vous. La construction d'une telle liste à partir d'une plage de dates devrait être une tâche triviale pour le langage de script de votre choix. Pour ma demande, je suis allé avec la route de liste générée, et il va bien travailler (la distribution CHD3).

Autres conseils

zjffdu dit, l'extension de chemin d'accès se fait par l'enveloppe. Une façon commune pour résoudre votre problème est d'utiliser simplement les paramètres Pig (ce qui est une bonne façon de rendre votre script plus resuable de toute façon):

shell:

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

script.pig:

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

i couru à travers cette réponse quand j'avais du mal à essayer de créer un glob de fichier dans un script, puis passer comme paramètre dans un script de porc.

aucune des réponses actuelles appliqué à ma situation, mais j'a trouvé une réponse générale qui pourrait être utile ici.

dans mon cas, l'expansion de la coquille qui se passait et passe alors que dans le script -. Causant des problèmes complets avec l'analyseur de porc, naturellement

donc simplement entourant le glob entre guillemets elle protège d'être expansé par la coquille, et il passe tel quel dans la commande.

ne fonctionnera pas:

$ pig -f my-pig-file.pig -p INPUTFILEMASK='/logs/file{01,02,06}.log' -p OTHERPARAM=6

TRAVAIL WILL

$ pig -f my-pig-file.pig -p INPUTFILEMASK="/logs/file{01,02,06}.log" -p OTHERPARAM=6

J'espère que cela sauve quelqu'un de la douleur et l'agonie.

Depuis travaux:

temp = LOAD '/user/training/test/{20100810,20100811,20100812}' USING SomeLoader()

mais cela ne fonctionne pas:

temp = LOAD '/user/training/test/{20100810..20100812}' USING SomeLoader()

mais si vous voulez une plage de dates portées dire 300 jours et le passage d'une liste complète à charge n'est pas élégant pour dire le moins. Je suis venu avec cela et il fonctionne.

Dites que vous voulez charger les données de 08/10/2012 à aujourd'hui 14/02/2013, ce que vous pouvez faire est

temp = LOAD '/user/training/test/{201210*,201211*,201212,2013*}' USING SomeLoader()

puis faire un filtre après

filtered = FILTER temp BY (the_date>='2012-10-08')
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

si la variable est au milieu du chemin du fichier, le nom du sous-dossier concate ou utilisez « * » pour tous les fichiers.

J'ai trouvé ce problème est causé par shell linux. shell Linux vous aider à développer

 {20100810..20100812} 

à

  20100810 20100811 20100812, 

commande vous fait exécuter

bin/hadoop fs -ls 20100810 20100811 20100812

Mais dans le hdfs api, il ne vous aidera à développer l'expression.

Merci à dave campbell. Une partie de l'au-delà des réponses sont fausses, car ils ont obtenu des votes.

Après mon résultat de test:

  • Travaux

    • pig -f test.pig -param input="/test_{20120713,20120714}.txt"
      • Ne peut pas avoir d'espace avant ou après « » dans l'expression
    • pig -f test.pig -param input="/test_201207*.txt"
    • pig -f test.pig -param input="/test_2012071?.txt"
    • pig -f test.pig -param input="/test_20120713.txt,/test_20120714.txt"
    • pig -f test.pig -param input=/test_20120713.txt,/test_20120714.txt
      • Ne peut pas avoir d'espace avant ou après « » dans l'expression
  • ne fonctionne pas

    • pig -f test.pig -param input="/test_{20120713..20120714}.txt"
    • pig -f test.pig -param input=/test_{20120713,20120714}.txt
    • pig -f test.pig -param input=/test_{20120713..20120714}.txt
  

Dois-je utiliser un langage plus comme Python pour capturer tous les timbres de date dans la gamme et les transmettre à charge en liste séparée par des virgules?

Probablement vous ne -. Cela peut être fait en utilisant UDF de charge personnalisée ou essayez-vous repensant la structure de répertoire (ceci étant bien si vos gammes sont pour la plupart statiques)

En outre: Pig accepte les paramètres, peut-être cela vous aidera (peut-être que vous pourriez faire fonction qui charge les données d'un jour et de l'union à ensemble résultant, mais je ne sais pas s'il est possible)

edit: écriture probablement python simple, ou un script bash qui génère la liste des dates (dossiers) est la solution la plus simple, vous que d'avoir juste pour passer à porc, et cela fonctionne bien

La réponse de Romain, si vous voulez juste la date paramétrez, la coquille se déroulera comme ceci:

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

porc:

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

S'il vous plaît notez les guillemets.

état Pig globe de soutien de hdfs,

Je pense que pig peut gérer le modèle     /user/training/test/{20100810,20100811,20100812},

vous pouvez coller les journaux d'erreur?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top