导航:首页 > 文件处理 > hadoop压缩配置

hadoop压缩配置

发布时间:2024-10-28 05:01:49

A. Hadoop 压缩从理论到实战

在大数据领域,无论上层计算引擎采用的是什么,在存储过程中,压缩都是一个避不开的问题。合适的压缩选择可以降低存储成本、减少网络传输I/O。而错误的压缩选择则可能让 cpu 负荷达到瓶颈、降低并发度等等,所以是否选择压缩、选择什么压缩格式在大数据存储环节中都是一个至关重要的问题。

点评:压缩时间和压缩率之间的取舍本质上是 cpu 资源和存储资源的取舍。是否需册猛要支持分片也不是绝对的,如果单个文件大小均小于 splitSize,则没必要支持分片。

点评:一阶段考虑尽可能支持分片(单个文件大于 splitSize 时)。二阶段考虑尽可能快的压悄姿基缩速度。三阶段根据是作为长期归档(几乎不用)or 作为下一作业输入,考虑尽可能高的压缩能力 or 支持分片。

点评:有两点需要注意,第一点:这里的速度和压缩率没有具体测试数据,而是给出了一个模糊的表达。因为即使具体测试了速度和压缩率,也会因数据不同而结果有很大的差异。后面会给出测试的脚本,大家可以结合自己的表数据自行测试。第二点:有些压缩格式性能参数很相似,为什么 Hadoop 中要搞这么多种?较为直观的一个原因是:不同存储格式支持的压缩是不一样的,比如 orc 存储格式只支持 zlib 和 snappy 两种压缩 [8] ,parquet 虽然支持很多压缩格式,但是不支持 bzip2 [7]

以下摘自《Hadoop The Definitive Guide》

重点阅读文中加粗片段。大致意思是:因为 gzip 压缩格式使用的 DEFLATE 压缩算法没办法做到随机任意读取,必须同步顺序读取。也就意味着没办法为每一个 block 创建一个分片(split),然后为该分片启一个 mapper 去读取数据。所以即使 gzip 文件有很多 block,MR 程序也只会启动一个 Mapper 去读取所有的 block。也即 gzip 这种压缩格式不支持分片。相反的,如果压缩格式使用的算法支持随机任意读取,那么就可以为每一个 block 创建一个分片,同时启动一个 mapper 去读取数据,这样有多少个 block 就有多少个分片,就有多少个 mapper ,这些 mapper 并行读取数据,效率大大提升。上述涉及到几个小概念,接下来分别进行详述。

一句话总结: zlib、gzip 在大数据语境中都是一种 压缩格式 ,他们使用相同的 压缩算法: DEFLATE,DefaultCodec 是 zlib 使用的 编解码器 ,Gzip 使用的编解码器是 GzipCodec

我们知道,Hadoop 在任务切分时,是按照文件的粒度进行的。即一个文件一个文件启谨进行切分。而每一个文件切分成几块,取决于 splitSize 的大小。比如两个文件,第一个文件 300M,第二个文件150M。分片大小是128M,那么对于第一个文件将会切分成3片(128M,128M,44M),第二个文件会切分成2片(128M,22M)。共计5片。所以分片数量除了由文件数决定,另一个决定因素就是 splitSize 即分片大小。

splitSize 如何计算?

几个前提:

影响参数:

接下来进行实际验证:

经过了 2.4.2 中的一系列实验,验证了一个结论:当一个输入格式支持分片时,mapper 数量是无限制的,反之 mapper 数量小于等于文件的数量。所以我们可以通过设置参数来试图调小分片大小来增加 mapper 数量看其上限是否等于文件数量即可。假如输入的文件个数只有一个,那么当 mapper 数量大于1的时候,说明该输入格式是支持分片的。

大家可以根据自己数据集和想测试的压缩和存储格式自行修改脚本。通过以上脚本跑出来的结果如下:

由 2.1 中评价压缩的三项指标可知,压缩率、压缩/解压速度、是否支持分片是衡量压缩最重要的三项指标。3.1.1小节中只对压缩率进行了测试。压缩/解压速度可以通过跑一些查询语句进一步测试。这里就不展开测试了。业界中常用的存储格式一般是 parquet, orc,所以上面测试除了纯文本只测试了这两种存储格式。

我们可以通过 hive> set io.compression.codecs; 来查看当前Hadoop集群支持的压缩,在公司的集群中查询得到的结果是:

