返回 导航

大数据

hangge.com

Hive - 数据存储格式详解4(RCFile格式)

作者:hangge | 2024-10-10 08:34

四、RCFile 格式

1,基本介绍

(1)RCFile 是专门为 Hive 设计的数据存储格式。数据会首先按照行分组,每个组内部按照列存储。他整合了行存储和列存储的优点,可以称为是行列式存储,大层面还是属于列式存储的。

(2)RCFile 的主要特点是压缩速度快,可分割,支持快速列存取。
提示:在读取所有列的情况下,RCFile 的性能没有 SequenceFile 高,不过在实际工作中大部分的统计分析需求都不会读取所有列。

(3)我们可以通过下图来直观的感受一下 RCFile 的数据存储格式:
  • 左边的 Relation 表示关系型数据库中的数据存储形式,可以把它认为是一张表,表中有 A\B\C\D 这几个列。
    • 第一行数据中 A 的值为 101B 的值为 111C 的值为 121D 的值为 131。后面的以此类推。
  • 针对这份数据,如果使用 RCFile 格式进行存储是这样的,看中间这个图:
    • RCFile 是存储在 HDFS 里面的,所以说会有多个 HDFSBlock 块。
    • 每个 Block 块内部包含多个 Row GroupRowGroup 可以翻译为:行组。
  • RowGroup 里面包含的是具体的数据,存储格式是这样的,看右边这个图:
    • 这里面的第一行数据是所有 A 字段的值,因为 RowGroup 是行列式存储,所以会把原始表中的每个列的数据存储到一起,便于查询这个列的数据。
    • 第二行是所有 B 字段的值。后面的以此类推。
  • 所以从这个图里面可以看出来,RCFile 会把数据首先按照行分成 Row Group,在 Row Group 内部按照列存储,每个列的数据存储在一起。

2,不使用压缩

(1)首先我们执行如下命令在 Hive 中创建一个 RCFile 存储格式的表。
注意:在这需要使用 stored as 指定 rcfile 存储格式,不指定的话默认是 textfile
create external table stu_rcfile_none_compress(
  id int,
  name string,
  city string
)
row format delimited
fields terminated by ','
lines terminated by '\n'
stored as rcfile
location '/stu_rcfile_none_compress';

(2)创建后执行如下命令确认一下这个表,如果 INPUTFORMAT 使用的是 RCFileInputFormat,说明这个表中需要存储 RCFile 格式的数据。
show create table stu_rcfile_none_compress;

(3)然后从普通表中查询数据导入到这个 RCFile 存储格式的表中。
  • 在这里我们设置 mapreduce.job.reduces=1,表示将结果数据写入到一个数据文件中,这也便于后面验证这个数据文件是否支持 Split
普通表 stu_textfile 中的数据来源可以参考我前面写的文章:Hive - 数据存储格式详解 2(TextFile 格式)
set mapreduce.job.reduces=1;
insert into stu_rcfile_none_compress select id,name,city from stu_textfile group by id,name,city;

(4)查看结果数据可以发现,其体积为 1G,远小于原始的 TextFile 文件以及 SequenceFile 格式的 2G 大小,可以说明 RCFile 在数据存储层面还是比较优秀的。

(5)接下来写一个 sql 查询表中的数据,验证是否支持切分:
select id,count(*) from stu_rcfile_none_compress group by id;
  • 可以看到产生了 8map 任务,说明 RCFile 格式的文件是支持切分的。

(6)最后,这个表中的数据验证完毕之后,建议删除一下数据,释放 HDFS 空间。
hdfs dfs -rm -r -skipTrash /stu_rcfile_none_compress

3,使用 Defalte 压缩

(1)接下来我们构建一个新的压缩数据表。
提示:这个压缩数据表的建表语句和上面不使用压缩数据表建表语句没有区别,唯一的区别就是在向表中添加数据的时候指定数据压缩格式。
create external table stu_rcfile_deflate_compress(
  id int,
  name string,
  city string
)
row format delimited
fields terminated by ','
lines terminated by '\n'
stored as rcfile
location '/stu_rcfile_deflate_compress';

(2)Hive 中默认是没有开启压缩的,我们执行如下命令开启 Hive 输出数据压缩功能,并且指定使用 deflate 压缩。
set hive.exec.compress.output=true;
set mapreduce.output.fileoutputformat.compress=true;
set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.DeflateCodec;
  • 如果后期不确定使用的是哪种压缩格式,可以通过这条命令查看:
set mapreduce.output.fileoutputformat.compress.codec;

(3)接下来通过 insert into select 从普通表中查询数据,插入到压缩表中。
  • 在这里我们设置 mapreduce.job.reduces=1,表示将结果数据写入到一个数据文件中,这也便于后面验证这个数据文件是否支持 Split
注意:为了能够控制任务最终产生的数据文件个数,在这里通过 mapreduce.job.reduces 来控制,并且 SQL 语句中需要有可以产生 shuffle 的操作,如果是普通的 select 语句,最终是不会产生 Reduce 任务的,那么 mapreduce.job.reduces 这个参数就无法生效了。
set mapreduce.job.reduces=1;
insert into stu_rcfile_deflate_compress select id,name,city from stu_textfile group by id,name,city;
  • 可以看到最终产生的数据文件大小为 341M

(5)接下来写一个 sql 查询压缩表中的数据,确认一下是否验证是否支持切分:
select id,count(*) from stu_rcfile_deflate_compress group by id;
  • 在这里看到产生了 2map 任务,说明 RCFile 格式带压缩的文件也支持切分。

(6)最后,这个压缩表中的数据查看后最好删除一下,这样可以释放 HDFS 存储空间。
hdfs dfs -rm -r -skipTrash /stu_rcfile_deflate_compress
评论

全部评论(0)

回到顶部