Hadoop切分纯文本时对某一行跨两个分片这种情况的处理

网友投稿 299 2022-11-24

Hadoop切分纯文本时对某一行跨两个分片这种情况的处理

hdfs写入文件需要把大文件分割成多个块,那么有可能会把文件的某一个行分成在不同的块中;这是一个出现分块的时候。还有个就是我的上篇博文中说到的,在mapreduce处理时,当hdfs分块的block大小大于split设置的最大值时也会分割成多个split分片,相当于对块的进一步切割。但是这两种情况出现的概率都很小。 当我们提交一个MapReduce程序来处理一个或多个纯文本时,Hadoop会根据设置的分片(split)大小把文件切分成多个(InputSplit),然后分配给MapReduce程序处理。而由于Hadoop对文件做切分的时候,只考虑分片大小,而不管切分的时候会不会把某一行分成两半(事实上,一个分片的结尾正好是一个换行符的概率很低)。那么,在MapReduce程序处理每一行文本的时候,我们会不会得到一个不完整的行? 事实上,Hadoop对这种某一行跨两个分片的情况进行了特殊的处理。 通常Hadoop使用的InputSplit是FileSplit,一个FileSplit主要存储了三个信息。假设根据设置分片大小为100,那么一个250字节大小的文件切分之后,我们会得到如下的FileSplit: (具体的切分算法可以参考FileInputFormat的实现) 因此,事实上,每个MapReduce程序得到的只是类似的信息。当MapReduce程序开始执行时,会根据path构建一个FSDataInputStream,定位到start,然后开始读取数据。在处理一个FileSplit的最后一行时,当读取到一个FileSplit的最后一个字符时,如果不是换行符,那么会继续读取下一个FileSplit的内容,直到读取到下一个FileSplit的第一个换行符。这样子就保证我们不会得到一个不完整的行了。 那么当MapReduce在处理下一个FileSplit的时候,怎么知道上一个FileSplit有没有已经处理了这个FileSplit的第一行内容? 我们只需要检查一下前一个FileSplit的最后一个字符是不是换行符,如果是,那么当前Split的第一行还没有被处理,如果不是,表示当前Split的第一行已经被处理,我们应该跳过。 在LineRecordReader中,使用了一个很巧妙的方法来实现上述的逻辑,把当前FileSplit的start减一,然后跳过第一行(下面是这个代码片断)。 }else{ if(start!= 0) { skipFirstLine =true; --start; fileIn.seek(start); } in=newLineReader(fileIn, job, recordDelimiter); } if(skipFirstLine) {// skip first line and re-establish "start". start+=in.readLine(newText(), 0, (int)Math.min((long)Integer.MAX_VALUE,end-start)); } 事实上,InputSplit只是一个逻辑上的概念,跟HDFS本身的block等机制无关,HDFS的好处是让我们可以假设MapReduce程序只是在处理一个本地的文件。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【转载】Hadoop产品介绍
下一篇:如何看待波卡和以太坊的区别
相关文章

 发表评论

暂时没有评论,来抢沙发吧~