宝塔服务器面板,一键全能部署及管理,送你10850元礼包,点我领取

        大数据环境下,在HDFS文件系统中存储数据,对数据进行压缩是十分有必要的。压缩数据可以使集群能够存储更多数据,减少磁盘IO,加快任务处理速度。但是,在hadoop上使用压缩也有两个比较麻烦的地方:第一,有些压缩格式不能被分块,并行的处理,比如gzip。第二,另外的一些压缩格式虽然支持分块处理,但是解压缩的过程非常缓慢,使job的瓶颈转移到了cpu上,也更加耗时,比如bzip2。

gzip

        由于gzip压缩不支持分片处理,这就意味这gzip压缩文件在mapreduce中只能被一个mapper来单个的处理。也就意味着在hadoop上大的gzip压缩文件无法实现并行处理,这样处理显然不高效,违背了Mapreduce的分而治之的思想。

bzip2

        bzip2的压缩比非常高,并且支持分片,但其压缩和解压过程都非常的缓慢,这样也无法在hadoop中高效的使用这种压缩。即使使用,由于其解压缩的低效,会使得job的瓶颈也转移到cpu上去。

lzo

        如果有一种压缩算法,即能够被分块,并行的处理,解压缩速度也非常快,那就非常的理想。这种方式就是lzo。在hadoop中使用lzo压缩算法可以减小数据的大小和数据的磁盘读写时间,不仅如此,lzo是基于block分块的,这样他就允许数据被分解成chunk,并行的被hadoop处理。同时,解压缩速度至少是gzip的两倍以上。这样的特点,就可以让lzo在hadoop上成为一种非常好用的压缩格式。
        然而,lzo本身不是splitable的,所以当数据为text格式时,用lzo压缩出来的数据当做job的输入是一个文件作为一个map。但是sequencefile本身是分块的,所以sequencefile格式的文件,再配上lzo的压缩格式,就可实现lzo文件方式的splitable。
        比如一个1.1G的lzo压缩文件,那么处理第二个128MBblock的mapper就必须能够确认下一个block的boundary,以便进行解压操作。lzo并没有写什么数据头来做到这一点,而是实现了一个lzoindex文件,将这个文件(foo.lzo.index)写在每个foo.lzo文件中。这个index文件只是简单的包含了每个block在数据中的offset,这样由于offset已知的缘故,对数据的读写就变得非常的快。通常能达到90-100MB/秒,也就是10-12秒就能读完一个GB的文件。一旦该index文件被创建,任何基于lzo的压缩文件就能通过load该index文件而进行相应的分块,并且一个block接一个block的被读取。也因此,各个mapper都能够得到正确的block,这就是说,可以只需要进行一个LzopInputStream的封装,就可以在hadoop的mapreduce中并行高效的使用lzo。如果现在有一个job的InputFormat是TextInputFormat,那么就可以用lzop来压缩文件,确保它正确的创建了index,将TextInputFormat换成LzoTextInputFormat,然后job就能像以前一样正确的运行,并且更加的快。有时候,一个大的文件被lzo压缩过之后,甚至都不用分块就能被单个mapper高效的处理了

总结

浅谈Hadoop的压缩格式之LZO-编程部落
浅谈Hadoop的压缩格式之LZO-编程部落

  1. gzip:hadoop内置支持,压缩比高,不支持split。
    用途:通常用来放不常访问的冷数据,较高的压缩比可以极大的节省磁盘空间。
  2. bzip2:压缩比高,支持split,支持多文件,缺点就是慢。
    用途:适用于对处理速度要求不高的场景。一般不常用。
  3. lzo: 压缩比一般,支持split(需要建索引,文件修改后需要重新建索引),压缩/解压速度快,支持hadoop native库,需要自己安装。
    用途:适合于经常访问的热数据。
  4. snappy:压缩比一般,不支持split,压缩/解压速度快,支持hadoop native库,需要自己安装。
    用途:和lzo性能类似,但不支持split,可以用于map中间结果的压缩。

参考:https://blog.csdn.net/u010299467/article/details/50501974?utm_source=blogxgwz7