hdfs小文件的解决方案

小文件的解决方案——应用程序自己控制

package small;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.commons.io.IOUtils;

public class Mes {

	public static void main(String[] args) throws Exception {
		FileSystem fs = FileSystem.newInstance(new URI(
				"hdfs://192.168.1.182:9000"), new Configuration());
		Path path = new Path("/me4");
		FSDataOutputStream out = fs.create(path);
		File dir = new File("E:\\test");
		for (File file : dir.listFiles()) {
			System.out.println(file);
			BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
			long len = file.length();
			byte[] buffer=new byte[(int)len];
			while ((len = in.read(buffer))!=-1){
				out.write(buffer);
			}
			in.close();
		}
		out.close();

	}

}

数据读写部分可改为

          for(File fileName : dir.listFiles()) {
               System.out.println(fileName.getAbsolutePath());
               final FileInputStream in= new FileInputStream(fileName.getAbsolutePath());
               final List<String> readLines = IOUtils.readLines(fileInputStream);
               //注意此IOUtils为org.apache.commons.io.IOUtils
               //org.apache.hadoop.io.IOUtils下的为readFully
               for (String line : readLines) {
                    out.write(line.getBytes());     
               }
               in.close();
          }
          out.close();


 

小文件的解决方案——SequenceFile

package small;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
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.SequenceFile;
import org.apache.hadoop.io.Text;

public class Seq {

	public static void main(String[] args) throws Exception{
		FileSystem fs = FileSystem.newInstance(new URI(
				"hdfs://192.168.1.182:9000"), new Configuration());
		Path seqPath = new Path("/seq3.seq");
		
		SequenceFile.Writer writer = SequenceFile.createWriter(fs, new Configuration(), seqPath, Text.class, Text.class);
		File dir = new File("E:\\test");
		
		Text key = new Text();
		Text value =new Text();
		InputStream in = null;  
	    byte[] buffer = null;
		for (File file : dir.listFiles()) {
			System.out.println(file);
			key.set(file.getName());
			in = new BufferedInputStream(new FileInputStream(file)); 
			long len = file.length();
			buffer=new byte[(int)len];
			IOUtils.readFully(in, buffer, 0, buffer.length); 
			value.set(buffer);
			writer.append(key, value);
			
		}
		in.close();
		IOUtils.closeStream(writer);
		
		SequenceFile.Reader reader=new SequenceFile.Reader(fs,seqPath,new Configuration());
		Text key2=new Text();
		Text value2=new Text();
		while(reader.next(key2,value2)){
		     System.out.println(key2);
		     System.out.println(value2);
		}
		IOUtils.closeStream(reader);
	}
}
	

MapFile

Configuration conf=new Configuration();
FileSystem fs=FileSystem.get(conf);
Path mapFile=new Path("mapFile.map");

//Writer内部类用于文件的写操作,假设Key和Value都为Text类型
MapFile.Writer writer=new MapFile.Writer(conf,fs,mapFile.toString(),Text.class,Text.class);

//通过writer向文档中写入记录
writer.append(new Text("key"),new Text("value"));
IOUtils.closeStream(writer);//关闭write流

//Reader内部类用于文件的读取操作
MapFile.Reader reader=new MapFile.Reader(fs,mapFile.toString(),conf);

//通过reader从文档中读取记录
Text key=new Text();
Text value=new Text();
while(reader.next(key,value)){
     System.out.println(key);
     System.out.println(key);
}
IOUtils.closeStream(reader);//关闭read流

Hadoop Archives
Hadoop Archives (HAR files)是在0.18.0版本中引入的,它的出现就是为了缓解大量小文件消耗namenode内存的问题。HAR文件是通过在HDFS上构建一个层次化的文件系统来工作。一个HAR文件是通过hadoop的archive命令来创建,而这个命令实 际上也是运行了一个MapReduce任务来将小文件打包成HAR。对于client端来说,使用HAR文件没有任何影响。所有的原始文件都 (using har://URL)。但在HDFS端它内部的文件数减少了。

通过HAR来读取一个文件并不会比直接从HDFS中读取文件高效,而且实际上可能还会稍微低效一点,因为对每一个HAR文件的访问都需要完成两层 index文件的读取和文件本身数据的读取。并且尽管HAR文件可以被用来作为MapReduce job的input,但是并没有特殊的方法来使maps将HAR文件中打包的文件当作一个HDFS文件处理。

创建文件 hadoop archive -archiveName xxx.har -p  /src  /dest
查看内容 hadoop fs -lsr har:///dest/xxx.har


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值