2013-04-24 5 views
27

Quali sono i vantaggi dell'utilizzo di chiavi/valori utilizzando null testi (ad esempio new Text(null)). Vedo quanto segue dal libro «Hadoop: The Definitive Guide».Vantaggi dell'utilizzo di NullWritable in Hadoop

NullWritable è un tipo speciale di Writable, in quanto ha una serializzazione a lunghezza zero. Nessun byte viene scritto o letto dallo stream. È usato come segnaposto; ad esempio, in MapReduce, una chiave o un valore può essere dichiarato come NullWritable quando non è necessario utilizzare per memorizzare la posizione in modo efficace. NullWritable può anche essere utile come chiave in SequenceFile quando si desidera memorizzare un elenco di valori, al contrario di per coppie chiave-valore. Si tratta di un Singleton immutabile: l'istanza può essere recuperata chiamando NullWritable.get()

Non capisco chiaramente come l'output è scritto utilizzando NullWritable? Sarà presente un singolo valore costante nel file di output iniziale che indica che le chiavi oi valori di questo file sono null, in modo che il framework MapReduce possa ignorare la lettura delle chiavi/valori null (a seconda di quale sia null)? Inoltre, come sono effettivamente serializzati i testi null?

Grazie,

Venkat

risposta

22

I tipi di chiave/valore deve essere data a tempo di esecuzione, quindi tutto scrittura o lettura NullWritables saprà in anticipo che si avrà a che fare con quel tipo; non c'è nessun marcatore o nulla nel file. E tecnicamente il NullWritables è "letto", è solo che "leggere" un NullWritable è in realtà un no-op. Si può vedere di persona che non c'è niente affatto scritto o letto:

NullWritable nw = NullWritable.get(); 
ByteArrayOutputStream out = new ByteArrayOutputStream(); 
nw.write(new DataOutputStream(out)); 
System.out.println(Arrays.toString(out.toByteArray())); // prints "[]" 

ByteArrayInputStream in = new ByteArrayInputStream(new byte[0]); 
nw.readFields(new DataInputStream(in)); // works just fine 

E per quanto riguarda le tue domande su new Text(null), ancora una volta, si può provare:

Text text = new Text((String)null); 
ByteArrayOutputStream out = new ByteArrayOutputStream(); 
text.write(new DataOutputStream(out)); // throws NullPointerException 
System.out.println(Arrays.toString(out.toByteArray())); 

Text non funziona affatto con un nullString.

+0

Grazie per la vostra tempo e risposta. Ora capisco come funziona NullWritable. Per quanto riguarda il testo nullo, mi dispiace, volevo parlare di avere chiavi/valori come testo e quindi fare un context.write (null, value) (si assuma che la chiave sia testo). –

+0

Ciò dovrebbe anche generare una NullPointerException. chiavi e valori null non funzionano. Se hai veramente bisogno di una chiave o di un valore nullo, dovresti prendere in considerazione qualche altra rappresentazione per questo, come una stringa vuota o -1. –

+2

'contesto.write (null, value) 'funzionerà in realtà per alcuni formati di output (TextOutputFormat ad esempio produrrà solo il valore senza la chiave e il delimitatore configurato) –

0

Modifica il metodo di esecuzione. e il successo

@Override 
public int run(String[] strings) throws Exception { 
    Configuration config = HBaseConfiguration.create(); 
    //set job name 
    Job job = new Job(config, "Import from file "); 
    job.setJarByClass(LogRun.class); 
    //set map class 
    job.setMapperClass(LogMapper.class); 

    //set output format and output table name 
    //job.setOutputFormatClass(TableOutputFormat.class); 
    //job.getConfiguration().set(TableOutputFormat.OUTPUT_TABLE, "crm_data"); 
    //job.setOutputKeyClass(ImmutableBytesWritable.class); 
    //job.setOutputValueClass(Put.class); 

    TableMapReduceUtil.initTableReducerJob("crm_data", null, job); 
    job.setNumReduceTasks(0); 
    TableMapReduceUtil.addDependencyJars(job); 

    FileInputFormat.addInputPath(job, new Path(strings[0])); 

    int ret = job.waitForCompletion(true) ? 0 : 1; 
    return ret; 
} 
0

È sempre possibile avvolgere la stringa nella propria classe scrivibile e hanno un valore booleano che indica che ha stringhe vuote o non:

@Override 
public void readFields(DataInput in) throws IOException { 
    ... 
    boolean hasWord = in.readBoolean(); 
    if(hasWord) { 
     word = in.readUTF(); 
    } 
    ... 
} 

e Joe

@Override 
public void write(DataOutput out) throws IOException { 
    ... 
    boolean hasWord = StringUtils.isNotBlank(word); 
    out.writeBoolean(hasWord); 
    if(hasWord) { 
     out.writeUTF(word); 
    } 
    ... 
}