要在Hadoop中有效利用地图缩减作业,我需要将数据存储在hadoop's sequence file format中。但是,目前数据只是平面.txt格式。任何人都建议我可以将.txt文件转换为序列文件吗?
答案 0 :(得分:32)
因此,最简单的答案只是一个具有SequenceFile输出的“身份”工作。
在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);
}
答案 1 :(得分:16)
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);
}
}
}
答案 2 :(得分:7)
这取决于TXT文件的格式。每条记录是一行吗?如果是这样,您可以简单地使用TextInputFormat,为每行创建一条记录。在您的映射器中,您可以解析该行并以您选择的方式使用它。
如果每条记录不是一行,则可能需要编写自己的InputFormat实现。请查看this tutorial以获取更多信息。
答案 3 :(得分:4)
您也可以创建一个中间表,将csv内容直接加载到其中,然后创建第二个表作为sequencefile(分区,聚簇等等)并插入到中间表中的select中。您还可以设置压缩选项,例如
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 ...;
MR框架将为您处理重型提升,为您节省编写Java代码的麻烦。
答案 4 :(得分:1)
要警醒用格式说明:
。
例如(请注意%
和s
之间的空格),System.out.printf("[% s]\t% s\t% s\n", writer.getLength(), key, value);
将给我们java.util.FormatFlagsConversionMismatchException: Conversion = s, Flags =
相反,我们应该使用:
System.out.printf("[%s]\t%s\t%s\n", writer.getLength(), key, value);
答案 5 :(得分:0)
如果您的数据不在HDFS上,则需要将其上传到HDFS。两个选项:
i)hdfs -put在.txt文件上,一旦你在HDFS上获得它,你可以将它转换为seq文件。
ii)您将文本文件作为输入放在HDFS客户端盒子上,并使用Sequence File API转换为SeqFile,方法是创建一个SequenceFile.Writer并附加(键,值)。
如果您不关心密钥,您可以将行号作为键,将完整文本作为值。
答案 6 :(得分:0)
如果你安装了Mahout - 它有一个名为:seqdirectory - 可以做到的