2012-07-19 18 views
5

Una consulta sqoop genera un archivo java que contiene una clase que contiene el código para obtener acceso en mapreduce a los datos de las columnas de cada fila. (la importación Sqoop se realizó en texto sin la opción --as-sequencefile, y con 1 línea por registro y comas entre las columnas) Pero, ¿cómo lo usamos realmente? Encontré un método público parse() en esta clase que toma el texto como entrada y rellena todos los miembros de la clase, así que para practicar modifiqué la aplicación de conteo de palabras para convertir una línea de texto del TextInputFormat en el asignador en una instnace de la clase generada por sqoop. Pero eso causa una "excepción.com.cloudera.sqoop.lib.RecordParser.ParseError no reportada; debe ser atrapada o declarada para ser lanzada" cuando llamo al método parse().¿Cómo se usa la clase generada en sqoop en MapReduce?

¿Se puede hacer de esta manera o es un InputFormat personalizado necesario para completar la clase con los datos de cada registro?

Respuesta

4

Ok, esto parece obvio una vez que lo descubras, pero como principiante de Java esto puede llevar tiempo.

Primero configure su proyecto: simplemente agregue el archivo .java generado en sqoop en su carpeta de origen. Uso eclipse para importarlo en la carpeta fuente de mi clase.

A continuación, sólo asegúrese de que configura la ruta de compilación de Java de su proyecto correctamente:

Añadir los siguientes archivos jar en las propiedades del proyecto/java build path/bibliotecas/Agregar archivo JAR externo: (por hadoop cdh4 +):

/usr/lib/hadoop/hadoop-common.jar 
/usr/lib/hadoop-[version]-mapreduce/hadoop-core.jar 
/usr/lib/sqoop/sqoop-[sqoop-version]-cdh[cdh-version].jar 

Entonces adaptar su código fuente mapreduce: Primera configurarlo:

public int run(String [] args) throws exception 
{ 
Job job = new Job(getConf()); 
job.setJarByClass(YourClass.class); 
job.setMapperClass(SqoopImportMap.class); 
job.setReducerClass(SqoopImprtReduce.class); 

FileInputFormat.addInputPath((job,"hdfs_path_to_your_sqoop_imported_file")); 
FileOutputFormat.setOutputPath((job,"hdfs_output_path")); 

// I simply use text as output for the mapper but it can be any class you designed 
// as long as you implement it as a Writable 
job.setMapOutputKeyClass(Text.Class); 
job.setMapOutputValueClass(Text.Class); 

job.setOutputKeyClass(Text.Class); 
job.setOutputValueClass(Text.Class); 
... 

n w configura tu clase de mapeador. Supongamos que su archivo Java importados Sqoop se llama Sqimp.java: y la mesa que ha importado tenía las siguientes columnas: id, nombre, edad su clase Mapper debería tener este aspecto:

public static class SqoopImportMap 
extends Mapper<LongWritable, Text, Text, Text> 
{ 

public void map(LongWritable k, Text v, Context context) 
{ 
    Sqimp s = new Sqimp(); 
    try 
    { 
    // this is where the code generated by sqoop is used. 
    // it automatically casts one line of the imported data into an instance of the generated class, 
    // to let you access the data inside the columns easily 
    s.parse(v); 
    } 
    catch(ParseError pe) {// do something if there is an error.} 

    try 
    { 
    // now the imported data is accessible: 
    // e.g 
    if (s.age>30) 
    { 
    // submit the selected data to the mapper's output as a key value pair. 
    context.write(new Text(s.age),new Text(s.id)); 
    } 
    } 
    catch(Exception ex) 
    {//do something about the error} 
} 
} 
Cuestiones relacionadas