可以看到 lzo 有两种编解码器: LzoCodec 和 LzopCodec。他们之间有什么区别呢?

如果你阅读过关于 Hadoop 压缩的文章,应该可以看到,绝大多数文章中对于 snappy 是否支持分片都是直接给出的否定的答案。 CDH 的文档中也指出来 snappy 是不支持分片的。

看文中加粗片段,虽然 snappy 本身是不支持分片的,但是如果 snappy 存储在一些特定的存储格式比如 SequenceFile 或者 Avro 中,那么是可以支持分片的。也就是说 snappy 是否支持分片是分情况讨论的。不能说使用了 snappy 压缩就一定不支持分片。前面提到了,业界中常用的存储格式一般是 parquet 或者 orc,而上面 CDH 的文章中恰恰没有提到 parquet 和 orc 是否支持,接下来以 parquet 为例,进行测试。测试内容即为 parquet + snappy 组合,是否支持分片。
首先准备数据,因为之前做压缩率测试,已经有了 parquet + snappy 文件了,这里直接拿来用。

一共3个输入文件,启了6个mapper,说明输入文件是可以分片的。即 parquet + snappy 的组合是支持分片的。在《Hadoop The Definitive Guide》中也对 parquet 是否支持分片有说明:

以 maprece.output.fileoutputformat.compress.codec 为例,这个参数可以在三个地方配置:

那么当三者都设置时,以哪个为准呢?按照经验来看,一定是粒度小的优先级大于粒度大的优先级。经过测试也验证了这种猜测。即:表级别 > hive > hadoop

初学者往往容易混淆存储格式和压缩格式之间的关系,其实二者是完全独立的。如果完整的阅读了该篇文章,应该已经消除了这一块理解对误区。这里总结一下:比如 parquet, orc,他们都是常见的 存储格式 。是否使用压缩,使用何种压缩都是可以设置的。而 zlib、gzip、lzo、lz4、snappy 等等这些都是常见的 压缩格式 ,他们既可以依附于某些 存储格式 ,比如之前提到的 parquet + snappy,orc + zlib 等等。也可以脱离特定的 存储格式 ,比如纯文本文件进行压缩,text + parquet, text + bzip2 等等。

B. Hive优化之Hive的配置参数优化

Hive是大数据领域常用的组件之一,主要用于大数据离线数仓的运算,关于Hive的性能调优在日常工作和面试中是经常涉及的一个点,因此掌握一些Hive调优是必不可少的一项技能。影响Hive效率的主要因素有数据倾斜、数据冗余、job的IO以及不同底层引擎配置情况和Hive本身参数和HiveSQL的执行等。本文主要从建表配置参数方面对Hive优化进行讲解。

1. 创建一个普通表

table test_user1(id int, name string,code string,code_id string ) ROW FORMAT DELIMITED FIELDS TERMINATED  BY ',';

2. 查看这张表的信息

DESCRIBE FORMATTED  test_user1;

我们从该表的描述信息介绍建表时的一些可优化点。

2.1 表的文件数

numFiles表示表中含有的文件数,当文件数过多时可能意味着该表的小文件过多,这时候我们可以针对小文件的问题进行一些优化,HDFS本身提供了解决方案:

(1)Hadoop Archive/HAR:将小文件打包成大文件。

(2)SEQUENCEFILE格式:将大量小文件压缩成一个SEQUENCEFILE文件。

(3)CombineFileInputFormat:在map和rece处理之前组合小文件。

(4)HDFS Federation:HDFS联盟,使用多个namenode节点管理文件。

除此之外,我们还可以通过设置hive的参数来合并小文件。

(1)输入阶段合并

需要更改Hive的输入文件格式,即参数hive.input.format,默认值是org.apache.hadoop.hive.ql.io.HiveInputFormat,我们改成org.apache.hadoop.hive.ql.io.CombineHiveInputFormat。这样比起上面对mapper数的调整,会多出两个参数,分别是mapred.min.split.size.per.node和mapred.min.split.size.per.rack,含义是单节点和单机架上的最小split大小。如果发现有split大小小于这两个值(默认都是100MB),则会进行合并。具体逻辑可以参看Hive源码中的对应类。

(2)输出阶段合并

