Hive的文件存储格式有五种:textfile、sequencefile、orc、parquet、avro,前面两种是行式存储,orc和parquet是列式存储。如果为textfile的文件格式,直接load,不需要走mapreduce;如果是其他的类型就需要走mapreduce了,因为其他类型都涉及到了文件压缩,需要借助mapreduce的压缩方式实现。
Textfile : 按行存储,不支持块压缩,默认格式,不支持压缩,磁盘开销大,加载数据的速度最高。
Sequencefile :
Hadoop API 提供的一种二进制文件,以
的形式序列化到文件中,按行存储。 (包含键值对的二进制的文件存储格式,支持压缩,可以节省存储空间)
Avro :
按行存储,带有schema文件格式,一行数据是个map,添加字段方便
Rcfile :
数据按行分块,每块按列存储,结合了行存储和列存储的优点。
rcfile保证同一行的数据位于同一节点,因此元组重构的开销很低。
rcfile能够利用列维度的数据压缩,且能跳过不必要的列读取。
对于成百上千字段的表而言,rcfile更合适。
Orcfile :
数据按行分块,每块按列存储,
压缩快,快速列存取。
效率比rcfile高,是rcfile的改良版本,使用了索引
提高读、写、处理数据的能力
(带有压缩和轻量级索引,一行数据是个数组,查询快,不适合添加字段)
Parquet :
按列存储,相对于orc,parquet压缩比较低,查询效率较低
(带有压缩和轻量级索引,和orc比较类似)
压缩比 : orc > parquet > textfile (textfile没有进行压缩)
查询速度 : 三者几乎一致
1. 创建Avro表
--1. schema文件,用json类型表示
vi avro.schema
{
"type" : "record",
"name" : "RunRecord",
"namespace" : "com.yao",
"fields" : [{
"name" : "word",
"type" : "string"
},{
"name" : "num",
"type" : "long"
}
]
}
--2. 将schema文件放到指定的hdfs目录下
hadoop fs -mkdir /user/cz/config
hadoop fs -put avro.schema /user/cz/config
--3. 根据 avro.schema.url 对应的目录下的schema文件,创建与文件格式相对应的表结构
create external table if not exists word_avro
row format serde 'org.apache.hadoop.hive.serde2.avro.AvroSerDe'
with serdeproperties ('avro.schema.url' = '/user/cz/config/avro.schema')
stored as avro
location '/user/cz/word_avro';
--查看字段信息
desc word_avro;
word string
num bigint
--4. 向 avro 表中存储数据
create table word_tmp(word string,num int) row format delimited fields terminated by ' ';
--查找表对应的目录
show create table word_tmp;
/hive/warehouse/yao.db/word_tmp
vi word_tmp
hello 20
world 10
hdfs 50
hadoop 80
mapreduce 90
hadoop fs -put word_tmp /hive/warehouse/yao.db/word_tmp
select * from word_tmp;
--查询导入的方式向avro存数据
insert into table word_avro select * from word_tmp;
select * from word_avro;
show create table word_avro;
dfs -ls /hive/warehouse/yao.db/word_avro
hadoop fs -get /hive/warehouse/yao.db/word_avro/000000_0
cat 000000_0
--开头Obj,avro.schema约束,存储方式就是avro,读的时候会转换成正常的数据
--如果要增加字段,只需要修改schema文件即可,在fields中添加{},定义字段名字类型以及默认值
vi avro.schema
{
"type" : "record",
"name" : "RunRecord",
"namespace" : "com.yao",
"fields" : [{
"name" : "word",
"type" : "string"
},{
"name":"new_col",
"type":"long",
"default":-1
},{
"name" : "num",
"type" : "long"
}
]
}
--重新上传到config目录下,覆盖上传
hadoop fs -put -f avro.schema /user/cz/config
--查看验证
desc word_avro
word string
new_col bigint
num bigint
--追加的方式
insert into table word_avro select word,88,num from word_tmp;
select * from word_avro;
hello -1 20
world -1 10
hdfs -1 50
hadoop -1 80
mapreduce -1 90
hello 88 20
world 88 10
hdfs 88 50
hadoop 88 80
mapreduce 88 90
总结: 如果增加字段,需要给新增字段设置默认值,否则查询会报错
优点: 后续数据的字段扩展不影响以前表的使用,或者后续表的修改不影响读取以前的数据
缺点: 数据里面存在冗余数据,会使数据的文件变得很大。
应用场景: 最原始的etl数据使用,因为最原始的数据经常变动结果,使用这种数据格式不受影响。
2. 创建orc表
(1)ORC文件格式解析
① 定义:
ORC File (Optimized Row Columnar file),有索引有压缩的列式存储格式。这种文件格式可以提供一种高效的方法存储Hive数据,其设计目标是用于克服Hive其他格式的缺陷,运用ORC File可以提高Hive的读、写、及处理数据的性能。
ORC File格式最主要的优点就是在文件中存储了一些轻量级的索引数据。
行式存储: 以一行一行为单位,在磁盘中存储数据。
列式存储: 每一列看成一行存储。
② orc file文件结构
ORC File包含一组组的行数据,称为stripes。
ORC File的file footer还包含一些额外的辅助信息。
ORC File文件的最后,一个被称为postscript的区,主要是用来存储压缩参数及压缩的大小。
stripe大小在Hive低版本中默认为250MB,高版本中默认为256MB。方便HDFS进行读取更加高效,HDFS的block块设置为256MB,256MB就会对应一个切片,就对应一个map task线程进行处理,一个线程就可以把一个stripe里面的数据进行读取
③stripe结构
每个stripe都包含index data、row data 以及stripe footer。stripe footer 包含流位置的目录,row data 在表扫描的时候会用到。
index data 包含每列的最大和最小值以及每列所在的行,行索引里面提供了偏移量,它可以跳到正确的压缩块位置。具有相对频繁的行索引,使得在stripe中快速读取的过程中可以跳过很多行,尽管这个stripe的大小很大。在默认情况下,最大可以跳过一万行。
(2)创建ORC表
--根据建表语句,创建user_install_status_other表
create external table `user_install_status_other_orc`(
`aid` string comment 'from deserializer',
`pkgname` string comment 'from deserializer',
`uptime` bigint comment 'from deserializer',
`type` int comment 'from deserializer',
`country` string comment 'from deserializer',
`gpcategory` string comment 'from deserializer')
partitioned by (`dt` string)
stored as orc
location 'hdfs://ns1/user/cz/user_install_status_other_orc'
tblproperties('orc.compress'='SNAPPY','orc.create.index'='true');
--指定压缩格式为snappy(默认是zlib),压缩性能更高,速度快,压缩完体积更小
--查询导入
insert overwrite table user_install_status_other_orc partition(dt='20141228')
select aid,pkgame,uptime,type,country,gpcategory
from yao.user_install_status_other where dt='20141228';
--从两个方面判断orc比textfile有什么优势:
--有索引,查询数据的时候不用启动mapreduce,有压缩,在hdfs占用的体积更小
两种类型的比较
--①查询对比
select * from user_install_status_other_orc where dt='20141228' and aid='81af53e9d9247805';
--在散列字段上,更能体现ORC结构的查询优势
--因为有索引,可以直接扫描orc文件,不需要执行mapreduce任务
--②磁盘存储
--orc支持压缩,存储数据量就会较小
(3)ORC表在压缩上的优势
dfs -du -s -h /user/cz/user_install_status_other_orc
-- -s代表统计这个目录下的总大小,-h代表显示大小的时候自适应显示
466.1M 1.4G /user/cz/user_install_status_other_orc
--orc这张表占用磁盘空间为466.1M,1.4G代表HDFS一个文件三个副本总的大小
dfs -du -s -h /hive/warehouse/yao.db/user_install_status_other;
1.3G 4.0G /hive/warehouse/yao.db/user_install_status_other
--没有经过压缩的数据占1.3G,总大小4.0G
--orc和普通表的两方面的对比
(4)hive使用hadoop配置压缩方式进行数据压缩
如何往textfile文件中导入压缩格式的文件:
--方法一:
-- 1.先设置压缩
-- 设置hive输出压缩
set hive.exec.compress.output=true;
set mapred.output.compress=true;
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;
-- 2.建表
create external table `user_install_status_gz`(
`aid` string comment 'from deserializer',
`pkgname` string comment 'from deserializer',
`uptime` bigint comment 'from deserializer',
`type` int comment 'from deserializer',
`country` string comment 'from deserializer',
`gpcategory` string comment 'from deserializer')
stored as textfile location 'hdfs://ns1/user/cz/user_install_status_gz';
-- 3.导入数据
insert overwrite table user_install_status_gz
select aid,pkgname,uptime,type,country,gpcategory from yao.user_install_status_limit;
-- 因为配置了压缩所以,hdsf文件中应该是xxxx.gz结尾
dfs -ls /user/cz/user_install_status_gz;
/user/cz/user_install_status_gz/000000_0.gz
--方法二:
--Hadoop默认支持gzip压缩方式,读取的时候能够解析结尾是gz的文件
create table dem_tab(id int,name string);
vi demo
1 zs
2 ls
3 ww
gzip demo
hadoop fs -put demo.gz /hive/warehouse/yao.db/demo_tab
--能够查到这张表的三条数据
select * from demo_tab;
1 zs
2 ls
3 ww
(5)parquet文件格式解析
① 定义
Parquet是面向分析型业务的列式存储格式,由Twitter和Cloudera合作开发,2015年5月从Apache的孵化器里毕业成为Apache顶级项目,支持大部分计算框架。而orc只能hive可以使用,因此parquet通用性更好。
② Parquet文件结构
parquet文件由一个文件头(header) ,就是该文件的Magic Code,用于校验它是否是一个parquet文件。一个或多个紧随其后的行组 (Row Goup)、Row Group由列块 (Column Chuck)、页 (Page)组成。以及一个用于结尾的文件尾 (footer) 构成。
行组 (Row Goup):
parquet在水平方向上将数据划分为行组,默认行组大小与HDFS Block块大小对齐,parquet保证一个行组会被一个mapper处理。
列块 (Column Chunk):
行组中每一列保存在一个列块中,一个列块具有相同的数据类型,不同的列块可以使用不同的压缩算法。
页 (Page):
parquet是页存储方式,每一列块包含多个页,一个页是最小的编码单位,同一列块的不同页可以使用
(6)创建parquet表
--存储方式parquet,压缩方式SNAPPY
create table if not exists yao.word_parquet(word string, num int)
stored as parquet
tblproperties ("parquet.compress"="SNAPPY")
--select * from word_tmp;
hello 20
world 10
hdfs 50
hadoop 80
mapreduce 90
--查询导入
insert into table word_par select * from word_tmp;
show create table word_par;
hadoop fs -get /hive/warehouse/yao.db/word_par/000000_0
参看视频: 32.创建Avro表_哔哩哔哩_bilibili