Pregunta

Para utilizar efectivamente los trabajos de reducción de mapas en Hadoop, necesito que se almacenen datos en Formato de archivo de secuencia de Hadoop. Sin embargo, actualmente los datos solo están en formato .txt plano. ¿Alguien puede sugerir una forma en que puedo convertir un archivo .txt en un archivo de secuencia?

¿Fue útil?

Solución

Entonces, la forma más simple de respuesta es solo un trabajo de "identidad" que tiene una salida de archivo de secuencia.

Parece esto en Java:

    public static void main(String[] args) throws IOException,
        InterruptedException, ClassNotFoundException {

    Configuration conf = new Configuration();
    Job job = new Job(conf);
    job.setJobName("Convert Text");
    job.setJarByClass(Mapper.class);

    job.setMapperClass(Mapper.class);
    job.setReducerClass(Reducer.class);

    // increase if you need sorting or a special number of files
    job.setNumReduceTasks(0);

    job.setOutputKeyClass(LongWritable.class);
    job.setOutputValueClass(Text.class);

    job.setOutputFormatClass(SequenceFileOutputFormat.class);
    job.setInputFormatClass(TextInputFormat.class);

    TextInputFormat.addInputPath(job, new Path("/lol"));
    SequenceFileOutputFormat.setOutputPath(job, new Path("/lolz"));

    // submit and wait for completion
    job.waitForCompletion(true);
   }

Otros consejos

import java.io.IOException;
import java.net.URI;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.Text;

//White, Tom (2012-05-10). Hadoop: The Definitive Guide (Kindle Locations 5375-5384). OReilly Media - A. Kindle Edition. 

public class SequenceFileWriteDemo { 

    private static final String[] DATA = { "One, two, buckle my shoe", "Three, four, shut the door", "Five, six, pick up sticks", "Seven, eight, lay them straight", "Nine, ten, a big fat hen" };

    public static void main( String[] args) throws IOException { 
        String uri = args[ 0];
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(URI.create( uri), conf);
        Path path = new Path( uri);
        IntWritable key = new IntWritable();
        Text value = new Text();
        SequenceFile.Writer writer = null;
        try { 
            writer = SequenceFile.createWriter( fs, conf, path, key.getClass(), value.getClass());
            for (int i = 0; i < 100; i ++) { 
                key.set( 100 - i);
                value.set( DATA[ i % DATA.length]);
                System.out.printf("[% s]\t% s\t% s\n", writer.getLength(), key, value); 
                writer.append( key, value); } 
        } finally 
        { IOUtils.closeStream( writer); 
        } 
    } 
}

Depende de cuál sea el formato del archivo txt. ¿Es una línea por récord? Si es así, simplemente puede usar TextInputFormat que crea un registro para cada línea. En su mapeador puede analizar esa línea y usarla de cualquier forma que elija.

Si no es una línea por registro, es posible que deba escribir su propia implementación de InputFormat. Echa un vistazo a este tutorial para más información.

También puede crear una tabla intermedia, cargar datos los contenidos de CSV directamente en él, luego crear una segunda tabla como secuencefile (dividido, agrupado, etc.) e inserte en seleccionar la tabla intermedia. También puede establecer opciones de compresión, por ejemplo,

set hive.exec.compress.output = true;
set io.seqfile.compression.type = BLOCK;
set mapred.output.compression.codec = org.apache.hadoop.io.compress.SnappyCodec;

create table... stored as sequencefile;

insert overwrite table ... select * from ...;

El MR Framework se encargará de la pesada por usted, ahorrándole la molestia de tener que escribir el código Java.

Estar vigilante con el especificador de formato :.

Por ejemplo (tenga en cuenta el espacio entre % y s), System.out.printf("[% s]\t% s\t% s\n", writer.getLength(), key, value); nos dará java.util.FormatFlagsConversionMismatchException: Conversion = s, Flags =

En cambio, debemos usar:

System.out.printf("[%s]\t%s\t%s\n", writer.getLength(), key, value); 

Si sus datos no están en HDFS, debe cargarlo en HDFS. Dos opciones:

i) HDFS -put en su archivo .txt y una vez que lo obtenga en HDFS, puede convertirlo en archivo SEQ.

ii) Toma el archivo de texto como entrada en su cuadro de cliente HDFS y se convierte en SEQFile usando las API de archivo de secuencia creando una secuenceFile.Writer y Appending (clave, valores).

Si no le importa la clave, puede hacer el número de línea como clave y completar el texto como valor.

Si tiene Mahout instalado, tiene algo llamado: SeqDirectory, que puede hacerlo

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top