参考资料
1. HDFS中的常用压缩算法及区别_大数据_王知无_InfoQ写作社区
2. orc格式和parquet格式对比-阿里云开发者社区
3.Hadoop 压缩格式 gzip/snappy/lzo/bzip2 比较与总结 | 海牛部落 高品质的 大数据技术社区
4. Hive中的文件存储格式TEXTFILE、SEQUENCEFILE、RCFILE、ORCFILE、Parquet 和 AVRO使用与区别详解_text orc pquest sequentfile_皮哥四月红的博客-CSDN博客
5.Hadoop 压缩格式 gzip/snappy/lzo/bzip2 比较与总结 | 海牛部落 高品质的 大数据技术社区
本文主要介绍下HDFS上的常见文件格式和压缩格式
总结 :
HDFS 中常见的文件存储格式
- textfile :行式存储格式
- sequencefile :行式存储格式
- orc :列式存储格式, 支持ACID,常用的文件组织方式, 查询效率比parquet高
- parquet : 列式存储格式 不支持ACID
HDFS中常见的文件压缩方式
- gzip : 不支持split
- lzo : 支持split
- snappy : 不支持split, 数仓中最常用的压缩方式
- bzip2 : 支持split
行式存储和列式存储
TEXTFILE 、SEQUENCEFILE、RCFILE、ORC、PARQUET,AVRO。其中TEXTFILE 、SEQUENCEFILE、AVRO都是基于行式存储,其它三种是基于列式存储;所谓的存储格式就是在Hive建表的时候指定的将表中的数据按照什么样子的存储方式,如果指定了A方式,那么在向表中插入数据的时候,将会使用该方式向HDFS中添加相应的数据类型。
逻辑图
如上图所示,左边为逻辑表,右边第一个为行式存储,第二个为列式存储。
1.行存储的特点
查询满足条件的一整行数据的时候,列存储则需要去每个聚集的字段找到对应的每个列的值,行存储只需要找到其中一个值,其余的值都在相邻地方,所以此时行存储查询的速度更快。
2.列存储的特点
因为每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量;每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法。
=====================================================
文件格式
下面对常见的文件存储格式做一个详细的介绍,主要以最常用的sequenceFile 和 parquet 为主。
TextFile
文件存储就是正常的文本格式,将表中的数据在hdfs上 以文本的格式存储
,下载后可以直接查看,也可以使用cat命令查看
如何指定
1.无需指定,默认就是
2.显示指定stored as textfile
3.显示指定
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
优缺点
1.行存储使用textfile存储文件默认每一行就是一条记录,
2.可以使用任意的分隔符进行分割。
3.但无压缩,所以造成存储空间大。可结合Gzip、Bzip2、Snappy等使用(系统自动检查,执行查询时自动解压),但使用这种方式,hive不会对数据进行切分,从而无法对数据进行并行操作。
-------------------------------------------------------------------------------
SequenceFile
SequenceFile 文件是 Hadoop 用来存储二进制形式的[Key,Value]对而设计的一种平面文件(Flat File)。可以把 SequenceFile 当做是一个容器,把所有的文件打包到 SequenceFile 类中可以高效的对小文件进行存储和处理。SequenceFile 文件并不按照其存储的 Key 进行排序存储,SequenceFile 的内部类 Writer 提供了 append 功能。SequenceFile 中的 Key 和 Value 可以是任意类型 Writable 或者是自定义 Writable。
在存储结构上,SequenceFile 主要由一个 Header 后跟多条 Record 组成,Header 主要包含了 Key classname,value classname,存储压缩算法,用户自定义元数据等信息,此外,还包含了一些同步标识,用于快速定位到记录的边界。每条 Record 以键值对的方式进行存储,用来表示它的字符数组可以一次解析成:记录的长度、Key 的长度、Key 值和 value 值,并且 Value 值的结构取决于该记录是否被压缩。
SequenceFile 支持三种记录存储方式:
-
无压缩, io 效率较差. 相比压缩, 不压缩的情况下没有什么优势.
-
记录级压缩, 对每条记录都压缩. 这种压缩效率比较一般.
-
块级压缩, 这里的块不同于 hdfs 中的块的概念. 这种方式会将达到指定块大小的二进制数据压缩为一个块. 相对记录级压缩, 块级压缩拥有更高的压缩效率. 一般来说使用 SequenceFile 都会使用块级压缩.
如何指定
1.stored as sequecefile
2.或者显示指定:
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.SequenceFileInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat'
优缺点
1.sequencefile存储格有压缩,存储空间小,有利于优化磁盘和I/O性能
2.同时支持文件切割分片,提供了三种压缩方式:none,record,block(块级别压缩效率跟高).默认是record(记录)
3.基于行存储
-------------------------------------------------------------------------------
RCFile 不推荐,推荐进化的ORCFile
在hdfs上将表中的数据以二进制格式编码,并且支持压缩。下载后的数据不可以直接可视化。
如何指定
1.stored as rcfile
2.或者显示指定:
STORED AS INPUTFORMAT
'org.apache.hadoop.hive.ql.io.RCFileInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.RCFileOutputFormat'
优缺点
1.行列混合的存储格式,基于列存储。
2.因为基于列存储,列值重复多,所以压缩效率高。
3.磁盘存储空间小,io小。
-------------------------------------------------------------------------------
ORCFile
ORC File,全名是Optimized Row Columnar (ORC) file,其实就是对RCFile做了一些优化。据官方文档介绍,这种文件格式可以提供一种高效的方法来存储Hive数据。它的设计目标是来克服Hive其他格式的缺陷。运用ORC File可以提高Hive的读、写以及处理数据的性能。
ORC(optimizedRC File) 存储源自RC(RecordCloimnar File)这种存储格式,RC是一种列式存储引擎,对schema演化(修改schema需要重新生成数据)支持较差,主要是在压缩编码,查询性能方面做了优化.RC/ORC最初是在Hive中得到使用,最后发展势头不错,独立成一个单独的项目.Hive1.xbanbendu版本对事物和update操作的支持,便是给予ORC实现的(其他存储格式暂不支持).
如何指定
1.CREATE TABLE ... STORED AS ORC
2.ALTER TABLE ... [PARTITION partition_spec] SET FILEFORMAT ORC
3.SET hive.default.fileformat=Orc
优缺点
1.面向列的存储格式
2.由Hadoop中RC files 发展而来,比RC file更大的压缩比,和更快的查询速度
3.Schema 存储在footer中
4.不支持schema evolution
5.支持事务(ACID)
6.为hive而生,在许多non-hive MapReduce的大数据组件中不支持使用
7.高度压缩比并包含索引
其他
ORC 文件格式可以使用 HIVE 自带的命令 concatenate
快速合并小文件
-------------------------------------------------------------------------------
Parquet
Parquet文件是以二进制方式存储的,所以是不可以直接读取的,文件中包括该文件的数据和元数据,因此Parquet格式文件是自解析的。
Apache Parquet 最初的设计动机是存储嵌套式数据,比如Protocolbuffer thrift json 等 将这类数据存储成列式格式以方便对其高效压缩和编码,且使用更少的IO操作取出需要的数据,
如何指定
Hive 0.13 and later:STORED AS PARQUET;
Hive 0.10 - 0.12:
ROW FORMAT SERDE 'parquet.hive.serde.ParquetHiveSerDe'
STORED AS
INPUTFORMAT 'parquet.hive.DeprecatedParquetInputFormat'
OUTPUTFORMAT 'parquet.hive.DeprecatedParquetOutputFormat';
优缺点
1.与ORC类似,基于Google dremel
2.Schema 存储在footer
3.列式存储
4.高度压缩比并包含索引
5.相比ORC的局限性,parquet支持的大数据组件范围更广
Avro
Avro是一个数据序列化系统,设计用于支持大批量数据交换的应用。支持二进制序列化方式,可以便捷,快速地处理大量数据;动态语言友好,Avro提供的机制使动态语言可以方便地处理Avro数据。
如何指定
1.STORED AS AVRO
2.STORED AS
INPUTFORMAT
'org.apache.hadoop.hive.ql.io.avro.AvroContainerInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.avro.AvroContainerOutputFormat'
优缺点
1.Avro以基于行的格式存储数据
2.设计的主要目标是为了满足schema evolution
3.schema和数据保存在一起
Parquet和ORC文件对比
不同文件格式的性能测试
测试demo1
新建六张不同文件格式的测试用表:
--textfile文件格式
CREATE TABLE `test_textfile`(`id` STRING,…,`desc` STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS textfile;
--sequence文件格式
CREATE TABLE `test_sequence`(`id` STRING,…,`desc` STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS sequence;
--rc文件格式
CREATE TABLE `test_rc`(`id` STRING,…,`desc` STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS rc;
--orc文件格式
CREATE TABLE `test_orc`(`id` STRING,…,`desc` STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS orc;
--parquet文件格式
CREATE TABLE `test_parquet`(`id` STRING,…,`desc` STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS parquet;
--avro文件格式
CREATE TABLE `test_avro`(`id` STRING,…,`desc` STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS avro;
然后,从同一个源表新增数据到这六张测试表,为了体现存储数据的差异性,我们选取了一张数据量比较大的源表(源表数据量为30000000条),根据测试结果从存储空间和SQL查询两个方面进行比较:
文件存储格式 HDFS存储空间 不含group by 含group by
TextFile 7.3 G 105s 370s
Sequence 7.8 G 135s 385s
RC 6.9 G 92s 330s
ORC 246.0 M 34s 310s
Parquet 769.0 M 28s 195s
AVRO 8.0G 240s 530s
根据性能测试总结
- 从存储文件的压缩比来看,ORC和Parquet文件格式占用的空间相对而言要小得多。
- 从存储文件的查询速度看,当表数据量较大时Parquet文件格式查询耗时相对而言要小得多。
测试demo2
https://netflixtechblog.com/using-presto-in-our-big-data-platform-on-aws-938035909fd4
这篇文章主要讲解了persto对 orc和parquet 的对比,见文章中部。
=====================================================================
压缩方式
Hadoop对于压缩格式的是透明识别,hadoop能够自动为我们将压缩的文件解压。 目前在Hadoop中常用的几种压缩格式:lzo,gzip,snappy,bzip2,我们简单做一下对比,方便我们在实际场景中选择不同的压缩格式。
压缩格式 | codec类 | 算法 | 扩展名 | 多文件 | splitable | native | 工具 | hadoop自带 |
---|---|---|---|---|---|---|---|---|
gzip | GzipCodec | deflate | .gz | 否 | 否 | 是 | gzip | 是 |
bzip2 | Bzip2Codec | bzip2 | .bz2 | 是 | 是 | 否 | bzip2 | 是 |
lzo | LzopCodec | lzo | .lzo | 否 | 是 | 是 | lzop | 否 |
snappy | SnappyCodec | snappy | .snappy | 否 | 否 | 是 | 无 | 否 |
- 压缩相关codec实现在org.apache.hadoop.io.compress包下面
deflate压缩
标准压缩算法,其算法实现是zlib,而gzip文件格式只是在deflate格式上增加了文件头和一个文件尾
gzip压缩
压缩率比较高,而且压缩/解压速度也比较快;
hadoop本身支持,在应用中处理gzip格式的文件就和直接处理文本一样;
有hadoop native库;
大部分linux系统都自带gzip命令,使用方便;
缺点 : 不支持split;
①适用于压缩后的文件大小在120M以内(haoop2的标准block大小是120M)的处理,可以有效提高读的并发,对hive,streaming,Java 等mr程序透明,无需修改原程序
②由于gzip拥有较高的压缩比,因此相比于其他压缩算法,更适用于冷数据的存储
bzip2压缩
支持split,支持多文件;
具有很高的压缩率,比gzip压缩率都高;
hadoop本身支持,但不支持native;
在linux系统下自带bzip2命令,使用方便;
压缩/解压速度很慢;
不支持native;
①适合对速度要求不高,但需要较高的压缩率的时候,可以作为mapreduce作业的输出格式
②输出之后的数据比较大,处理之后的数据需要压缩存档减少磁盘空间并且以后数据用得比较少的情况
③对单个很大的文本文件想压缩减少存储空间,同时又需要支持split,而且兼容之前的应用程序(即应用程序不需要修改)的情况
lzo压缩
压缩/解压速度也比较快,合理的压缩率;
支持split,是hadoop中最流行的压缩格式(需要建索引,文件修改后需要重新建索引);
支持hadoop native库;
可以在linux系统下安装lzop命令,使用方便;
压缩率比gzip要低一些;
hadoop本身不支持,需要安装;
在应用中对lzo格式的文件需要做一些特殊处理(为了支持split需要建索引,还需要指定inputformat为lzo格式);
①适用于较大文本的处理
snappy压缩
高速压缩速度和合理的压缩率;
支持hadoop native库;
不支持split;
压缩率比gzip要低;
hadoop本身不支持,需要安装;
linux系统下没有对应的命令
Tips :
① 当mapreduce作业的map输出的数据比较大的时候,作为map到reduce的中间数据的压缩格式;
②或者作为一个mapreduce作业的输出和另外一个mapreduce作业的输入
是否压缩数据以及使用何种压缩格式对性能具有重要的影响,一般原则:
- 需要平衡压缩和解压缩数据所需的能力、读写数据所需的磁盘 IO,以及在网络中发送数据所需的网络带宽。正确平衡这些因素有赖于集群和数据的特征,以及您的使用模式。
- 如果数据已压缩(例如 JPEG 格式的图像),则不建议进行压缩。事实上,结果文件实际上可能大于原文件。
- GZIP 压缩使用的 CPU 资源比 Snappy 或 LZO 更多,但可提供更高的压缩比。GZIP 通常是不常访问的冷数据的不错选择。而 Snappy 或 LZO 则更加适合经常访问的热数据。
- BZip2 还可以为某些文件类型生成比 GZip 更多的压缩,但是压缩和解压缩时会在一定程度上影响速度。HBase 不支持 BZip2 压缩。
- Snappy 的表现通常比 LZO 好。应该运行测试以查看您是否检测到明显区别。
- 对于 MapReduce,如果您需要已压缩数据可拆分,BZip2、LZO 和 Snappy 格式都可拆分,但是 GZip 不可以。可拆分性与 HBase 数据无关。
- 对于 MapReduce,可以压缩中间数据、输出或二者。相应地调整您为 MapReduce 作业提供的参数。
=======================================================================
延申问题
为什么hadoop没有自带lzo和snappy压缩?
主要是由于lzo和snappy压缩采用的是GPL协议,而hadoop是apache协议,有关协议的区别可参考阮大神的图示: