hadoop - ultimos - Pig Latin: carga varios archivos de un rango de fechas(parte de la estructura del directorio)
ultimo archivo modificado linux (10)
Tengo el siguiente escenario-
La versión de cerdo utilizó 0.70
Ejemplo de estructura de directorio 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>
Como puede ver en las rutas enumeradas anteriormente, uno de los nombres de directorio es un sello de fecha.
Problema: quiero cargar archivos de un rango de fechas desde 20100810 a 20100813.
Puedo pasar el ''de'' y ''a'' del rango de fechas como parámetros del script de Pig, pero ¿cómo hago uso de estos parámetros en la instrucción LOAD? Soy capaz de hacer lo siguiente
temp = LOAD ''/user/training/test/{20100810,20100811,20100812}'' USING SomeLoader() AS (...);
Lo siguiente funciona con hadoop:
hadoop fs -ls /user/training/test/{20100810..20100813}
Pero falla cuando intento lo mismo con LOAD dentro del script de cerdo. ¿Cómo hago uso de los parámetros pasados al script Pig para cargar datos de un rango de fechas?
El registro de error sigue:
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)
¿Debo utilizar un lenguaje superior como Python para capturar todos los sellos de fecha en el rango y pasarlos a CARGAR como una lista separada por comas?
aclamaciones
¿Debo utilizar un lenguaje superior como Python para capturar todos los sellos de fecha en el rango y pasarlos a CARGAR como una lista separada por comas?
Probablemente no lo haga; esto puede hacerse utilizando la UDF de carga personalizada, o intente reconsiderar su estructura de directorios (esto funcionará bien si sus rangos son principalmente estáticos).
adicionalmente: Pig acepta parámetros, tal vez esto podría ayudarte (tal vez podrías hacer una función que cargará datos de un día y los unirá al conjunto resultante, pero no sé si es posible)
editar: probablemente escribir una secuencia de comandos simple de python o bash que genere una lista de fechas (carpetas) es la solución más fácil, solo tienes que pasarla a Pig, y esto debería funcionar bien.
A la respuesta de Romain, si solo quiere parametrizar la fecha, el shell se ejecutará así:
pig -param input="$(echo {20100810..20100812} | tr '' '' ,)" -f script.pig
cerdo:
temp = LOAD ''/user/training/test/{$input}'' USING SomeLoader() AS (...);
Por favor, tenga en cuenta las citas.
Como dijo zjffdu, la expansión de la ruta la realiza el shell. Una forma común de resolver su problema es simplemente usar los parámetros Pig (que es una buena manera de hacer que su script sea más accesible de todos modos):
cáscara:
pig -f script.pig -param input=/user/training/test/{20100810..20100812}
script.pig:
temp = LOAD ''$input'' USING SomeLoader() AS (...);
Encontré que este problema es causado por linux shell. Shell de Linux te ayudará a expandirte
{20100810..20100812}
a
20100810 20100811 20100812,
entonces realmente ejecutas el comando
bin/hadoop fs -ls 20100810 20100811 20100812
Pero en la hdfs api
, no te ayudará a expandir la expresión.
Entonces como esto funciona:
temp = LOAD ''/user/training/test/{20100810,20100811,20100812}'' USING SomeLoader()
Pero esto no funciona:
temp = LOAD ''/user/training/test/{20100810..20100812}'' USING SomeLoader()
pero si desea un rango de fechas que dure 300 días y pasar una lista completa a LOAD no es elegante, por decir lo menos. Se me ocurrió esto y funciona.
Supongamos que quiere cargar datos del 2012-10-08 al día de hoy 2013-02-14, lo que puede hacer es
temp = LOAD ''/user/training/test/{201210*,201211*,201212,2013*}'' USING SomeLoader()
luego haz un filtro después de eso
filtered = FILTER temp BY (the_date>=''2012-10-08'')
Gracias a Dave Campbell. Algunas de las respuestas más allá están mal ya que obtuvieron algunos votos.
A continuación está el resultado de mi prueba:
Trabajos
-
pig -f test.pig -param input="/test_{20120713,20120714}.txt"
- No se puede tener espacio antes o después de "," en la expresión
-
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
- No se puede tener espacio antes o después de "," en la expresión
-
No funciona
-
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
-
Me encontré con esta respuesta cuando tenía problemas para tratar de crear un archivo glob en un script y luego pasarlo como un parámetro en un script de cerdo.
ninguna de las respuestas actuales se aplicó a mi situación, pero encontré una respuesta general que podría ser útil aquí.
en mi caso, estaba ocurriendo la expansión del intérprete de órdenes y luego pasaba eso al guión, lo que causaba problemas completos con el analizador de cerdos, comprensiblemente.
así que simplemente rodeando el globo en comillas dobles lo protege de ser expandido por el caparazón, y lo pasa como está en el comando.
NO FUNCIONARÁ
$ pig -f my-pig-file.pig -p INPUTFILEMASK=''/logs/file{01,02,06}.log'' -p OTHERPARAM=6
TRABAJARÁ
$ pig -f my-pig-file.pig -p INPUTFILEMASK="/logs/file{01,02,06}.log" -p OTHERPARAM=6
Espero que esto le ahorre a alguien algo de dolor y agonía.
Pig está procesando su patrón de nombre de archivo utilizando las utilidades globales de archivo hadoop, no las utilidades globales de shell. Hadoop están documentados here . Como puede ver, hadoop no admite el operador ''..'' para un rango. Me parece que tiene dos opciones: escribir la lista {date1,date2,date2,...,dateN}
mano, que si se trata de un caso de uso raro es probablemente el camino a seguir, o escribir un script de contenedor que genera esa lista para ti. La creación de dicha lista a partir de un rango de fechas debe ser una tarea trivial para el lenguaje de scripts de su elección. Para mi aplicación, me he ido con la ruta de la lista generada, y está funcionando bien (distribución CHD3).
Pig
soporte mundial estado de hdfs
,
entonces creo que pig
puede manejar el patrón /user/training/test/{20100810,20100811,20100812}
,
podrías pegar los registros de error?
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á en el medio de la ruta del archivo, concatena el nombre de la subcarpeta o usa ''*'' para todos los archivos.