2012-07-19 8 views
5

Una query sqoop genera un file java che contiene una classe che contiene il codice per ottenere l'accesso in mapreduce ai dati delle colonne per ogni riga. (l'importazione di Sqoop è stata eseguita in testo senza l'opzione --as-sequencefile e con 1 riga per record e virgole tra le colonne) Ma come si usa effettivamente?Come utilizzare la classe generata da sqoop in MapReduce?

Ho trovato un metodo pubblico parse() in questa classe che accetta Text come input e popola tutti i membri della classe, quindi per esercitarmi ho modificato l'applicazione wordcount per convertire una riga di testo da TextInputFormat nel mapper in un instnace della classe generata da sqoop. Ma ciò causa un "eccezione non dichiarata.com.cloudera.sqoop.lib.RecordParser.ParseError; deve essere catturato o dichiarato essere gettato" quando chiamo il metodo parse().

Può essere eseguito in questo modo o è un formato di input personalizzato necessario per popolare la classe con i dati di ogni record?

risposta

4

Ok questo sembra ovvio una volta scoperto, ma come un principiante java questo può richiedere tempo.

Per prima cosa configurare il progetto: basta aggiungere il file .java generato sqoop nella cartella di origine. Io uso eclipse per importarlo nella mia cartella sorgente di classe.

Poi basta assicurarsi che si configurato java percorso di generazione del progetto in modo corretto:

Aggiungere i seguenti file jar nelle proprietà del progetto/java percorso di generazione/librerie/aggiungere jar esterni: (per 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 

Poi adattare il codice sorgente MapReduce: primo configurarla:

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); 
... 

No w configura la tua classe mapper. Supponiamo che il file java importato Sqoop si chiama Sqimp.java: e il tavolo è stato importato avuto le seguenti colonne: id, nome, l'età la classe mapper dovrebbe assomigliare a questa:

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} 
} 
} 
Problemi correlati