用户行为数据 GB TB … 越来越大
数据量越来越大 ==> 面对问题:如何高效的处理 ==> 优化
Hadoop生态系统 :对数据进行压缩处理使得提高我们的数据处理效率
如何选择和使用压缩 就是一个至关重要的问题 摆在我们面前
压缩工具:winrar、7-zip
压缩:
解压缩:
Mainly two general types:
从3个角度来看:输入、中间、输出
输入
如果输入文件是经过压缩的,那么数据压缩过后所占用的HDFS的空间就会少很多
通常情况下,也就意味着读取数据所耗费的时间也就比较少
但也有种情况下读取耗费的时间多(如果你的CPU跟不上,也是不行的)
MapReduce/Hive/Spark这些框架是可以读取压缩文件的,它们会自动进行解压
这些计算框架在读取文件之后,具备自动解压文件的功能
数据有没有压缩,分布式处理框架都是能自动识别的,并不需要去做额外的东西
涉及到一个问题:
中间
以MapReduce来看,Map过程之后是有输出的
如果在做shuffle之前,对数据使用压缩,必然是会减少磁盘空间,
而在shuffle过程因为体积减少,传输效率也是会提高的
建议:中间过程也是采用压缩
输出
对于输出也是同理的,如果对于输出的文件是作为历史文件的,更应该使用压缩,而且需要选用压缩比非常高的压缩方式
这样历史数据,占用空间肯定少了
总结:
对于上述三点,不管哪一步,都建议采用压缩,
前提:CPU(如果CPU都不够用,就别采用压缩了)
从上述的来看,压缩能带来的好处有:
但是压缩/解压缩的过程,CPU的利用率是很高的
在使用的时候,是针对集群的状况来做取舍的,如下图所示:
对于压缩的使用,是需要结合实际生产环境进行权衡的
Compression format | Tool | Algorithm | File extention |
---|---|---|---|
Gzip | gzip | DEFLATE | .gz |
Bzip2 | bzip2 | bzip2 | .bz2 |
LZO | lzop | LZO | .lzo |
Snappy | N/A | Snappy | .snappy |
测试环境:
8 core
i7 CPU
8GB memory
64 bit CentOS
1.4GB Wikipedia Corpus 2-gram text input(1.4G文本类型的数据)
压缩效果如下图所示:
Compression Ratio:BZIP2 > GZIP > LZO
压缩解压缩时间小姑如下图所示:
压缩比和压缩速度成反比(因为你的压缩比越高,那么你压缩过后的数据也就越少,这样压缩所需要耗费的时间也就越多)
比如:BZIP2压缩效果最好,但是压缩解压缩时间最慢
Compression Speed:LZO > GZIP > BZIP2
根据实际的业务场景来说:
如何选择压缩格式,是需要出于对时间/空间的权衡的,如下图所示:
对于Hadoop/Spark作业(Hadoop指生态,Hive也是一样):
这些作业通常情况下,有一个特点,IO密集型(因为数据读取对于磁盘IO、网络IO等各方面都是比较重的)
能否支持分割对于一个作业的运行效率有很大的影响
假设数据大小为1G ==> 如果不支持分割,只能由1个mapper去处理
不支持分割的话,不管你的速度多快,肯定也会拖慢整个作业的执行时间,进而影响作业执行效率
$> hadoop checknative
会出现一堆false ==> 会影响压缩的使用
建议:Hadoop编译native使得支持native + snappy
参考Blog:编译hadoop2.6.0-cdh5.7.0 native支持snappy & 编译中遇到的坑及解决办法
压缩格式是否支持分割需要知道,这样有助于生产上的选型:
Compression format | Tool | Algorithm | File extention | Splittable |
---|---|---|---|---|
Gzip | gzip | DEFLATE | .gz | No |
Bzip2 | bzip2 | bzip2 | .bz2 | Yes |
LZO | lzop | LZO | .lzo | Yes if indexed |
Snappy | N/A | Snappy | .snappy | No |
关于压缩格式是否支持分割的相关解读:
When considering how to compress data that will be processed by MapReduce,it is important to understand whether the compression format supports splitting;Splittability must be taken into account;
当我们考虑如何去压缩我们的数据的时候。这是很重要的,去理解压缩格式是否支持分割分割必须被考虑在内
If a compression method is splittable,every compressed input split can be extracted and processed independently.
如果一个压缩方法是可以分割的,那么每个被压缩的文件被split之后就能被抽取出来,然后进行独立的处理
Split1.rar --> Decompress --> Mapper
Split2.rar --> Decompress --> Mapper
Split3.rar --> Decompress --> Mapper
Split4.rar --> Decompress --> Mapper
举例:
1个文件1个G 和 4个文件1个G
这样对比,必然是后者处理起来速度要更快一些的
如果不支持分割,只能进行串行的处理;如果支持分割,就能进行并行的处理
关于压缩(是否支持分割)的例子:
Consifer an uncompressed file stored in HDFS whose size 1GB.With an
HDFS block size of 64MB,the file will be stored as 16 blocks, and a
MapReduce job using this file as input will create 16 input
splits,each processed independently as input to a separate map task.
没有压缩的1G文件,block默认为64MB,会产生16个block
MapReduce job会为其创建16个input splits,有16个map task去处理
If the file were an GZIP file,a single map will process the 16 HDFS
blocks,most of which will not be local to the map.Also,with fewer
maps,so many take longer to run.
如果使用GZIP压缩(不支持分割),就只会有一个map task去处理,那么速度会慢很多
压缩格式 | 类 |
---|---|
Zlib | org.apache.hadoop.io.compress.DefaultCodec |
Gzip | org.apache.hadoop.io.compress.GzipCodec |
Bzip2 | org.apache.hadoop.io.compress.BZip2Codec |
Lzo | com.hadoop.compression.lzo.LzoCodec |
Lzo | org.apache.hadoop.io.compress.Lz4Codec |
Snappy | org.apache.hadoop.io.compress.SnappyCodec |
Hadoop配置压缩:
core-site.xml:
io.compression.codecs
org.apache.hadoop.io.compress.GzipCodec,
org.apache.hadoop.io.compress.DefaultCodec,
org.apache.hadoop.io.compress.BZip2Codec
mapred-site.xml(只配了最终的输出,中间输出的自己去配):
mapreduce.output.fileoutputformat.compress
true
mapreduce.output.fileoutputformat.compress.codec
org.apache.hadoop.io.compress.BZip2Codec
注意: 该配置文件是reduce的 如果是map会是mapreduce.map.output
测试:
$>hadoop jar hadoop-mapreduce-examples-2.6.0-cdh5.7.0.jar wordcount
/ruozeinput.txt /wc_compression_output
查看结果:
创建表,并导入数据:
hive>create table page_view(
track_time string,
url string,
session_id string,
referer string,
ip string,
end_user_id string,
city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
hive>LOAD DATA LOCAL INPATH '/home/hadoop/data/page_views.dat' OVERWRITE INTO TABLE page_views;
查看HDFS上的数据:
$>hadoop fs -ls /user/hive/warehouse/page_views
$>hadoop fs -du -h /user/hive/warehouse/page_views
18.1M 18.1M
配置:
hive>set hive.exec.compress.output=true;
hive>set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.BZip2Codec;
创建表page_views_bzip2:
hive>create table page_views_bzip2
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
AS SELECT * FROM page_views;
查看HDFS上的数据:
$>hadoop fs -du -h /user/hive/warehouse/page_views_bzip2
3.6M 3.6M
配置:
hive>set hive.exec.compress.output=true;
hive>set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.GzipCodec;
创建表page_views_gzip:
hive>create table page_views_gzip
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
AS SELECT * FROM page_views;
查看HDFS上的数据:
$>hadoop fs -du -h /user/hive/warehouse/page_views_bzip2
5.3M 5.3M