我在hdfs中存储了大量的数据,但是单个文件非常小(kbs)。所以mapreduce处理要花很多时间。我能缩短处理时间吗?sequencefile是个不错的选择吗?请提供一些java或mr代码将多个较小的文本文件转换为sequencefile。
0kjbasz61#
您可以覆盖 org.apache.hadoop.mapred.lib.CombineFileInputFormat 创建你的 CombinedInputFormat . 关于实现,请看我的答案。通过设置参数 mapred.max.split.size 您可以控制要将输入文件合并到的大小。更多详情请阅读这里。
org.apache.hadoop.mapred.lib.CombineFileInputFormat
CombinedInputFormat
mapred.max.split.size
e37o9pze2#
在这种情况下,sequencefile将是一个不错的选择。你可以这样做:
public class TextToSequenceConverter { /** * @param args * @throws IOException * @throws IllegalAccessException * @throws InstantiationException */ @SuppressWarnings("deprecation") public static void main(String[] args) throws IOException, InstantiationException, IllegalAccessException { // TODO Auto-generated method stub Configuration conf = new Configuration(); conf.addResource(new Path("/hadoop/projects/hadoop-1.0.4/conf/core-site.xml")); conf.addResource(new Path("/hadoop/projects/hadoop-1.0.4/conf/hdfs-site.xml")); FileSystem fs = FileSystem.get(conf); Path inputFile = new Path("/infile"); FSDataInputStream inputStream = fs.open(inputFile); Path outputFile = new Path("/outfile"); IntWritable key = new IntWritable(); int count = 0; Text value = new Text(); String str; SequenceFile.Writer writer = SequenceFile.createWriter(fs, conf,outputFile, key.getClass(), value.getClass()); while (inputStream.available() > 0) { key.set(count++); str = inputStream.readLine(); value.set(str); writer.append(key, value); } fs.close(); IOUtils.closeStream(writer); System.out.println("SEQUENCE FILE CREATED SUCCESSFULLY........"); } }
你可能还想看看har文件。你可能会发现这是一本很好的读物:http://blog.cloudera.com/blog/2009/02/the-small-files-problem/要将hdfs目录中的所有文件转换为单个序列文件,请执行以下操作:
package my.pack; import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.io.SequenceFile; import org.apache.hadoop.io.Text; public class BundleSeq { /** * @param args * @throws IOException * @throws IllegalAccessException * @throws InstantiationException */ public static void main(String[] args) throws IOException, InstantiationException, IllegalAccessException { // TODO Auto-generated method stub Configuration conf = new Configuration(); conf.addResource(new Path( "/hadoop/projects/hadoop-1.0.4/conf/core-site.xml")); conf.addResource(new Path( "/hadoop/projects/hadoop-1.0.4/conf/hdfs-site.xml")); FileSystem fs = FileSystem.get(conf); Path inputFile = new Path("/bundleinput"); Path outputFile = new Path("/outfile"); FSDataInputStream inputStream; Text key = new Text(); Text value = new Text(); SequenceFile.Writer writer = SequenceFile.createWriter(fs, conf, outputFile, key.getClass(), value.getClass()); FileStatus[] fStatus = fs.listStatus(inputFile); for (FileStatus fst : fStatus) { String str = ""; System.out.println("Processing file : " + fst.getPath().getName() + " and the size is : " + fst.getPath().getName().length()); inputStream = fs.open(fst.getPath()); key.set(fst.getPath().getName()); while(inputStream.available()>0) { str = str+inputStream.readLine(); } value.set(str); writer.append(key, value); } fs.close(); IOUtils.closeStream(writer); System.out.println("SEQUENCE FILE CREATED SUCCESSFULLY........"); } }
这里filename是键,file content是值。
2条答案
按热度按时间0kjbasz61#
您可以覆盖
org.apache.hadoop.mapred.lib.CombineFileInputFormat
创建你的CombinedInputFormat
. 关于实现,请看我的答案。通过设置参数mapred.max.split.size
您可以控制要将输入文件合并到的大小。更多详情请阅读这里。
e37o9pze2#
在这种情况下,sequencefile将是一个不错的选择。你可以这样做:
你可能还想看看har文件。
你可能会发现这是一本很好的读物:http://blog.cloudera.com/blog/2009/02/the-small-files-problem/
要将hdfs目录中的所有文件转换为单个序列文件,请执行以下操作:
这里filename是键,file content是值。