Hadoop适用于少量的大文件场景,而不是大量的小文件场景(这里的小文件通常指文件大小显著小于HDFS Block Size的文件),其主要原因是因为FileInputFormat在为这些小文件生成切片的时候,会为每一个小文件生成一个切片,如果小文件数目众多,会导致大量的Map Task,每个Map Task仅仅处理很少量的数据(即一个小文件的全部数据),这种情况会带来很大的运行开销且耗时较长。
 
CombineFileInputFormat设计目的就是用来应对小文件的场景,FileInputFormat为每一个小文件生成一个切片,而CombineFileInputFormat会将许多小文件“打包”为一个切片,使得每一个Map Task可以处理更多的数据。更为关键的是CombineFileInputFormat在决定将哪些小文件的数据块“打包”为一个切片时会充分考虑数据本地性(节点本地性、机器本地性)的特性,因此不会在运行时间和网络带宽方面来很大的开销。
 
不光是小文件的场景,在处理大文件时CombineFileInputFormat也有优势,原因在于它会将同一节点上的多个数据块形成一个切片,对Data-Local Map Tasks可能带来一定的优化。
 
思路
 
CombineFileInputFormat有三个重要的属性:
 
 
maxSplitSize:切片大小最大值,可通过属性mapreduce.input.fileinputformat.split.maxsize或CombineFileInputFormat实例方法setMaxSplitSize()进行设置;
 
minSplitSizeNode:同一节点的数据块形成切片时,切片大小的最小值,可通过属性mapreduce.input.fileinputformat.split.minsize.per.node或CombineFileInputFormat实例方法setMinSplitSizeNode()进行设置;
 
minSplitSizeRack:同一机架的数据块形成切片时,切片大小的最小值,可通过属性mapreduce.input.fileinputformat.split.minsize.per.rack或CombineFileInputFormat实例方法setMinSplitSizeRack()进行设置;
 
 
CombineFileInputFormat有一个“过滤池”的概念,pools中保存着多个“过滤池”实例(实际就是MultiPathFilter实例,该实例由多个PathFilter实例构成),一个切片中的数据块只可能来自于同一个过滤池,但可以来自同一个过滤池中的不同文件。
 
注:“过滤池”的设计目的还不是很明白,欢迎大家交流,貌似Hive有相关的应用。
 
getSplits():
 
 
step 1
 
获取输入路径中的所有文件;
 
step 2
 
迭代为每个过滤池中的文件生成切片;
 
     step 2.1
     
     获取满足当前过滤池实例的所有文件myPaths;
 
     step 2.2
 
     为mypaths中的文件生成切片;
 
step 3
 
为不属于任何过滤池的文件生成切片。
 
无论是满足某过滤池实例条件的文件还是不属于任何过滤池的文件,可以笼统地理解为“一批文件”,getMoreSplits()就是为这一批文件生成切片的。
 
 
step 1
 
前面提到,CombineFileInputFormat在将小文件“打包”为一个切片的时候,会考虑数据本地性(节点本地性、数据本地性),而且一个切片涉及到多个小文件,因此此处定义了三个对应关系:
 
rackToBlocks:机架和数据块的对应关系;
blockToNodes:数据块和节点的对应关系;
nodeToBlocks:节点和数据块的对应关系。
 
此外还应注意到比较重要的两个类:
 
OneFileInfo:代表一个文件;
OneBlockInfo:代表一个文件中的数据块,注意这个地方的数据块是“逻辑”上的数据块,不能直接对应HDFS Block,后续会说原因。
 
step 2
 
迭代这“一批文件”,为每一个文件构建OneFileInfo对象(由OneFileInfo构造函数完成),OneFileInfo对象本身并没有多少实际作用,它的意义是在构建过程中维护了上述三个对应关系的信息。
 
其中有一段代码是为这个文件生成对应的OneBlockInfo对象(多个),如下:
 
 
可以看出,对于每一个数据块(由locations[i]表示)而言,构建OneBlockInfo的逻辑是一个循环的过程,根据maxSize(maxSplitSize)的值不同就有可以产生多个OneBlockInfo对象,这也是“逻辑块”的原因。
 
迭代完成之后,我们即可以认为数据块、节点、机架相互之间的对应关系已经建立完毕,接下来可以根据这些信息生成切片。
 
step 3 
 
切片的形成过程(createSplits())如下:
 
(1)不断迭代节点列表,逐个节点(数据块)形成切片(Local Split);对于每一个节点而言,遍历并累加这个节点上的数据块,
     a.如果maxSplitSize != 0且累加的数据块大小大于或等于maxSize,则将这些数据块形成一个切片,继续下一个节点(为了达到多个节点之间分布切片的目的);
     b.如果maxSplitSize == 0,则上述累加的数据块可能为该节点的全部数据块,也可能是节点在迭代过程中剩余的数据块,这些数据块根据条件的不同可能全部形成一个切片,或者全部留作后续处理;
 
