Hadoop Lzo 源码分析之分片/切片原理

首先说明你一点Lzo本身是不具备压缩分割的功能的;

lzo压缩已经广泛用于Hadoop中,至于为什么要在Hadoop中使用Lzo.这里不再重述.其中很重要的一点就是由于分布式计算,所以需要支持对压缩数据进行分片,也就是Hadoop的InputSplit,这样才能分配给多台机器并行处理.所以这里花了一天的时间,看了下Hadoop lzo的源码,了解下Hadoop lzo是如何做到的.

其实一直有种误解,就是以为lzo本身是支持分布式的,也就是支持压缩后的数据可以分片(对于这种误解的产生可以看最后边的注释).我们提供给它分片的逻辑,由lzo本身控制.但看了Hadoop lzo源码才发现,lzo只是个压缩和解压缩的工具,如何分片,是由Hadoop lzo(Javad代码里)控制.具体的分片算法写得也很简单,就是在内存中开一块大大的缓存,默认是256K,缓存可以在通过io.compression.codec.lzo.buffersize参数指定.数据读入缓存(实际上要更小一些),如果缓存满了,则交给lzo压缩,获取压缩后的数据,同时在lzo文件中写入压缩前后的大小以及压缩后的数据.所以这里,一个分片,其实就是<=缓存大小。

总结起来就是Hadoop在读入一个大文件的时候,会为每个文件维护一个索引文件,之后将文件按照一分一分的读入缓存,每当缓存读满,就将这一份进行lzo压缩,并在索引文件中维护相关的信息——一个缓存写完后便会将写入的数据长度写到索引文件中.如此在Hadoop分布式时只要根据索引文件的各个长度,读取该长度的数据 ,便可交给map处理.

 

误解产生注释:就拿我们公司目前使用的框架来说,因为在需要被分析的用户行为日志是通过flume读取kafka中的消息数据,之后存入hdfs中,但是在这个读取过程中,flume设置了读取到某个最大数据量值A的时候,进行hdfs写入生成一个文件,并配置了文件压缩方式为lzo,A的值一般我们会设置为跟一个block值得大小相同(因为压缩后的文件会比A小很多,所以A值要设置的略大一些,先不考虑这些),这样每个lzo文件的大小就不会超过一个block,然后我们再放入maptask中的分片一般也是默认值一个block的值,所以给人的感觉就是存到hdfs上的lzo文件支持了分布式运算,但是如果我们存储的文件是X倍单个block大小的一个lzo文件,他还是会存往一个块内,然后再分片时只会被看作一个分片处理(这就会在某些情况下诱发一些问题),其实大多数情况下这样做确实已经够用了;但是在及特殊情况下如果不使用真的lzo自动分片(建立lzo.index索引文件),可能会出现一些问题,比如一个lzo的文件过大导致再给与一个maptask处理的时候过于漫长违背了分布式的初衷,另外如果文件再大些可能会导致内存泄漏的问题;

 

如何为lzo文件建立索引以及如何使用带索引的lzo文件可以参考:https://blog.csdn.net/liweihope/article/details/89735109

你可能感兴趣的:(Hadoop Lzo 源码分析之分片/切片原理)