B站尚硅谷hive学习视频整理,用于自查
文章目录
1.什么是hive
Hive 是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类 SQL 查询功能。本质是将HQL转化为MapReduce
2.Hive优缺点
- 优点:
1)操作接口采用类 SQL 语法,提供快速开发的能力(简单、容易上手)。
2)避免了去写 MapReduce,减少开发人员的学习成本。
3)Hive 的执行延迟比较高,因此 Hive 常用于数据分析,对实时性要求不高的场合。
4)Hive 优势在于处理大数据,对于处理小数据没有优势,因为 Hive 的执行延迟比较高。
5)Hive 支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。 - 缺点
1)Hive 的 HQL 表达能力有限
2)Hive 的效率比较低
3.hive和数据库比较
1)查询语言
由于 SQL 被广泛的应用在数据仓库中,因此,专门针对 Hive 的特性设计了类 SQL 的查询语言 HQL。熟悉 SQL 开发的开发者可以很方便的使用 Hive 进行开发。
2)数据更新
由于 Hive 是针对数据仓库应用设计的,而数据仓库的内容是读多写少的。因此,Hive 中不建议对数据的改写,所有的数据都是在加载的时候确定好的(一次写入,多次查询)。而数据库中的数据通常是需要经常进行修改的,因此可以使用 INSERT INTO … VALUES 添加数据,使用 UPDATE … SET 修改数据。
3)执行延迟
Hive 在查询数据的时候,由于没有索引,需要扫描整个表,因此延迟较高。另外一个导致 Hive 执行延迟高的因素是 MapReduce 框架。由于 MapReduce 本身具有较高的延迟,因此在利用 MapReduce 执行 Hive 查询时,也会有较高的延迟。相对的,数据库的执行延迟较低。当然,这个低是有条件的,即数据规模较小,当数据规模大到超过数据库的处理能力的时候,Hive 的并行计算显然能体现出优势。
4)数据规模
由于 Hive 建立在集群上并可以利用 MapReduce 进行并行计算,因此可以支持很大规模的数据;对应的,数据库可以支持的数据规模较小。
4.hive常用交互命令
1)“-e”不进入 hive 的交互窗口执行 sql 语句
hive -e "select id from student;"
2)“-f”执行脚本中 sql 语句并将结果写入txt文件中
bin/hive -f /opt/module/hive/datas/hivef.sql > /opt/module/datas/hive_result.txt
3)退出
exit;
4)在 hive cli 命令窗口中如何查看 hdfs 文件系统
hive(default)>dfs -ls /;
5)查看在 hive 中输入的所有历史命令
- 进入到当前用户的根目录 /root 或/home/atguigu
- 查看. hivehistory 文件
cat .hivehistory
5.hive数据类型
- 基本数据类型
tinyint /smallint /INT/ BIGINT/ BOOLEAN / FLOAT /DOUBLE/ STRING/decimal/varchar/ TIMESTAMP /BINARY - 集合数据类型
STRUCT/MAP/ARRAY
STRUCT和 c 语言中的 struct 类似,都可以通过“点”符号访问元素内容。例如,如果某个列的数据类型是 struct<first:STRING, last:STRING>,那么第 1 个元素可以通过字段struct.first 来引用。
6.将文件数据load到hive表中
(1)假设某表有如下一行,我们用 JSON 格式来表示其数据结构。在 Hive 下访问的格式为
{
"name": "songsong",
"friends": ["bingbing" , "lili"] , //列表 Array,
"children": { //键值 Map,
"xiao song": 18 ,
"xiaoxiao song": 19
}
"address": { //结构 Struct,
"street": "hui long guan",
"city": "beijing"
}
}
2)基于上述数据结构,我们在 Hive 里创建对应的表,并导入数据。创建本地测试文件 test.txt
{"name": "songsong", "friends": ["bingbing" , "lili"] , "children": { "xiao song": 18 ,"xiaoxiao song": 19}"address": {"street": "hui long guan","city": "beijing"}}
3)测试表 test
create table test(
name string,
friends array<string>,
children map<string, int>,
address struct<street:string, city:string>
)
row format serde 'org.apache.hadoop.hive.serde2.JsonSerDe'
location '/user/hive/warehouse/test';
4)导入文本数据到测试表
load data local inpath '/opt/module/hive/datas/test.txt' into table test;
hdfs上的文件被load后会被删除
5)访问三种集合列里的数据,以下分别是 ARRAY,MAP,STRUCT 的访问方式
select friends[1],children['xiao song'],address.city from test where name="songsong";
OK
_c0 _c1 city
lili 18 beijing
Time taken: 0.076 seconds, Fetched: 1 row(s)
7.类型转化
- 可以进行隐式转换,但是不能进行反向转化
(1)任何整数类型都可以隐式地转换为一个范围更广的类型,如 TINYINT 可以转换成INT,INT 可以转换成 BIGINT。
(2)所有整数类型、FLOAT 和 STRING 类型都可以隐式地转换成DOUBLE。
(3)TINYINT、SMALLINT、INT 都可以转换为 FLOAT。
(4)BOOLEAN 类型不可以转换为任何其它的类型。 - 可以使用 CAST 操作显示进行数据类型转换
例如 CAST(‘1’ AS INT)将把字符串’1’ 转换成整数 1;如果强制类型转换失败,如执行CAST(‘X’ AS INT),表达式返回空值 NULL。
8.DDL
- 数据库相关
--增
CREATE DATABASE [IF NOT EXISTS] database_name
[COMMENT database_comment]
[LOCATION hdfs_path] --指定存放位置
[WITH DBPROPERTIES (property_name=property_value, ...)];
--删
drop database if exists db_hive2;
drop database db_hive cascade; --如果数据库不为空,可以采用 cascade 命令,强制删除
--改
alter database db_hive set dbproperties('createtime'='20170830');
--查
desc database extended db_hive; --extended 查看详细信息
- 表相关
--增
CREATE [TEMPORARY][EXTERNAL] TABLE [IF NOT EXISTS] table_name --EXTERNAL外部表
[(col_name data_type [COMMENT col_comment], ...)]
[COMMENT table_comment]
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] --分区
[CLUSTERED BY (col_name, col_name, ...)[SORTED BY (col_name [ASC|DESC]**-, ...)] INTO num_buckets BUCKETS] --分桶
[ROW FORMAT row_format]
[STORED AS file_format]
[LOCATION hdfs_path]
[TBLPROPERTIES (property_name=property_value, ...)]
[AS select_statement]
[like table]
ROW FORMAT指定SerDe,序列化和反序列化
语法一:
ROW FORMAT DELIMITED
[FIELDS TERMINATED BY char] --列分隔符
[COLLECTION ITEMS TERMINATED BY char] --map、struct和array中每个元素之间的分隔符
[MAP KEYS TERMINATED BY char] --map中key与value的分隔符
[LINES TERMINATED BY char] --行分隔符
[NULL DEFINED AS char]
语法二:
ROW FORMAT SERDE serde_name [WITH SERDEPROPERTIES (propertyname=property_value,…)]
STORED AS 指定存储文件类型,常用的存储文件类型:SEQUENCEFILE(二进制序列文件)、TEXTFILE(文本,默认值=)、ORC、PARQUET。
AS:后跟查询语句,根据查询结果创建表,会复制数据,不允许创建外部表。
LIKE 允许用户复制现有的表结构,但是不复制数据,允许创建外部表。
--查
show create table table_name;
desc [formatted|extended] table_name;
--删(如果是删除外部表,hdfs 中的数据还在,但是 metadata 中 dept 的元数据已被删除)
drop table table_name;
truncate table table_name;
--修改内部表 student2 为外部表
alter table student2 set tblproperties('EXTERNAL'='TRUE');
--更新列
ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]
--增加和替换列(ADD 是代表新增一字段,字段位置在所有列后面(partition 列前),REPLACE 则是表示替换表中所有字段。)
ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...)
alter 后HDFS数据文件并不会更改,需要重新load文件数据才能使用。
在alter时会自动校验数据类型能否转换,比如string转为int会报错,可以设置set hive.metastore.disallow.incompatible.col.type.changes=false;关闭校验
9.DML
- 数据导入
--向表中装载数据
load data [local] inpath '数据的 path' [overwrite] into table student [partition (partcol1=val1,…)];
--insert(overwrite覆盖 into追加)不支持插入部分字段
insert overwrite/into table student_par select id, name from student where month='201709';
--查询语句中创建表并加载数据
create table if not exists student3 as select id, name from student;
--创建表时通过 Location 指定加载数据路径
create external table if not exists student5( id int, name string)
row format delimited fields terminated by '\t'
location '/student';
-- Import 数据到指定 Hive 表中
import table student2 from '/user/hive/warehouse/export/student';
- 数据导出
--将查询的结果导出
insert overwrite local directory '/opt/module/hive/data/export/student1' --local表示导出至本地,如无,表示导出到hdfs
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'--格式化,可省略
select * from student;
-- Hadoop 命令导出到本地
dfs -get /user/hive/warehouse/student/student.txt/opt/module/data/export/student3.txt;
--Hive Shell 命令导出(hive -f/-e 执行语句或者脚本 > file)
bin/hive -e 'select * from default.student;' >/opt/module/hive/data/export/student4.txt;
--Export 导出到 HDFS 上(export 和 import 主要用于两个 Hadoop 平台集群之间 Hive 表迁移)
export table default.student to '/user/hive/warehouse/export/student';
--清除(Truncate 只能删除管理表,不能删除外部表中数据)
truncate table table_name
- 查询
1 )A<=>B :如果 A 和 B 都为 NULL,则返回 TRUE,如果一边为 NULL,返回 False;
2)比较运算符中(<>,<,>,between and),有一方为NULL,结果就返回NULL;
3)A RLIKE B, A REGEXP B:B 是基于 java 的正则表达式;
4)hive中连接方式有FULL JOIN,将会返回所有表中符合 WHERE 语句条件的所有记录。如果任一表的指定字段没有符合条件的值的话,那么就使用 NULL 值替代。
5)优化:当对 3 个或者更多表进行 join 连接时,如果每个 on 子句都使用相同的连接键的话,那么只会产生一个 MapReduce job。
6)order by全局排序,只有一个 Reducer
7)sort by对于大规模的数据集 order by 的效率非常低。在很多情况下,并不需要全局排序,此时可以使用先distribute by分区,再sort by排序。如 select * from emp distribute by deptno sort by empno desc;
8)cluster by当 distribute by 和 sorts by 字段相同时,可以使用 cluster by 方式,但是排序只能是升序。
9)group by having和sql相同
10.分区
建表:
create table dept_partition(
deptno int, dname string, loc string
)
partitioned by (day string)
row format delimited fields terminated by '\t';
注意:分区字段不能是表中已经存在的数据,可以将分区字段看作表的伪列。
加载数据
load data local inpath '/opt/module/hive/datas/dept_20200401.log' into table dept_partition partition(day='20200401');
分区表加载数据时,必须指定分区
创建分区
alter table dept_partition add partition(day='20200404');
alter table dept_partition add partition(day='20200405') partition(day='20200406');
删除分区(注意逗号)
alter table dept_partition drop partition (day='20200406');
alter table dept_partition drop partition (day='20200404'), partition(day='20200405');
查看分区
show partitions dept_partition;
创建二级分区表
create table dept_partition2(
deptno int, dname string, loc string)
partitioned by (day string, hour string)
row format delimited fields terminated by '\t';
11.数据上传到分区表的方式
方法一:上传后同步
1)上传文件
hive (default)> dfs -mkdir -p
/user/hive/warehouse/mydb.db/dept_partition2/day=20200401/hour=13;
hive (default)> dfs -put /opt/module/datas/dept_20200401.log
/user/hive/warehouse/mydb.db/dept_partition2/day=20200401/hour=13;
此时查询不到刚上传的数据
2)执行修复命令
hive> msck repair table dept_partition2;
此时可以查询到数据
方法二:上传数据后添加分区
1)上传文件
2)执行添加分区
hive (default)> alter table dept_partition2 add partition(day='201709',hour='14');
方法三:创建文件夹后 load 数据到分区
1)创建目录
hive (default)> dfs -mkdir -p /user/hive/warehouse/mydb.db/dept_partition2/day=20200401/hour=15;
2)上传数据
hive (default)> load data local inpath '/opt/module/hive/datas/dept_20200401.log' into table dept_partition2 partition(day='20200401',hour='15');
12.严格模式和非严格模式
参数设置
--开启非严格模式
hive.exec.dynamic.partition.mode=nonstrict
--开启严格模式
hive.exec.dynamic.partition.mode=strict
- 如果Hive开启严格模式,将会阻止以下三种查询:
1)对分区表查询,where条件中过滤字段没有分区字段;
2)对order by查询,order by的查询不带limit语句。
3)笛卡尔积join查询,join查询语句中不带on条件或者where条件; - 如果Hive开启严格模式,表示必须指定至少一个分区为
静态分区
--建表
create table dept_partition_dy(id int, name string) partitioned by (loc int,dt timestamp) row format delimited fields terminated by '\t';
--非严格模式
set hive.exec.dynamic.partition.mode=nonstrict;
hive (default)> insert into table dept_partition_dy partition(loc) select deptno, dname, loc, dt from dept;
--严格模式
set hive.exec.dynamic.partition.mode=strict;
hive (default)> INSERT OVERWRITE TABLE dept_partition_dy PARTITION(dt='2024-11-19', loc)
SELECT deptno, dname, loc from dept;
--在这里,loc分区将由SELECT子句(即loc)的最后一列动态创建。
--而dt分区是手动指定写死的。
13.动态分区
动态分区是指向分区表insert时,被写入的分区不由用户指定,而是由每行数据的最后一个字段的值来动态决定。
开启动态分区参数设置
--开启动态分区功能(默认 true,开启)
hive.exec.dynamic.partition=true
--设置为非严格模式
hive.exec.dynamic.partition.mode=nonstrict
--在所有执行 MR 的节点上,最大一共可以创建多少个动态分区。默认 1000
hive.exec.max.dynamic.partitions=1000
--在每个执行 MR 的节点上,最大可以创建多少个动态分区。该参数需要根据实际的数据来设定。比如:源数据中包含了一年的数据,即 day 字段有 365 个值,那么该参数就需要设置成大于 365,如果使用默认值 100,则会报错。
hive.exec.max.dynamic.partitions.pernode=100
--整个 MR Job 中,最大可以创建多少个 HDFS 文件。默认 100000
hive.exec.max.created.files=100000
--当有空分区生成时,是否抛出异常。一般不需要设置。默认 false
hive.error.on.empty.partition=false
14.分桶
对于一张表或者分区,Hive 可以进一步组织成桶,也就是更为细粒度的数据范围划分。
分桶是将数据集分解成更容易管理的若干部分的另一个技术。
分区针对的是数据的存储路径;分桶针对的是数据文件。
建表
create table stu_buck(id int, name string)
clustered by(id)
into 4 buckets
row format delimited fields terminated by '\t';
分桶规则:
Hive 的分桶采用对分桶字段的值进行哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中
分桶表操作需要注意的事项:
(1)reduce 的个数设置为-1,让 Job 自行决定需要用多少个 reduce 或者将 reduce 的个
数设置为大于等于分桶表的桶数
(2)从 hdfs 中 load 数据到分桶表中,避免本地文件找不到问题
(3)不要使用本地模式
15.抽样查询
对于非常大的数据集,有时用户需要使用的是一个具有代表性的查询结果而不是全部结果。Hive 可以通过对表进行抽样来满足这个需求。
语法: TABLESAMPLE(BUCKET x OUT OF y)
查询表 stu_buck 中的数据。
hive (default)> select * from stu_buck tablesample(bucket 1 out of 4 on id);
注意:x 的值必须小于等于 y 的值,否则
FAILED: SemanticException [Error 10061]: Numerator should not be bigger than denominator in sample clause for table stu_buck
16.常用函数
1)查看系统自带的函数hive> show functions;
2)显示自带的函数的用法hive> desc function upper;
3)详细显示自带的函数的用法hive> desc function extended upper;
4)空字段赋值,如果 value 为 NULL,则 NVL 函数返回default_value 的值,否则返回 value 的值,如果两个参数都为 NULL ,则返回 NULL。NVL( value,default_value)
5)CASE WHEN THEN ELSE END
6)字符串拼接:CONCAT(string A/col, string B/col…)
17.行转列
- CONCAT_WS(separator, str1, str2,…):它是一个特殊形式的 CONCAT()。第一个参数为分隔符。分隔符可以是与剩余参数一样的字符串。如果分隔符是 NULL,返回值也将为 NULL。str为null会被跳过;
注意: CONCAT_WS must be "string or array - COLLECT_SET(col):函数只接受基本数据类型,它的主要作用是将某字段的值进行去重汇总,产生 Array 类型字段
举例
需求
把星座和血型一样的人归类到一起。结果如下:
sql
SELECT
t1.c_b,
CONCAT_WS("|",collect_set(t1.name))
FROM (
SELECT
NAME,
CONCAT_WS(',',constellation,blood_type) c_b
FROM person_info
)t1
GROUP BY t1.c_b
18. 列转行
- EXPLODE(col):将 hive 一列中复杂的 Array 或者 Map 结构拆分成多行。
- LATERAL VIEW
用法:LATERAL VIEW udtf(expression) tableAlias AS columnAlias
解释:用于和 split, explode 等 UDTF 一起使用,它能够将一列数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合
举例
需求
SELECT
movie,
category_name
FROM
movie_info
lateral VIEW
explode(split(category,",")) movie_info_tmp AS category_name;
19.窗口函数
1)OVER():指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化。
2)CURRENT ROW:当前行
3)n PRECEDING:往前 n 行数据
4)n FOLLOWING:往后 n 行数据
5)UNBOUNDED:起点,
UNBOUNDED PRECEDING 表示从前面的起点,
UNBOUNDED FOLLOWING 表示到后面的终点
6)LAG(col,n,default_val):往前第 n 行数据
7)LEAD(col,n, default_val):往后第 n 行数据
8)NTILE(n):把有序窗口的行分发到指定数据的组中,各个组有编号,编号从 1 开始,对于每一行,NTILE 返回此行所属的组的编号。注意:n 必须为 int 类型。
9)RANK() 排序相同时会重复,总数不会变
10)DENSE_RANK() 排序相同时会重复,总数会减少
11)ROW_NUMBER() 会根据顺序计算
--(1)查询在 2017 年 4 月份购买过的顾客及总人数
select name,count(*) over () from business where substring(orderdate,1,7) = '2017-04' group by name;
--(2)查询顾客的购买明细及月购买总额
select name,orderdate,sum(cost) over(partition by substring(1,7),name) from business;
--(3)上述的场景, 将每个顾客的 cost 按照日期进行累加
select name,orderdate,sum(cost) over(partition by substring(1,7),name order by orderdate) from business;
--(4)查询每个顾客上次的购买时间
select name,orderdate,lag(orderdate,1,'1900-01-01') over(partition by name order by orderdate) from business;
--(5)查询前 20%时间的订单信息
select * from (select *,row number() over(order by orderdate) rn from business) where rn<=3;
20.自定义函数UDF
分类:
1)UDF 一进一出
2)UDAF 聚集函数,多进一出(类似于count,max)
3)UDTF 一进多出(如lateral view explode())
步骤:
1)导入依赖
<dependencies>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>3.1.2</version>
</dependency>
</dependencies>
2)创建函数类
3)打成 jar 包上传到服务器/opt/module/data/myudf.jar
4)将 jar 包添加到 hive 的 classpath
hive (default)> add jar /opt/module/data/myudf.jar;
5)创建临时函数与开发好的 java class 关联
hive (default)> create temporary function my_len as "com.atguigu.hive.MyStringLength";
6)即可在 hql 中使用自定义的函数
hive (default)> select ename,my_len(ename) ename_len from emp;
21.列式存储和行式存储
如图所示左边为逻辑表,右边第一个为行式存储,第二个为列式存储。
1)行存储的特点
查询满足条件的一整行数据的时候,列存储则需要去每个聚集的字段找到对应的每个列的值,行存储只需要找到其中一个值,其余的值都在相邻地方,所以此时行存储查询的速度更快。
2)列存储的特点
因为每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量;每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法。
21.hive文件格式
Hive 支持的存储数据的格式主要有:TEXTFILE 、SEQUENCEFILE、ORC、PARQUET。
TEXTFILE 和 SEQUENCEFILE 的存储格式都是基于行存储的;
ORC 和 PARQUET 是基于列式存储的。
- ORC
每个stripe一般为HDFS的块大小,128M,但是默认为64M,可以修改为128M。每一个 stripe 包含多条记录,这些记录按照列进行独立存储,对应到 Parquet中的 row group 的概念。每个 Stripe 里有三部分组成,分别是 Index Data,Row Data,Stripe Footer:
Index Data:一个轻量级的 index,默认是每隔 1W 行做一个索引。这里做的索引应该只是记录某行的各字段在 Row Data 中的 offset。
Row Data:存的是具体的数据,先取部分行,然后对这些行按列进行存储。对每个列进行了编码,分成多个 Stream 来存储。
Stripe Footer:存的是各个 Stream 的类型,长度等信息。
每个文件有一个 File Footer,这里面存的是每个 Stripe 的行数,每个 Column 的数据类型信息等;每个文件的尾部是一个 PostScript,这里面记录了整个文件的压缩类型以及FileFooter 的长度信息等。在读取文件时,会 seek 到文件尾部读 PostScript,从里面解析到File Footer 长度,再读 FileFooter,从里面解析到各个 Stripe 信息,再读各个 Stripe,即从后
往前读。
1)建表
create table log_orc(
track_time string,
url string,
session_id string,
referer string,
ip string,
end_user_id string,
city_id string
)
stored as orc
tblproperties("orc.compress"="NONE"); -- 设置 orc 存储不使用压缩
2)desc formatted log_orc;
SerDe:以ORC格式序列化和反序列化
InputFormat:以ORC格式输入
OutputFormat:以ORC格式输出
3)向表中加载数据
hive (default)> insert into table log_orc select * from log_text;
不能通过load data的方式加载数据,无法解析
4)查看表中数据大小
hive (default)> dfs -du -h /user/hive/warehouse/log_orc/ ;
5)ORC文件格式支持的参数如下:
参数 | 默认值 | 说明 |
---|---|---|
orc.compress | ZLIB | 压缩格式,可选项:NONE、ZLIB,、SNAPPY |
orc.compress.size | 262,144 | 每个压缩块的大小(ORC文件是分块压缩的) |
orc.stripe.size | 67,108,864 | 每个stripe的大小 |
orc.row.index.stride | 10,000 | 索引步长(每隔多少行数据建一条索引) |
- Parquet
是Hadoop生态中的一个通用的文件格式。以二进制方式存储,因此Parquet格式文件是自解析的。
(1)行组(Row Group):每一个行组包含一定的行数,在一个 HDFS 文件中至少存储一个行组,类似于 orc 的 stripe 的概念。
(2)列块(Column Chunk):在一个行组中每一列保存在一个列块中,行组中的所有列连续的存储在这个行组文件中。一个列块中的值都是相同类型的,不同的列块可能使用不同的算法进行压缩。
(3)页(Page):每一个列块划分为多个页,一个页是最小的编码的单位,在同一个列块的不同页可能使用不同的编码方式。
通常情况下,在存储 Parquet 数据的时候会按照 Block 大小设置行组的大小,由于一般情况下每一个 Mapper 任务处理数据的最小单位是一个 Block,这样可以把每一个行组由一个 Mapper 任务处理,增大任务执行并行度。
1)建表
create table parquet_table
(column_speces)
stored as parquet
tblproperties (property_name=property_value,...);
2)加载数据方式与 orc相同。
3)支持的参数如下:
参数 | 默认值 | 说明 |
---|---|---|
parquet.compression | uncompressed | 压缩格式,可选项:uncompressed,snappy,gzip,lzo,brotli,lz4 |
parquet.block.size | 134217728 | 行组大小,通常与HDFS块大小保持一致 |
parquet.page.size | 1048576 | 页大小 |
22.压缩
在Hive表中和计算过程中,保持数据的压缩,会提高磁盘空间的有效利用和查询性能。
为了支持多种压缩/解压缩算法,Hadoop 引入了编码/解码器,如下表所示:
压缩格式 | 对应的编码/解码器 |
---|---|
DEFLATE | org.apache.hadoop.io.compress.DefaultCodec |
gzip | org.apache.hadoop.io.compress.GzipCodec |
bzip2 | org.apache.hadoop.io.compress.BZip2Codec |
LZO | com.hadoop.compression.lzo.LzopCodec |
Snappy | org.apache.hadoop.io.compress.SnappyCodec |
bzip2和LZO可切片,DEFLATE,Gzip,Snappy不可切片
压缩速度:Snappy>LZO>Gzip>bzip2
解压速度:Snappy>LZO>Gzip>bzip2
22.1 建表时进行压缩
不同表类型的声明压缩方式是不同的。
- TextFile
多数情况下,无需在建表语句做出声明。直接将压缩后的文件导入到该表即可,Hive在查询表中数据时,可自动识别其压缩格式,进行解压。需要注意的是,在执行往表中导入数据的SQL语句时,用户需设置以下参数,来保证写入表中的数据是被压缩的。
--SQL语句的最终输出结果是否压缩
set hive.exec.compress.output=true;
--输出结果的压缩格式(以下示例为snappy)
set mapreduce.output.fileoutputformat.compress.codec =org.apache.hadoop.io.compress.SnappyCodec;
2)ORC
create table orc_table
(column_specs)
stored as orc
tblproperties ("orc.compress"="snappy");
3)Parquet
create table orc_table
(column_specs)
stored as parquet
tblproperties ("parquet.compression"="snappy");
22.2 计算过程中压缩
1)单个MR的中间结果进行压缩
单个MR的中间结果是指Mapper输出的数据,对其进行压缩可降低shuffle阶段的网络IO,可通过以下参数进行配置:
--开启MapReduce中间数据压缩功能
set mapreduce.map.output.compress=true;
--设置MapReduce中间数据数据的压缩方式(以下示例为snappy)
set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
2)单条SQL语句的中间结果进行压缩
单条SQL语句的中间结果是指,两个MR(一条SQL语句可能需要通过MR进行计算)之间的临时数据,可通过以下参数进行配置:
--是否对两个MR之间的临时数据进行压缩
set hive.exec.compress.intermediate=true;
--压缩格式(以下示例为snappy)
set hive.intermediate.compression.codec= org.apache.hadoop.io.compress.SnappyCodec;