直接将hive.merge.mapfiles和hive.merge.mapredfiles都设为true即可,前者表示将map-only任务的输出合并,后者表示将map-rece任务的输出合并,Hive会额外启动一个mr作业将输出的小文件合并成大文件。另外,hive.merge.size.per.task可以指定每个task输出后合并文件大小的期望值,hive.merge.size.smallfiles.avgsize可以指定所有输出文件大小的均值阈值,默认值都是1GB。如果平均大小不足的话,就会另外启动一个任务来进行合并。

2.2 表的存储格式

通过InputFormat和OutputFormat可以看出表的存储格式是TEXT类型,Hive支持TEXTFILE, SEQUENCEFILE, AVRO, RCFILE, ORC,以及PARQUET文件格式,可以通过两种方式指定表的文件格式:

(1)CREATE TABLE ... STORE AS <file_format>:在建表时指定文件格式,默认是TEXTFILE

(2)ALTER TABLE ... [PARTITION partition_spec] SET FILEFORMAT <file_format>:修改具体表的文件格式

如果要改变创建表的默认文件格式,可以使用set

hive.default.fileformat=<file_format>进行配置,适用于所有表。同时也可以使用set

hive.default.fileformat.managed = <file_format>进行配置,仅适用于内部表或外部表。

扩展:不同存储方式的情况

TEXT,

SEQUENCE和

AVRO文件是面向行的文件存储格式,不是最佳的文件格式,因为即便只查询一列数据,使用这些存储格式的表也需要读取完整的一行数据。另一方面,面向列的存储格式(RCFILE,

ORC, PARQUET)可以很好地解决上面的问题。关于每种文件格式的说明,如下:

(1)TEXTFILE

创建表时的默认文件格式,数据被存储成文本格式。文本文件可以被分割和并行处理,也可以使用压缩,比如GZip、LZO或者Snappy。然而大部分的压缩文件不支持分割和并行处理,会造成一个作业只有一个mapper去处理数据,使用压缩的文本文件要确保文件不要过大,一般接近两个HDFS块的大小。

(2)SEQUENCEFILE

key/value对的二进制存储格式,sequence文件的优势是比文本格式更好压缩,sequence文件可以被压缩成块级别的记录,块级别的压缩是一个很好的压缩比例。如果使用块压缩,需要使用下面的配置:set

hive.exec.compress.output=true; set io.seqfile.compression.type=BLOCK

(3)AVRO

二进制格式文件,除此之外,avro也是一个序列化和反序列化的框架。avro提供了具体的数据schema。

(4)RCFILE

全称是Record Columnar File,首先将表分为几个行组,对每个行组内的数据进行按列存储,每一列的数据都是分开存储,即先水平划分,再垂直划分。

(5)ORC

全称是Optimized Row Columnar,从hive0.11版本开始支持,ORC格式是RCFILE格式的一种优化的格式,提供了更大的默认块(256M)

(6)PARQUET

另外一种列式存储的文件格式,与ORC非常类似,与ORC相比,Parquet格式支持的生态更广,比如低版本的impala不支持ORC格式。

配置同样数据同样字段的两张表,以常见的TEXT行存储和ORC列存储两种存储方式为例,对比执行速度。

TEXT存储方式

总结: 从上图中可以看出列存储在对指定列进行查询时,速度更快, 建议在建表时设置列存储的存储方式 。

2.3 表的压缩

对Hive表进行压缩是常见的优化手段,一些存储方式自带压缩选择,比如SEQUENCEFILE支持三种压缩选择:NONE,RECORD,BLOCK。Record压缩率低,一般建议使用BLOCK压缩;

ORC支持三种压缩选择:NONE,ZLIB,SNAPPY。我们以TEXT存储方式和ORC存储方式为例,查看表的压缩情况。

配置同样数据同样字段的四张表,一张TEXT存储方式,另外三张分别是默认压缩方式的ORC存储、SNAPPY压缩方式的ORC存储和NONE压缩方式的ORC存储,查看在hdfs上的存储情况:

TEXT存储方式

默认压缩ORC存储方式

SNAPPY压缩的ORC存储方式

NONE压缩的ORC存储方式

总结 :可以看到ORC存储方式将数据存放为两个block,默认压缩大小加起来134.69M,SNAPPY压缩大小加起来196.67M,NONE压缩大小加起来247.55M,TEXT存储方式的文件大小为366.58M,且默认block两种存储方式分别为256M和128M,ORC默认的压缩方式比SNAPPY压缩得到的文件还小,原因是ORZ默认的ZLIB压缩方式采用的是deflate压缩算法,比Snappy压缩算法得到的压缩比高,压缩的文件更小。 ORC不同压缩方式之间的执行速度,经过多次测试发现三种压缩方式的执行速度差不多,所以建议采用ORC默认的存储方式进行存储数据。