(2)不断迭代机架列表,逐个机架(数据块)形成切片(Rack Split);对于每一个机架而言,处理流程与(1)类同,仅判断条件时策略不同;
     
(3)遍历并累加剩余数据块,如果maxSplitSize != 0且累积的数据块大小大于或等于maxSplitSize,则将这些数据块形成一个切片;
 
(4)剩余数据块形成一个切片。
 
该部分代码比较冗长,建议读者自行阅读,核心逻辑比较简单:优先将一个节点上的数据块形成切片(同时兼顾切片分布问题),次之将一个机架的数据块形成切片,最后将剩余数据块形成切片。

Hadoop CombineFileInputFormat实现原理及源码分析的更多相关文章

  1. Hadoop FileInputFormat实现原理及源码分析

    FileInputFormat(org.apache.hadoop.mapreduce.lib.input.FileInputFormat)是专门针对文件类型的数据源而设计的,也是一个抽象类,它提供两 ...

  2. OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波

    http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 201 ...

  3. ConcurrentHashMap实现原理及源码分析

    ConcurrentHashMap实现原理 ConcurrentHashMap源码分析 总结 ConcurrentHashMap是Java并发包中提供的一个线程安全且高效的HashMap实现(若对Ha ...

  4. HashMap和ConcurrentHashMap实现原理及源码分析

    HashMap实现原理及源码分析 哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表, ...

  5. (转)ReentrantLock实现原理及源码分析

    背景:ReetrantLock底层是基于AQS实现的(CAS+CHL),有公平和非公平两种区别. 这种底层机制,很有必要通过跟踪源码来进行分析. 参考 ReentrantLock实现原理及源码分析 源 ...

  6. 【转】HashMap实现原理及源码分析

    哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景极其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,而HashMap的实现原理也常常出 ...

  7. 【OpenCV】SIFT原理与源码分析:DoG尺度空间构造

    原文地址:http://blog.csdn.net/xiaowei_cqu/article/details/8067881 尺度空间理论   自然界中的物体随着观测尺度不同有不同的表现形态.例如我们形 ...

  8. 《深入探索Netty原理及源码分析》文集小结

    <深入探索Netty原理及源码分析>文集小结 https://www.jianshu.com/p/239a196152de

  9. HashMap实现原理及源码分析之JDK8

    继续上回HashMap的学习 HashMap实现原理及源码分析之JDK7 转载 Java8源码-HashMap  基于JDK8的HashMap源码解析  [jdk1.8]HashMap源码分析 一.H ...

随机推荐

  1. java 获取黑屏信息保存在list中,截取字符执行

    ArrayList<String> list1 = new ArrayList<String>(); Process p = Runtime.getRuntime().exec ...

  2. [PWA] 0. Introduce to Offline First

    Why offline first? Imagin you are visiting a website, it is fine if wifi connection is good. It migh ...

  3. [CSS3] CSS :target Selector

    The :target selector allows us to interact with a fragment identifier, or hash, in our URL from CSS. ...

  4. android下大文件分割上传

    由于android自身的原因,对大文件(如影视频文件)的操作很容易造成OOM,即:Dalvik堆内存溢出,利用文件分割将大文件分割为小文件可以解决问题. 文件分割后分多次请求服务. //文件分割上传 ...

  5. Swift: Initialization-2

    Failable Initializers 有的时候,可能是参数问题.需要的外部资源没有到位等原因,初始化可能失败.为了应对这种情况,我们可以定义一个或多个可失败的构造方法. init? A fail ...

  6. Spring.Net+NHibernate+asp.net mvc + easyui

    毕业4个月的入手项目..前段时间在公司一直做的维护..为了弄明白自己也就跟着写了一个,目前也正在学习:不对的或者是有更好的还请各位赐教. 在学习的过程中主要参考::http://www.cnblogs ...

  7. centos5.2 x86 安装 oracle 11g2r 日志

    一.安装centos 二.安装ora所需的库 三.修改centos内核 四.建用户组和目录结构等 五.安装ora11g2r 六.安装sqlplus的翻页程序和help补丁 七.自启动脚本 八.常用命令 ...

  8. expdp 备份数据库

    操作系统层面创建目录 [root@Oracle10g ~]# mkdir -p /home/oracle/db_back/ 2. 修改目录的所属用户.所属组 [root@Oracle10g ~]# c ...

  9. 使用下拉列表框<select>标签,节省空间

    下拉列表在网页中也常会用到,它可以有效的节省网页空间.既可以单选.又可以多选.如下代码: 讲解: 1.value: 2.selected="selected": 设置selecte ...

  10. SQL window身份登陆 SQL server不能登陆

    用window方式登陆然后,在SQL Server Management Studio 中新建查询,执行下面代码一. ALTER LOGIN sa ENABLE GO ALTER LOGIN sa W ...