一、上次回顾
- ETL是只有map没有reduce的,MapReduce开发的Java代码我们只需要把项目跑出来即可;处理完的结果是hdfs上的一个location,刷新分区信息,就能够查询得到。
二、压缩在Hadoop项目中的使用场景
Mapreduce --> ETL --> HDFS(普通的文本格式)
- 我们在HDFS上使用的是纯文本格式,数据未经任何压缩,在生产上肯定是不行的;假设生产上一天的数据量是500G,以三副本为例的话,1500G,会占用很多个block,这样是不行的;所以在ETL --> HDFS的时候可以把压缩(compression)加进去。
ETL --> Compression --> HDFS
- 以Windows进行举例,使用右键进行压缩,采用ZIP\RAR方式压缩,压缩方式还分为很多种(较快、很快、标准)
压缩带来的好处:
1、节省磁盘利用率
2、加快网络传输
带来的坏处:
1、多了一步操作压缩和解压,对于压缩、解压是需要耗费CPU的
假设大桥.mp4,1.5G,对文件进行压缩后是0.8G;现在需要把它拷贝到移动硬盘,肯定是0.8G的文件传输起来较快.
压缩不仅仅减少磁盘的空间,还能加速网络的传输,结合MapReduce的流程,压缩往往发生在Shuffle阶段,Shuffle过程会分到一个Reduce中去。
总结:在大数据中任何一种调优方式都不是万能的,需要结合生产实际情况来看。在生产场景中:集群整体负载高的话,就不能使用压缩和解压;集群负载低的话可以开压缩。
压缩就是磁盘和CPU的一个取舍。
压缩使用场景
压缩场景:
1、input:Flume Sink HDFS <==> Spark/Mapreduce
2、output:Spark/Mapreduce ==> Sink Hadoop
3、temp:Sink DISK
2.1、常用压缩格式介绍
1、Windows上的压缩:
2、同样在Linux上也有压缩:
检查自己机器上的Hadoop是否支持压缩:下载Hadoop源码添加仓库一个命令执行到底就能okay?
[hadoop@sz5i5j-01 hadoop]$ bin/hadoop checknative
20/05/11 12:46:53 INFO bzip2.Bzip2Factory: Successfully loaded & initialized native-bzip2 library system-native
20/05/11 12:46:53 INFO zlib.ZlibFactory: Successfully loaded & initialized native-zlib library
Native library checking:
hadoop: true /home/hadoop/app/hadoop-2.6.0-cdh5.7.0/lib/native/libhadoop.so.1.0.0
zlib: true /lib64/libz.so.1
snappy: true /lib64/libsnappy.so.1
lz4: true revision:99
bzip2: true /lib64/libbz2.so.1
openssl: true /lib64/libcrypto.so
面试必问必考:
1、常用压缩格式对比:
No Compress | Snappy | LZ4 | LZO | GZIP | BZIP2 |
---|---|---|---|---|---|
1403M | 701M | 693M | 684M | 447M | 390M |
2、常用压缩速度对比:
Time | BZIP2 | GZIP | LZO | LZ4 | Snappy |
---|---|---|---|---|---|
压缩时间 | 142 | 85 | 7.6 | 6.45 | 6.41 |
解压时间 | 62 | 21 | 11.1 | 2.36 | 19.84 |
总结:压缩速度压缩比肯定是成反比的,一般选择压缩速度与压缩时间相近的进行选择;LZO、LZ4、Snappy如上是都可以进行选择的。
压缩在Hadoop中的应用 - 常用Codec
压缩格式 | 配置参数 |
---|---|
zlib | org.apache.hadoop.io.compress.DefaultCodec |
gzip2 | org.apache.hadoop.io.compress.GzipCodec |
bzip2 | org.apache.hadoop.io.compress.BZip2Codec |
lzo | org.apache.hadoop.io.lzo.LzoCodec |
lz4 | org.apache.hadoop.io.compress.Lz4Codec |
snappy | org.apache.hadoop.io.compress.SnappyCodec |
注意事项:
压缩比VS压缩速度
是否分片
-
在MapReduce中,如果一个块大小是128M的话,文本输入是200M的话,就会出现2个分片,启动2个map task,支持分片意味着可以并行着跑的;不支持分片意味着只能串行跑会很慢。
-
Bzip2是支持分片的,LZO默认是不支持分片,但可以通过创建索引的方式来支持分片;Flume --> HDFS可以采用Bzip2的方式,
- 如上图,ETL的原始数据在HDFS上,如果要压缩需要采用支持分片的(文本默认支持分片),Map完之后,把数据spill到磁盘,reduce的数据输出。
打死都要掌握的:
第一个阶段:我们要选择可分片的(splitable);
第二个阶段:选择速度快的压缩;
第三个阶段:分场景:数据作为归档用,采用高压缩比;如果这个作业的输出作为下一个作业的输入一定要考虑分片,不然就只有一个task来处理了。
2.2、压缩的配置使用&&运行Wordcount案例
1、编辑core-site.xml
1、这个property中需要配置很多个压缩,Gzip\BZip2,然后以逗号为分割
<property>
<name>io.compression.codecs</name>
<value>org.apache.hadoop.io.compress.GzipCodec,
org.apache.hadoop.io.compress.DefaultCodec,
org.apache.hadoop.io.compress.BZip2Codec,</value>
</property>
2、编辑mared-site.xml
1、mapreduce的输出不压缩,我们配置了true就是支持压缩:
<property>
<name>mapreduce.output.fileoutputformat.compress</name>
<value>true</value>
</property>
2、mapreduce的output支持BZip2压缩:
<property>
<name>mapreduce.output.fileoutputformat.compress.codec</name>
<value>org.apache.hadoop.io.compress.BZip2Codec</value>
</property>
配置完后做一个wordcount的案例:
1、hdfs上创建一个数据存放目录:
hdfs dfs -mkdir -p /wordcount/input
2、linux本地编辑一份数据上传到hdfs:
hdfs dfs -put /home/hadoop/data/ruozeinput.txt /wordcount/input
3、wordcount跑一个mapreduce:
hadoop jar hadoop-mapreduce-examples-2.6.0-cdh5.7.0.jar wordcount /wordcount/input/ruozeinput.txt /wordcount/output1
4、测试数据读取是否有问题:
[hadoop@sz5i5j-01 hadoop]$ hdfs dfs -text /wordcount/output1/part-r-00000.bz2
20/05/11 13:52:22 INFO bzip2.Bzip2Factory: Successfully loaded & initialized native-bzip2 library system-native
20/05/11 13:52:22 INFO compress.CodecPool: Got brand-new decompressor [.bz2]
hello 2
john 3
world 1
跑完的数据是以BZIP2结尾的,说明我们配置的是成功的;压不压缩对于用户来说是无感知的
三、压缩在Hive中的使用
- 写在前面,压缩在Hive中怎么使用在Spark中就怎么使用
1、创建Hive表
create table page_views(tarck_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';
2、从本地准备好一个10m左右的数据加载至Hive做测试:
load data local inpath '/home/hadoop/data/page_views.dat' overwrite into table page_views;
3、由于我们在工作中会使用到非常多的Codec,我们可以进行设置:
//查看Hive是否支持压缩,默认是关的
hive (hive)> set hive.exec.compress.output;
hive.exec.compress.output=false
//把默认是关的压缩打开
hive (hive)> set hive.exec.compress.output=true;
hive (hive)> set mapreduce.output.fileoutputformat.compress;
mapreduce.output.fileoutputformat.compress=true
//查看到已经是bzip2压缩了
hive (hive)> set mapreduce.output.fileoutputformat.compress.codec;
mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.BZip2Codec
4、创建Bizp2的压缩表:
create table page_views_bzip2 as select * from page_views;
select * from page_views_bzip2;
- 去到sz5i5j-01:50070中验证如上是否采用压缩,压缩后的大小是多少?注意我在Dbeaver中使用如上命令并没有触发压缩机制
1、原始数据大小:18.13M
2、压缩后的数据大小:3.64M,压缩比是20%
小结:压缩只是在生产上的一个场景
3.1、file format(行式存储VS列式存储)和compression
在hive创建表的时候还有一个:Stored as file_format
File_format包含哪些东西呢,默认的是textfile;
有如下这些形式:
file_format:
: SEQUENCEFILE
| TEXTFILE -- (Default, depending on hive.default.fileformat configuration) //默认
| RCFILE -- (Note: Available in Hive 0.6.0 and later)
| ORC -- (Note: Available in Hive 0.11.0 and later)
| PARQUET -- (Note: Available in Hive 0.13.0 and later)
执行这个参数作验证:
hive (g6_hadoop)> set hive.default.fileformat;
hive.default.fileformat=TextFile
行式存储:
A | B | C | D |
---|---|---|---|
101 | 111 | 121 | 131 |
102 | 112 | 122 | 132 |
103 | 113 | 123 | 133 |
-
行式存储的优点:select * 的时候数据一下子全部出来了,缺点是比如我们只要两列:select a,c from 它也会把所有的数据加载出来;
-
列式存储的优点:select a,c 的时候没什么问题;一旦使用select * 的时候会发生数据的重组
在大数据工作中,99%的情况都是采用列式存储的,主要采用orc和parquet的存储格式,
SequeceFile
1、创建表:
create table page_views_seq(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' stored as sequencefile;
2、导入数据到这个表,出现报错:
hive (hive)> load data local inpath '/home/hadoop/data/page_views.dat' into table page_views_seq;
Loading data to table hive.page_views_seq
Failed with exception Wrong file format. Please check the file's format.
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.MoveTask
//提示要导入的文件格式不一致,目标表是sequencefile格式,我们的源数据是textfile格式:
insert into table page_views_seq select * from page_views;
查看Sequence file后的文件大小:使用sequence file存的东西明显要比textfile存的数据多:
RCFILE
是一个行列混合的存储,性能很低.
还是接上面的表,四列A、B、C、D;存到组里,把一列变为一行存储到一起了
RCFILE测试出来9.8M:
[hadoop@hadoop hive-1.1.0-cdh5.7.0]$ hdfs dfs -du -s -h /user/hive/warehouse/g6_hadoop.db/page_views_rcfile
9.8 M 9.8 M /user/hive/warehouse/g6_hadoop.db/page_views_rcfile
RCFILE对于查询来讲没有区别,仅仅是存储上节省了约10%的空间。
ORC FILE(重点)
- 几步走,同样的是创建表,导入数据:
create table page_views_orc(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' stored as orc;
insert overwrite table page_views_orc select * from page_views;
- orc压缩后的大小
ORC底层使用的是ZLIB压缩:
1、创建不压缩的表:
create table page_views_orc_null(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' stored as orc tblproperties("orc.compress"="NONE");
2、插入数据:
insert into page_views_orc_null select * from page_views;
建表的时候采用ORC格式,并且ORC底层默认是Zlib压缩,从18M压缩成了3.6M,即使把ORC底层的ZLib压缩关闭后,也能压缩成7.7M。
parquet(重点)
1、设置压缩格式为gzip
set parquet.compression=gzip;
2、设置压缩格式:
hive (g6_hadoop)> set parquet.compression=gzip;
hive (g6_hadoop)> set parquet.compression;
parquet.compression=gzip
3、创建表
create table page_views_parquet_gzip stored as parquet as select * from page_views;
- 他们各自使用压缩+自己的一个存储格式,可以使得磁盘节省非常非常多,这就是parquet的一个用法,到目前为止都是从存储角度来讲的;那从查询的角度去看呢;
测试查询性能:
1、查询page_views中的session_id,这个表是textfile:
hive (hive)> select * from page_views where session_id = "M6MPYNVRZQ8EDKVP8E97TPKXENNS77KR";
MapReduce Jobs Launched:
Stage-Stage-1: Map: 1 Reduce: 1 Cumulative CPU: 4.89 sec HDFS Read: 19022707 HDFS Write: 39 SUCCESS
Total MapReduce CPU Time Spent: 4 seconds 890 msec
2、查询bzip压缩中的数据:
hive (hive)> select count(*) from page_views_bzip2 where session_id = "M6MPYNVRZQ8EDKVP8E97TPKXENNS77KR";
MapReduce Jobs Launched:
Stage-Stage-1: Map: 2 Reduce: 1 Cumulative CPU: 11.17 sec HDFS Read: 4108798 HDFS Write: 39 SUCCESS
Total MapReduce CPU Time Spent: 11 seconds 170 msec
3、查询orc中数据:
hive (hive)> select count(*) from page_views_orc where session_id = "M6MPYNVRZQ8EDKVP8E97TPKXENNS77KR";
MapReduce Jobs Launched:
Stage-Stage-1: Map: 1 Reduce: 1 Cumulative CPU: 4.58 sec HDFS Read: 1257493 HDFS Write: 39 SUCCESS
Total MapReduce CPU Time Spent: 4 seconds 580 msec
OK
- 所以在生产上,不仅仅要考虑的是压缩比,还要考虑到的是数据的查询性能,如上所示,我们的HDFS READ在一步步的慢慢减少了。