将本地文件读成sequenceFile文件,处理海量小文件的一种方式

个人观点:当处理海量小文件时,先将小文件进行sequenceFile操作或者类似操作处理,然后再上传到HDFS系统进行下一步的处理。(如有其它建议,欢迎留言)

 

一、直接上传本地栅格数据将导致的问题

                根据栅格数据的特点,每层的图片个数都为上层数量的四倍。在第20层时,仅仅第20层的图片的数量达到了“2199023255552”张(世界地图在第一层被切成了两张图片,第二十层的数量为:4**7*2),且每张图片的大小都为10-20kb不等。HDFS在存储文件时,会将文件break them into chunks,默认inputSplit的大小与block块的大小一致,为128M,如果单个文件的大小小于block块的大小则不会切分,直接将改小文件存储到一个block块中。因此如果不对栅格数据文件做处理,将导致占据大量的block块;由于namenode中会存储为元数据信息,因此也将导致namenode节点记录大量小文件的位置等元数据信息而产生压力过大,甚至namenode节点的内存可能会被占满。

二、在本地将栅格数据处理成sequenceFile文件

                SequenceFile文件是Hadoop用来存储二进制形式的key-value对而设计的一种平面文件。通常对小文件的处理是使用sequenceFile文件或MapFile文件。此次选用的处理方式是使用SequenceFile文件。(MapFile文件由两部分组成,dataindexindex作为文件的索引,存储每个Recordkey值以及它的偏移量。mapFile文件的检索效率较sequenceFile文件高,但是访问mapFile文件时需要先将索引文件加载到内存)

由于sequenceFile文件由Keyvalue组成,此处的key值存放的为文件的路径,例如:file:/home/greatmap/World/6/109/48.jpegvalue的值存放的为图片的字节数组文件。栅格数据存放在的文件夹下,通过遍历文件夹,将所有的图片都写成一个sequenceFile文件。

 

 

下面是具体实现过程:

 

[java]  view plain  copy
  1. public class SequenceFileTest {  
  2.    
  3.    
  4.  //本地linux磁盘输出路径  
  5.  static String PATH = "/home/greatmap/out";  
  6.  static SequenceFile.Writer writer = null;  
  7.    
  8.  public static void main(String[] args) throws Exception{  
  9.   
  10. //设置读取本地磁盘文件  
  11.   Configuration conf = new Configuration();  
  12.   conf.set("fs.default.name""file:///");  
  13.   conf.set("mapred.job.tracker""local");  
  14.   
  15.    
  16.   
  17. //linux磁盘下路径  
  18.   String path = "/home/greatmap/World/";  
  19.   URI uri = new URI(path);  
  20.   FileSystem fileSystem = FileSystem.get(uri, conf);  
  21.   //实例化writer对象  
  22.   writer = SequenceFile.createWriter(fileSystem, conf, new Path(PATH), Text.class, BytesWritable.class);  
  23.     
  24.   //递归遍历文件夹,并将文件下的文件写入sequenceFile文件  
  25.   listFileAndWriteToSequenceFile(fileSystem,path);  
  26.     
  27.   //关闭流  
  28.   org.apache.hadoop.io.IOUtils.closeStream(writer);  
  29.   
  30. }  
  31.   
  32.    
  33.   
  34. /**** 
  35.   * 递归文件;并将文件写成SequenceFile文件 
  36.   * @param fileSystem 
  37.   * @param path 
  38.   * @throws Exception 
  39.   */  
  40.  public static void listFileAndWriteToSequenceFile(FileSystem fileSystem,String path) throws Exception{  
  41.   final FileStatus[] listStatuses = fileSystem.listStatus(new Path(path));  
  42.   for (FileStatus fileStatus : listStatuses) {  
  43.    if(fileStatus.isFile()){  
  44.     Text fileText = new Text(fileStatus.getPath().toString());  
  45.     System.out.println(fileText.toString());  
  46.     //返回一个SequenceFile.Writer实例 需要数据流和path对象 将数据写入了path对象  
  47.     FSDataInputStream in = fileSystem.open(new Path(fileText.toString()));  
  48.     byte[] buffer = IOUtils.toByteArray(in);  
  49.     in.read(buffer);  
  50.     BytesWritable value = new BytesWritable(buffer);  
  51.       
  52.     //写成SequenceFile文件  
  53.     writer.append(fileText, value);  
  54.       
  55.    }  
  56.    if(fileStatus.isDirectory()){  
  57.     listFileAndWriteToSequenceFile(fileSystem,fileStatus.getPath().toString());  
  58.    }  
  59. //   org.apache.hadoop.io.IOUtils.closeStream(writer);  
  60.      
  61.   }  
  62.  }}  


 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值