小文件与CombineFileInputFormat

1GB的文件分割成16个64M与 100KB的10000个快

10000每个文件都需要使用一个map操作,作业时间比一个文件上的16个map操作慢几十甚至几百倍。


CombineFileInputFomat可以缓冲这个问题,他是针对小文件而设计的, FileInputFormat为每个文件产生一个分片,而CombineFileInputFormat把多个文件 打包到一个分片中 以便每个mapper可以处理更多的数据, 关键是,决定那些块放入同一个分片时, CombineFileInputFormat会考虑到节点和机架的因素, 所以在典型的MR作业中处理输入的速度并不会下降。


当日,如果可能的化,应该尽量避免需许多的小文件的情况, 因为MR处理数据的最佳速度最好与数据在集群中的传速度相同,而处理小文件将增加作业运行而必须要的寻址次数,还有在HDFS集群中存储大量的小文件会浪费namenode的内存, 一个可以减少大量小文件的方法是使用SequenceFile将这些小文件 合并成一个大文件, 可以将文件名作为键 (如果不需要键,可以用NullWritable等常量代替,) 文件的内存作为值,参见范例7-4 但是如果HDFS中已经有大量的小文件了, CombineFileInputFormat方法值得一试。


由于CombineFileInputFormat 是一个抽象类, 没有提供实体类(不同于FileInputFormat)所以 使用的时候需要一些额外的工作,  例如如果要使用 CombineFileInputFormat 与 TextInputFormat相同,需要创建一个CombineFileInputFormat 的具体的子类, 并且实现 getRecordReader()方法。



你可能感兴趣的:(__MapReduce)