[转]Hadoop切分纯文本时对某一行跨两个分片这种情况的处理
来源:互联网 发布:linux杀java进程 编辑:程序博客网 时间:2024/05/18 07:06
Hadoop切分纯文本时对某一行跨两个分片这种情况的处理
作者: zsxwing 更新: 2012-09-06 22:42:51 发布: 2012-09-06 22:42:51
原文地址:http://blog.iamzsx.me/show.html?id=172007
当我们提交一个MapReduce程序来处理一个或多个纯文本时,Hadoop会根据设置的分片(split)大小把文件切分成多个(InputSplit),然后分配给MapReduce程序处理。而由于Hadoop对文件做切分的时候,只考虑分片大小,而不管切分的时候会不会把某一行分成两半(事实上,一个分片的结尾正好是一个换行符的概率很低)。那么,在MapReduce程序处理每一行文本的时候,我们会不会得到一个不完整的行?
事实上,Hadoop对这种某一行跨两个分片的情况进行了特殊的处理。
通常Hadoop使用的InputSplit是FileSplit,一个FileSplit主要存储了三个信息
<path, start, 分片length>
。假设根据设置分片大小为100,那么一个250字节大小的文件切分之后,我们会得到如下的FileSplit:
<path, 0, 100><path, 100, 100><path, 200, 50>
(具体的切分算法可以参考FileInputFormat的实现)
因此,事实上,每个MapReduce程序得到的只是类似
<path, 0, 100>
的信息。当MapReduce程序开始执行时,会根据path构建一个FSDataInputStream,定位到start,然后开始读取数据。在处理一个FileSplit的最后一行时,当读取到一个FileSplit的最后一个字符时,如果不是换行符,那么会继续读取下一个FileSplit的内容,直到读取到下一个FileSplit的第一个换行符。这样子就保证我们不会得到一个不完整的行了。
那么当MapReduce在处理下一个FileSplit的时候,怎么知道上一个FileSplit有没有已经处理了这个FileSplit的第一行内容?
我们只需要检查一下前一个FileSplit的最后一个字符是不是换行符,如果是,那么当前Split的第一行还没有被处理,如果不是,表示当前Split的第一行已经被处理,我们应该跳过。
在LineRecordReader中,使用了一个很巧妙的方法来实现上述的逻辑,把当前FileSplit的start减一,然后跳过第一行(下面是这个代码片断)。
99 }else{ 100 if(start!= 0) { 101 skipFirstLine =true; 102 --start; 103 fileIn.seek(start); 104 } 105 in=newLineReader(fileIn, job, recordDelimiter); 106 } 107 if(skipFirstLine) {// skip first line and re-establish "start". 108 start+=in.readLine(newText(), 0, 109 (int)Math.min((long)Integer.MAX_VALUE,end-start)); 110 }
这里注意,新版本的hadoop已经有所修改,不再用这种方式来保证读取完整的一行数据。最新的方法时:保证每个分片读取完成后的当前读取位置要处于下一分片中。对应的,除了第一个分片以外,每个分片都会在读取时跳过首行。这种改动简化了冗余的逻辑。下面是从hadoop2.6.0的源码中扒过来的更新后的代码。为了不改动转载文章,原文的旧代码依然放在了上面作为对比 ——by Harper
// We always read one extra line, which lies outside the upper180 // split limit i.e. (end - 1)181 while (getFilePosition() <= end || in.needAdditionalRecordAfterSplit()) {182 if (pos == 0) {183 newSize = skipUtfByteOrderMark();184 } else {185 newSize = in.readLine(value, maxLineLength, maxBytesToConsume(pos));186 pos += newSize;187 }
事实上,InputSplit只是一个逻辑上的概念,跟HDFS本身的block等机制无关,HDFS的好处是让我们可以假设MapReduce程序只是在处理一个本地的文件。
- [转]Hadoop切分纯文本时对某一行跨两个分片这种情况的处理
- Hadoop切分纯文本时对某一行跨两个分片这种情况的处理
- Hadoop切分纯文本时对某一行跨两个分片这种情况的处理
- 求 火狐对kindeditor 进行纯文本复制时,将其文本属性带入的问题
- VB中删除、替换或者插入内容到文本中某一行及解析文本行列的处理实例(转)
- 使用awk命令获取文本的某一行,某一列
- L3---fragment---ipsec: ipsec对3层分片的处理
- VB中删除、替换或者插入内容到文本中某一行,及文本行列的处理实例
- 【pandas】对矩阵的某一行、某一列进行求和
- mysql 插入数据时,出现"\xF0\x9F\x8F\x80"这种情况的处理!
- mysql 插入数据时,出现"\xF0\x9F\x8F\x80"这种情况的处理!
- 纯文本的威力
- shell中对文本的一些处理
- 第5.6节 按字母顺序对文本行组成的集合进行排序,引入指针处理问题,消除了因移动文本行本身所带来的复杂的存储管理和巨大的开销这两个孪生问题
- 查找替换RTF格式的文本时对锁定文本的处理问题
- RTF转纯文本
- 纯文本转超文本
- 数据库水平切分的两个思路
- JavaScript全文搜索之相关度评分
- Python 包管理工具解惑
- java程序打包所jar
- ant 问题解决
- 遍历map
- [转]Hadoop切分纯文本时对某一行跨两个分片这种情况的处理
- 对象序列化类库MsgPack介绍
- 微软100题(1) 二元查找树转变成排序的双向链表
- QtScript中脚本与C++代码的交互
- unity之NGUI之Anchors代码创建
- Linux v2.6内核编程之/sys/中的kobject
- 读取excel内容
- 对fmdb简单的封装
- 有效解决android sdk content loader 0%