2.4 分桶分区

Num Buckets表示桶的数量,我们可以通过分桶和分区操作对Hive表进行优化:

对于一张较大的表,可以将它设计成分区表,如果不设置成分区表,数据是全盘扫描的,设置成分区表后,查询时只在指定的分区中进行数据扫描,提升查询效率。要注意尽量避免多级分区,一般二级分区足够使用。常见的分区字段:

(1)日期或者时间,比如year、month、day或者hour,当表中存在时间或者日期字段时,可以使用些字段。

(2)地理位置,比如国家、省份、城市等

(3)业务逻辑,比如部门、销售区域、客户等等

与分区表类似,分桶表的组织方式是将HDFS上的一张大表文件分割成多个文件。分桶是相对分区进行更细粒度的划分,分桶将整个数据内容按照分桶字段属性值得hash值进行区分,分桶可以加快数据采样,也可以提升join的性能(join的字段是分桶字段),因为分桶可以确保某个key对应的数据在一个特定的桶内(文件),所以巧妙地选择分桶字段可以大幅度提升join的性能。通常情况下,分桶字段可以选择经常用在过滤操作或者join操作的字段。

创建分桶表

create

table test_user_bucket(id int, name string,code string,code_id string )

clustered by(id) into 3 buckets ROW FORMAT DELIMITED FIELDS TERMINATED 

BY ',';

查看描述信息

DESCRIBE FORMATTED test_user_bucket

多出了如下信息

查看该表的hdfs

同样的数据查看普通表和分桶表查询效率

普通表

分桶表

普通表是全表扫描,分桶表在按照分桶字段的hash值分桶后,根据join字段或者where过滤字段在特定的桶中进行扫描,效率提升。

本文首发于: 数栈研习社

数栈是云原生—站式数据中台PaaS,我们在github上有一个有趣的开源项目: FlinkX

FlinkX是一个基于Flink的批流统一的数据同步工具,既可以采集静态的数据,比如MySQL,HDFS等,也可以采集实时变化的数据,比如MySQL

binlog,Kafka等,是全域、异构、批流一体的数据同步引擎,大家如果有兴趣,欢迎来github社区找我们玩~

C. 压缩包在root用户下解压过了,怎么才能把它删除然后在hadoop用户下再解压

如果需要删除在root用户下解压的压缩包,再在hadoop用户下解压,可以按照以下步骤进行:

1. 以root身份登录系统,找到需要删除的压缩包所在目录,删除该文件,可以使用命令:sudo rm -f 压缩包名称。

2. 切换至hadoop用户,并切换至需要解压的目录。

3. 用hadoop用户权限再次下载需要解压的压缩包,可以使用cp或wget等命令。

4. 解压该文件,可以使用unzip或tar等命令进行解压操作。

需要注意的是,对于需要维护的高级操作,应该充分理解相关命令的用法,避免误操作误操作造成不必要的麻烦。

D. 如何在Scala中读取Hadoop集群上的gz压缩文件

(1)一个从文件创建的Scala对象,或(2)一个并行切片(分布在各个节点之间),或(3)从其他RDD转换得来,或(4)改变已有RDD的持久性,如请求将已有RDD缓存在内存中。Spark应用称为driver,实现单个节点或一组节点上的操作。

阅读全文

与hadoop压缩配置相关的资料

热点内容
10种编程语言 浏览:743
绵阳学驾驶手机上下什么app 浏览:126
python如何模拟网页操作 浏览:40
单片机多文件编译方法 浏览:838
不动产压缩时间 浏览:569
租房管理平台源码 浏览:65
复乐园pdf 浏览:455
程序员找到公交车 浏览:695
婴儿宝宝操有什么APP推荐 浏览:71
如何将数据库附加到服务器上 浏览:391
php退出循环 浏览:479
梦幻西游怎么修改服务器人数上限 浏览:330
自动开启命令 浏览:845
查询云服务器访问的ip 浏览:836
智能app的弱点是什么 浏览:410
php实现的n 浏览:544
Python写出特效 浏览:976
加密的zip压缩包修复 浏览:415
安卓系统源码如何混淆 浏览:291
题库算法 浏览:476