1.Hive的概述
√ 意義:在于大幅度降低工程師學(xué)習(xí)MapReduce的學(xué)習(xí)成本,讓好用(計(jì)算速度快)的MapReduce更方便的使用(使用簡(jiǎn)單)
√ 基本概念:Hive是基于Hadoop的一個(gè)數(shù)據(jù)倉(cāng)庫(kù)工具凳厢,可以將結(jié)構(gòu)化的數(shù)據(jù)文件映射為一張數(shù)據(jù)庫(kù)表账胧,并提供類SQL查詢功能(HQL)。
√ 本質(zhì):其本質(zhì)是將SQL轉(zhuǎn)換為MapReduce的任務(wù)進(jìn)行運(yùn)算先紫,底層由HDFS來(lái)提供數(shù)據(jù)的存儲(chǔ)治泥,hive可以理解為一個(gè)將SQL轉(zhuǎn)換為MapReduce的任務(wù)的工具。
√ Hive可以做數(shù)據(jù)存儲(chǔ),可以做數(shù)據(jù)分析; Hive的存儲(chǔ)依賴于HDFS; Hive的分析依賴于MapReduce.
√ 特點(diǎn):
1)可擴(kuò)展: 可以自由地?cái)U(kuò)展集群的規(guī)模,一般不需要重啟服務(wù)
2)延展性: 支持用戶自定義函數(shù),可以根據(jù)自己的需求實(shí)現(xiàn)自己的函數(shù)
3)容錯(cuò): 良好的容錯(cuò)性,節(jié)點(diǎn)出現(xiàn)問(wèn)題SQL仍可完成執(zhí)行
2.Hive的架構(gòu)
元數(shù)據(jù): 描述數(shù)據(jù)(表屬性)的數(shù)據(jù)---表屬性包括:表名,字段名,字段類型.
解釋器遮精、編譯器居夹、優(yōu)化器、執(zhí)行器:完成HQL 查詢語(yǔ)句從詞法分析本冲、語(yǔ)法分析准脂、編譯、優(yōu)化以及查詢計(jì)劃的生成檬洞。生成的查詢計(jì)劃存儲(chǔ)在HDFS 中狸膏,并在隨后有MapReduce 調(diào)用執(zhí)行.
===每天練習(xí)SQL語(yǔ)句===
3.Hive的使用場(chǎng)景: 海量數(shù)據(jù){前提} 離線分析{場(chǎng)景}(關(guān)鍵!)
少量的數(shù)據(jù)不建議使用Hive(效率低)添怔。
延時(shí)性高湾戳!---不適合在線數(shù)據(jù)查詢(快速查詢)
有索引贤旷,但是默認(rèn)不創(chuàng)建!
沒(méi)有專門的數(shù)據(jù)格式砾脑;用戶可以自定義(三個(gè)屬性)
加載時(shí)幼驶,不需要轉(zhuǎn)換格式;不會(huì)對(duì)數(shù)據(jù)本身進(jìn)行修改拦止,甚至不會(huì)掃描(相當(dāng)于拷貝)
不支持對(duì)數(shù)據(jù)的修改和添加县遣,加載時(shí)已確定好;
建立在Hadoop之上汹族,Hive的可擴(kuò)展性和Hadoop的可擴(kuò)展性是一致的!
===總結(jié):hive具有sql數(shù)據(jù)庫(kù)的外表其兴,但應(yīng)用場(chǎng)景完全不同顶瞒,hive只適合用來(lái)做批量數(shù)據(jù)統(tǒng)計(jì)分析。
4.Hive的數(shù)據(jù)存儲(chǔ)
===數(shù)據(jù)模型:
DB:數(shù)據(jù)庫(kù)
Table:數(shù)據(jù)表(內(nèi)部表)
External Table:外部表
Partition:表的分區(qū)
Bucket:表的桶
5.Hive的安裝部署
===安裝hive
/etc/profile文件是系統(tǒng)的核心配置文件元旬,盡量不要修改榴徐!------使用/etc/profile.d,添加需要的腳本文件后,source /etc/profile即可
在/etc/profile.d路徑下添加一個(gè)腳本匀归,將需要添加的配置填寫在腳本中
export HIVE_HOME=/export/servers/hive-1.1.0-cdh5.14.0 export PATH=:PATH
最后 source /etc/profile
===安裝MySQL【使用yum源】
===修改hive的配置文件【注意修改hive-site.xml中MySQL的位置在哪臺(tái)機(jī)器上】
===上傳MySQL的lib驅(qū)動(dòng)包
===使用方式
###配置環(huán)境變量后坑资,可以在任意目錄下直接使用hive###
1)第一種:Hive交互shell------在hive、bin的目錄下使用bin
cd /export/servers/hive-1.1.0-cdh5.14.0
bin/hive
- 查看所有數(shù)據(jù)庫(kù)
hive (default)> show databases;
- 創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)
hive (default)> create database myhive;
- 使用該數(shù)據(jù)庫(kù)并創(chuàng)建數(shù)據(jù)庫(kù)表
hive (default)> use myhive;
hive (myhive)> create table test(id int,name string);
以上命令操作完成之后穆端,一定要確認(rèn)mysql里面出來(lái)一個(gè)數(shù)據(jù)庫(kù)hive
2)第二種:Hive JDBC 服務(wù)【hive的默認(rèn)端口是10000】
啟動(dòng)hiveserver2服務(wù)
前臺(tái)啟動(dòng)
cd /export/servers/hive-1.1.0-cdh5.14.0
bin/hive --service hiveserver2
- 后臺(tái)啟動(dòng)
cd /export/servers/hive-1.1.0-cdh5.14.0
nohup bin/hive --service hiveserver2 &
- beeline連接server2
bin/beeline
beeline> !connect jdbc:hive2://node01.hadoop.com:10000
注意:如果使用beeline方式連接hiveserver2袱贮,一定要保證hive在mysql當(dāng)中的元數(shù)據(jù)庫(kù)已經(jīng)創(chuàng)建成功,不然就會(huì)拒絕連接
3)第三種:Hive命令
- 使用 –e 參數(shù)來(lái)直接執(zhí)行hql的語(yǔ)句
bin/hive -e "use myhive;select * from test;"
4)第四種:使用 –f 參數(shù)通過(guò)指定文本文件來(lái)執(zhí)行hql的語(yǔ)句
vim hive.sql
use myhive;select * from test;
bin/hive -f hive.sql
6.Hive基本操作
6.1 創(chuàng)建數(shù)據(jù)庫(kù)與創(chuàng)建數(shù)據(jù)庫(kù)表
- 創(chuàng)建數(shù)據(jù)庫(kù)
創(chuàng)建數(shù)據(jù)庫(kù)
create database if not exists myhive;
use myhive;
===說(shuō)明:hive的表存放位置模式是由hive-site.xml當(dāng)中的一個(gè)屬性指定的
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
Hive的數(shù)據(jù)庫(kù)体啰、表攒巍、分區(qū)在HDFS上都是以一個(gè)文件夾的方式存在的
【創(chuàng)建數(shù)據(jù)庫(kù)或者表時(shí),帶“l(fā)ocation”荒勇,就在指定的位置上創(chuàng)建柒莉,不帶就是/user/hive/warehouse/中】
- 創(chuàng)建數(shù)據(jù)庫(kù)并指定hdfs的存儲(chǔ)位置
create database myhive2 location '/myhive2';
- 修改數(shù)據(jù)庫(kù)
可以使用alter database 命令來(lái)修改數(shù)據(jù)庫(kù)的一些屬性。但是數(shù)據(jù)庫(kù)的元數(shù)據(jù)信息是不可更改的沽翔,包括數(shù)據(jù)庫(kù)的名稱以及數(shù)據(jù)庫(kù)所在的位置
alter database myhive2 set dbproperties('createtime'='20200606');
- 查看數(shù)據(jù)庫(kù)的詳細(xì)信息
查看基本信息
desc database myhive2;
查看數(shù)據(jù)庫(kù)更多詳細(xì)信息
desc database extended myhive2兢孝;
- 刪除數(shù)據(jù)庫(kù)
刪除一個(gè)空數(shù)據(jù)庫(kù),如果數(shù)據(jù)庫(kù)下面有數(shù)據(jù)表仅偎,那么就會(huì)報(bào)錯(cuò)
drop database myhive2;
強(qiáng)制刪除數(shù)據(jù)庫(kù)跨蟹,包含數(shù)據(jù)庫(kù)下面的表一起刪除
drop database myhive cascade; 不要執(zhí)行(危險(xiǎn)動(dòng)作)
- 創(chuàng)建數(shù)據(jù)庫(kù)表操作
創(chuàng)建數(shù)據(jù)庫(kù)表語(yǔ)法
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name
[(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]
6.2 管理表
- hive建表
use myhive;
create table stu(id int,name string);
insert into stu values (1,"zhangsan");
select * from stu;
- 創(chuàng)建表并且指定字段之間(列)的分隔符
create table if not exists stu2(id int ,name string) row format delimited fields terminated by '\t' stored as textfile location '/user/stu2';
insert into stu2 values (1,"zhangsan");
insert into stu2 values (2,"lisi");
insert into stu2 values (3,"wangwu");
- 根據(jù)查詢結(jié)果創(chuàng)建表
create table stu333 as select * from stu2;
- 根據(jù)已經(jīng)存在的表結(jié)構(gòu)創(chuàng)建表
create table stu4 like stu2;
- 查詢表的類型
desc stu2;【信息】
desc formatted stu2哨颂;【詳細(xì)信息】
- 數(shù)據(jù)加載
建表(案例):
create table student (s_id string,s_name string,s_birth string , s_sex string ) row format delimited fields terminated by '\t';
從本地文件系統(tǒng)向表中加載數(shù)據(jù)【local:Linux系統(tǒng)喷市;沒(méi)有l(wèi)ocal,就是hdfs系統(tǒng)(加載數(shù)據(jù)方式相同);into之前加overwrite會(huì)先將數(shù)據(jù)清空再添加數(shù)據(jù)】
load data local inpath '/export/servers/hivedatas/student.csv' into table student_tmp;
6.3 外部表:
- 外部表因?yàn)槭侵付ㄆ渌膆dfs路徑的數(shù)據(jù)加載到表當(dāng)中來(lái)威恼,所以hive表會(huì)認(rèn)為自己不完全獨(dú)占這份數(shù)據(jù)品姓,所以刪除hive表的時(shí)候寝并,數(shù)據(jù)仍然存放在hdfs當(dāng)中,不會(huì)刪掉
===csv文件的默認(rèn)分隔符是“腹备,”
- 案例===創(chuàng)建外部表并且添加數(shù)據(jù)
create external table techer (t_id string,t_name string) row format delimited fields terminated by '\t';
create external table student (s_id string,s_name string,s_birth string , s_sex string ) row format delimited fields terminated by '\t';
- 加載數(shù)據(jù)同上
從hdfs文件系統(tǒng)向表中加載數(shù)據(jù)(需要提前將數(shù)據(jù)上傳到hdfs文件系統(tǒng)衬潦,其實(shí)就是一個(gè)移動(dòng)文件的操作)
cd /export/servers/hivedatas
hdfs dfs -mkdir -p /hivedatas
hdfs dfs -put techer.csv /hivedatas/
load data inpath '/hivedatas/techer.csv' into table techer;
===內(nèi)部表和外部表的區(qū)別:刪除表時(shí),內(nèi)部表的元數(shù)據(jù)植酥,數(shù)據(jù)文件同時(shí)刪除镀岛;外部表是刪除元數(shù)據(jù),真正的數(shù)據(jù)文件不刪除友驮。
6.4 分區(qū)【不同的文件夾】表
- 創(chuàng)建表【分區(qū)的字段絕對(duì)不能出現(xiàn)在表的字段里】
創(chuàng)建分區(qū)表語(yǔ)法
create table score(s_id string,c_id string, s_score int) partitioned by (month string) row format delimited fields terminated by '\t';
創(chuàng)建一個(gè)表帶多個(gè)分區(qū)
create table score2 (s_id string,c_id string, s_score int) partitioned by (year string,month string,day string) row format delimited fields terminated by '\t';
- 加載數(shù)據(jù)
加載數(shù)據(jù)到分區(qū)表中
load data local inpath '/export/servers/hivedatas/score.csv' into table score partition (month='201806');
加載數(shù)據(jù)到一個(gè)多分區(qū)的表中去
load data local inpath '/export/servers/hivedatas/score.csv' into table score2 partition(year='2018',month='06',day='01');
- 查詢
多分區(qū)聯(lián)合查詢使用union all來(lái)實(shí)現(xiàn)
select * from score where month = '201806' union all select * from score where month = '201806';
- 查看分區(qū)
show partitions score;
- 添加分區(qū)
添加一個(gè)分區(qū)
alter table score add partition(month='201805');
同時(shí)添加多個(gè)分區(qū)
alter table score add partition(month='201804') partition(month = '201803');
注意:
1)數(shù)據(jù)在加載時(shí)漂羊,工程師必須清楚的知道這個(gè)數(shù)據(jù)是屬于哪個(gè)分區(qū)的
2)添加分區(qū)之后就可以在hdfs文件系統(tǒng)當(dāng)中看到表下面多了一個(gè)文件夾
- 刪除分區(qū)
刪除分區(qū)
alter table score drop partition(month = '201806');
- 案例練習(xí)
6.5 分桶表【減少了JOIN的數(shù)據(jù)量】
將數(shù)據(jù)按照指定的字段進(jìn)行分成多個(gè)桶中去,說(shuō)白了就是將數(shù)據(jù)按照字段進(jìn)行劃分卸留,可以將數(shù)據(jù)按照字段劃分到多個(gè)文件當(dāng)中去
***桶可以作用在hive的表之上走越,還可以作用在hive的分區(qū)之上***
===>必須按照的順序:
開啟hive的桶表功能
set hive.enforce.bucketing=true;
設(shè)置reduce的個(gè)數(shù)
set mapreduce.job.reduces=3;
- 使用語(yǔ)法
創(chuàng)建普通表:
create table course_common (c_id string,c_name string,t_id string) row format delimited fields terminated by '\t';
普通表中加載數(shù)據(jù)
load data local inpath '/export/servers/hivedatas/course.csv' into table course_common;
通過(guò)insert overwrite給桶表中加載數(shù)據(jù)
insert overwrite table course select * from course_common cluster by(c_id);
===分桶的字段必須在已有的字段里!
6.6 修改表
-
表重命名
基本語(yǔ)法:
alter table old_table_name rename to new_table_name;
把表score4修改成score5
alter table score4 rename to score5;
增加/修改列信息
(1)查詢表結(jié)構(gòu)
desc score5;
(2)添加列
alter table score5 add columns (mycol string, mysco string);
(3)查詢表結(jié)構(gòu)
desc score5;
(4)更新列
alter table score5 change column mysco mysconew int;
(5)查詢表結(jié)構(gòu)
desc score5;
- 刪除表
drop table score5;
6.7 hive表中加載數(shù)據(jù)
- 直接向分區(qū)表中插入數(shù)據(jù)
create table score3 like score;
insert into table score3 partition(month ='201807') values ('001','002','100');
- 通過(guò)查詢插入數(shù)據(jù)
通過(guò)load方式加載數(shù)據(jù)
load data local inpath '/export/servers/hivedatas/score.csv' overwrite into table score partition(month='201806');
通過(guò)查詢方式加載數(shù)據(jù)
create table score4 like score;
insert overwrite table score4 partition(month = '201806') select s_id,c_id,s_score from score;
注: 關(guān)鍵字overwrite 必須要有
- 多插入模式
給score表加載數(shù)據(jù)
load data local inpath '/export/servers/hivedatas/score.csv' overwrite into table score partition(month='201806');
創(chuàng)建第一部分表:
create table score_first( s_id string,c_id string) partitioned by (month string) row format delimited fields terminated by '\t' ;
創(chuàng)建第二部分表:
create table score_second(c_id string,s_score int) partitioned by (month string) row format delimited fields terminated by '\t';
分別給第一部分與第二部分表加載數(shù)據(jù)
from score
insert overwrite table score_first partition(month='201806') select s_id,c_id
insert overwrite table score_second partition(month = '201806') select c_id,s_score;
- 查詢語(yǔ)句中創(chuàng)建表并且加載數(shù)據(jù)(as select)
將查詢結(jié)果保存到一張表中去
create table score5 as select * from score耻瑟;
- 創(chuàng)建表時(shí)通過(guò)location制定加載數(shù)據(jù)路徑
1. 創(chuàng)建表旨指,并指定在hdfs上的位置
create external table score6 (s_id string,c_id string,s_score int) row format delimited fields terminated by '\t' location '/myscore6';
2)上傳數(shù)據(jù)到hdfs上
hdfs dfs -mkdir -p /myscore6
hdfs dfs -put score.csv /myscore6;
3)查詢數(shù)據(jù)
select * from score6;
- 清空表數(shù)據(jù)
只能清空管理表,也就是內(nèi)部表
truncate table score5;
7.hive查詢語(yǔ)法
7.1 select
注【hive中的排序】:
1)order by 會(huì)對(duì)輸入做全局排序喳整,因此只有一個(gè)reducer時(shí)谆构,會(huì)導(dǎo)致當(dāng)輸入規(guī)模較大時(shí),需要較長(zhǎng)的計(jì)算時(shí)間框都。
2)sort by不是全局排序是輸入做全局排序搬素,其在數(shù)據(jù)進(jìn)入reducer前完成排序∷蚕睿【reduce內(nèi)部有序】
3)distribute by(字段)根據(jù)指定的字段將數(shù)據(jù)分到不同的reducer蔗蹋,且分發(fā)算法是hash散列【distribute by經(jīng)常和sort by配合使用】。
4)Cluster by(字段) 除了具有Distribute by的功能外囱淋,還會(huì)對(duì)該字段進(jìn)行排序【但是排序只能是倒敘排序猪杭,不能指定排序規(guī)則為ASC或者DESC】。
===因此妥衣,如果分桶和sort字段是同一個(gè)時(shí)皂吮,此時(shí),cluster by = distribute by + sort by
===分桶表的作用:最大的作用是用來(lái)提高join操作的效率税手;【可以作為優(yōu)化的選項(xiàng)】
-
全表查詢
select * from score;
-
選擇特定列查詢
select s_id ,c_id from score;
-
列別名
1)重命名一個(gè)列蜂筹。
2)便于計(jì)算。
3)緊跟列名芦倒,也可以在列名和別名之間加入關(guān)鍵字‘AS’
select s_id as myid ,c_id from score;
7.2 常用函數(shù)
1)求總行數(shù)(count)
select count(1) from score;
2)求分?jǐn)?shù)的最大值(max)
select max(s_score) from score;
3)求分?jǐn)?shù)的最小值(min)
select min(s_score) from score;
4)求分?jǐn)?shù)的總和(sum)
select sum(s_score) from score;
5)求分?jǐn)?shù)的平均值(avg)
select avg(s_score) from score;
7.3 limit語(yǔ)句
典型的查詢會(huì)返回多行數(shù)據(jù)艺挪。LIMIT子句用于限制返回的行數(shù)。
select * from score limit 3;
7.4 WHERE語(yǔ)句
1)使用WHERE 子句兵扬,將不滿足條件的行過(guò)濾掉麻裳。
2)WHERE 子句緊隨 FROM 子句口蝠。
3)案例實(shí)操
查詢出分?jǐn)?shù)大于60的數(shù)據(jù)
select * from score where s_score > 60;
7.5 比較運(yùn)算符(between/in/is null)
2)案例實(shí)操
(1)查詢分?jǐn)?shù)等于80的所有的數(shù)據(jù)
select * from score where s_score = 80;
(2)查詢分?jǐn)?shù)在80到100的所有數(shù)據(jù)
select * from score where s_score between 80 and 100;
(3)查詢成績(jī)?yōu)榭盏乃袛?shù)據(jù)
select * from score where s_score is null;
(4)查詢成績(jī)是80和90的數(shù)據(jù)
select * from score where s_score in(80,90);
7.6 like和rlike
1)使用LIKE運(yùn)算選擇類似的值
2)選擇條件可以包含字符或數(shù)字:
% 代表零個(gè)或多個(gè)字符(任意個(gè)字符)。
_ 代表一個(gè)字符津坑。
3)RLIKE子句是Hive中這個(gè)功能的一個(gè)擴(kuò)展妙蔗,其可以通過(guò)Java的正則表達(dá)式這個(gè)更強(qiáng)大的語(yǔ)言來(lái)指定匹配條件与帆。
4)案例實(shí)操
(1)查找以8開頭的所有成績(jī)
select * from score where s_score like '8%';
(2)查找第二個(gè)數(shù)值為9的所有成績(jī)數(shù)據(jù)
select * from score where s_score like '_9%';
(3)查找成績(jī)中含9的所有成績(jī)數(shù)據(jù)
select * from score where s_score rlike '[9]';
7.7 邏輯運(yùn)算符(and/or/not)
案例實(shí)操
(1)查詢成績(jī)大于80夹孔,并且s_id是01的數(shù)據(jù)
select * from score where s_score >80 and s_id = '01';
(2)查詢成績(jī)大于80,或者s_id 是01的數(shù)
select * from score where s_score > 80 or s_id = '01';
(3)查詢s_id 不是 01和02的學(xué)生
select * from score where s_id not in ('01','02');
8.Hive Shell參數(shù)
略
9.Hive函數(shù)
略
10.hive的數(shù)據(jù)壓縮
略
11.hive的數(shù)據(jù)存儲(chǔ)格式
===行存儲(chǔ)的使用場(chǎng)景:只需要找到其中的一個(gè)值猎提,其余的值都在相鄰的地方穆役,【這個(gè)值周邊的字段大部分的業(yè)務(wù)都會(huì)使用到】
===列存儲(chǔ)的使用場(chǎng)景:對(duì)少量字段但是數(shù)據(jù)條數(shù)很多的情況下
===數(shù)據(jù)格式(4種)}:TEXTFILE(行存) SEQUENCEFILE(行存) ORC(列存) PARQUET(列存)
12.存儲(chǔ)和壓縮結(jié)合
===hive壓縮算法和存儲(chǔ)格式的選擇:
在實(shí)際的項(xiàng)目開發(fā)當(dāng)中寸五,hive表的數(shù)據(jù)存儲(chǔ)格式一般選擇:orc或parquet。壓縮方式一般選擇snappy孵睬。
13.調(diào)優(yōu)
13.1 fetch抓炔ゼ摺(hive可以避免進(jìn)行MapReduce)
【hive.fetchtask.conversion有三個(gè)值:minimal more none】
hive.fetchtask.conversion對(duì)以下三種語(yǔ)句不會(huì)轉(zhuǎn)化成MR:
1)select* from table;
2)select字段 from table掰读;
3)select字段from table limit N;
hive.fetchtask.conversion為none時(shí)對(duì)所有語(yǔ)句都會(huì)轉(zhuǎn)化成MR
13.2 本地模式
此方法將MapReduce程序在本地執(zhí)行叭莫,不提交到集群中(任務(wù)未分配到集群上運(yùn)行)蹈集。
對(duì)于小數(shù)據(jù)集,使用本地模式執(zhí)行時(shí)間可以明顯被縮短雇初。
本地模式設(shè)置:
1)開啟本地模式:set hive.exec.mode.local.auto=true;
2)設(shè)置local mr接收的的最大輸入數(shù)據(jù)量拢肆,當(dāng)輸入數(shù)據(jù)量小于這個(gè)值時(shí)采用local mr的方式,默認(rèn)為134217728靖诗,即128M(是否在本地執(zhí)行的分界點(diǎn)):set hive.exec.mode.local.auto.inputbytes.max=51234560;
3)//設(shè)置local mr接收的文件個(gè)數(shù)的最大個(gè)數(shù)郭怪,當(dāng)輸入文件個(gè)數(shù)小于這個(gè)值時(shí)采用local mr的方式,默認(rèn)為4(是否在本地執(zhí)行的分界點(diǎn)):set hive.exec.mode.local.auto.input.files.max=10;
13.3 Group By
默認(rèn)情況下刊橘,Map階段同一Key數(shù)據(jù)分發(fā)給一個(gè)reduce鄙才,當(dāng)一個(gè)key數(shù)據(jù)過(guò)大時(shí)就傾斜了。
并不是所有的聚合操作都需要在Reduce端完成促绵,很多聚合操作都可以先在Map端進(jìn)行部分聚合攒庵,最后在Reduce端得出最終結(jié)果。
==開啟Map端局部聚合參數(shù)設(shè)置【使用場(chǎng)景需要謹(jǐn)慎考慮败晴,不能使用在類似平均數(shù)的算法上浓冒,此功能會(huì)開啟多個(gè)任務(wù)】
(1)開啟mapj聚合:是否在Map端進(jìn)行聚合,默認(rèn)為True
set hive.map.aggr = true;
(2)設(shè)置聚合的數(shù)量:在Map端進(jìn)行聚合操作的條目數(shù)目
set hive.groupby.mapaggr.checkinterval = 100000;
(3)數(shù)據(jù)傾斜時(shí)負(fù)載均衡:有數(shù)據(jù)傾斜的時(shí)候進(jìn)行負(fù)載均衡(默認(rèn)是false)
set hive.groupby.skewindata = true;
當(dāng)選項(xiàng)設(shè)定為 true尖坤,生成的查詢計(jì)劃會(huì)有兩個(gè)MR Job稳懒。
13.4 Count(distinct)
基于語(yǔ)法級(jí)別的優(yōu)化
1)SELECT count(DISTINCT id) FROM bigtable;---效率低下
2)SELECT count(id) FROM (SELECT id FROM bigtable GROUP BY id) a;---效率較高
===在海量數(shù)據(jù)的前提下,第二種較快B丁3“稹墅冷!
13.5 笛卡爾積
盡量避免無(wú)效的on條件或不再使用條件
13.6 使用分區(qū)剪裁、列剪裁
在查詢語(yǔ)句中辙谜,盡量使用哪些列就讀取哪些列俺榆,業(yè)務(wù)需要使用哪些分區(qū)的數(shù)據(jù),就讀取哪些分區(qū)
關(guān)于join的優(yōu)化:盡量將where條件添加在on后面
盡量?jī)?yōu)先過(guò)濾數(shù)據(jù)再進(jìn)行數(shù)據(jù)的join装哆,盡量避免先join后后過(guò)濾
13.7 動(dòng)態(tài)分區(qū)的調(diào)整
以第一個(gè)表的表結(jié)構(gòu)為準(zhǔn)罐脊,將第一個(gè)表的表結(jié)構(gòu)完全復(fù)制到第二個(gè)表中,第二個(gè)表的數(shù)據(jù)在加載時(shí)蜕琴,就不需要指定分區(qū)
開啟動(dòng)態(tài)分區(qū)參數(shù)設(shè)置
(1)開啟動(dòng)態(tài)分區(qū)功能(默認(rèn)true萍桌,開啟)
set hive.exec.dynamic.partition=true;
(2)設(shè)置為非嚴(yán)格模式(動(dòng)態(tài)分區(qū)的模式,默認(rèn)strict凌简,表示必須指定至少一個(gè)分區(qū)為靜態(tài)分區(qū)上炎,nonstrict模式表示允許所有的分區(qū)字段都可以使用動(dòng)態(tài)分區(qū)。)
set hive.exec.dynamic.partition.mode=nonstrict;
(3)在所有執(zhí)行MR的節(jié)點(diǎn)上雏搂,最大一共可以創(chuàng)建多少個(gè)動(dòng)態(tài)分區(qū)藕施。
set hive.exec.max.dynamic.partitions=1000;
(4)在每個(gè)執(zhí)行MR的節(jié)點(diǎn)上,最大可以創(chuàng)建多少個(gè)動(dòng)態(tài)分區(qū)凸郑。該參數(shù)需要根據(jù)實(shí)際的數(shù)據(jù)來(lái)設(shè)定裳食。比如:源數(shù)據(jù)中包含了一年的數(shù)據(jù),即day字段有365個(gè)值芙沥,那么該參數(shù)就需要設(shè)置成大于365诲祸,如果使用默認(rèn)值100,則會(huì)報(bào)錯(cuò)而昨。
set hive.exec.max.dynamic.partitions.pernode=100
(5)文件句柄數(shù):整個(gè)MR Job中救氯,最大可以創(chuàng)建多少個(gè)HDFS文件。
在linux系統(tǒng)當(dāng)中歌憨,每個(gè)linux用戶最多可以開啟1024個(gè)進(jìn)程着憨,每一個(gè)進(jìn)程最多可以打開2048個(gè)文件,即持有2048個(gè)文件句柄躺孝,下面這個(gè)值越大享扔,就可以打開文件句柄越大
set hive.exec.max.created.files=100000;
(6)當(dāng)有空分區(qū)生成時(shí),是否拋出異常植袍。一般不需要設(shè)置惧眠。
set hive.error.on.empty.partition=false;
13.8 分桶
作用:1)便于數(shù)據(jù)取樣;2)對(duì)于join的查詢語(yǔ)句有優(yōu)化的效果
13.9 數(shù)據(jù)傾斜
13.9.1 map數(shù)量
通常情況下于个,作業(yè)會(huì)通過(guò)input的目錄產(chǎn)生一個(gè)或者多個(gè)map任務(wù)氛魁。
影響map數(shù)量的因素:1)基于數(shù)據(jù)塊的數(shù)量;2)文件的數(shù)量;
map的數(shù)量要按照實(shí)際情況定秀存,不是越多越好捶码,也不是越少越好;綜合考慮或链!
在數(shù)據(jù)分析時(shí)惫恼,盡量合理的設(shè)置map的數(shù)量,若一個(gè)大文件澳盐,字段較少祈纯,但是數(shù)據(jù)量較多,此時(shí)map的數(shù)量較少叼耙,會(huì)導(dǎo)致每個(gè)map處理的數(shù)據(jù)很多腕窥,效率很差,解決方案就是增加map的數(shù)量筛婉;
增加map的數(shù)量方案:
set mapreduce.job.reduces =10;
create table a_1 as
select * from a
distribute by rand(123);【對(duì)隨機(jī)數(shù)取余】
文件數(shù)量很多簇爆,但每個(gè)文件內(nèi)的數(shù)據(jù)量較少,此時(shí)會(huì)開啟很多map爽撒,map的開銷時(shí)間遠(yuǎn)遠(yuǎn)會(huì)高于計(jì)算時(shí)間入蛆。導(dǎo)致數(shù)據(jù)量較少但時(shí)間較長(zhǎng)。解決方案---小文件合并硕勿!
13.9.2 reduce的數(shù)量
1)方法一:直接修改參數(shù):set mapreduce.job.reduces = 15
2)方法二:
(1)每個(gè)Reduce處理的數(shù)據(jù)量默認(rèn)是256MB
hive.exec.reducers.bytes.per.reducer=256123456
(2)每個(gè)任務(wù)最大的reduce數(shù)安寺,默認(rèn)為1009
hive.exec.reducers.max=1009
(3)計(jì)算reducer數(shù)的公式
N=min(參數(shù)2,總輸入數(shù)據(jù)量/參數(shù)1)
13.10 并行執(zhí)行
hive將sql轉(zhuǎn)換成mapreduce首尼,程序在執(zhí)行有多個(gè)階段,可以開啟hive的并行執(zhí)行功能言秸。
set hive.exec.parallel=true; //打開任務(wù)并行執(zhí)行
set hive.exec.parallel.thread.number=16; //設(shè)置并行度:同一個(gè)sql允許最大并行度软能,默認(rèn)為8
13.11 嚴(yán)格模式
Hive提供了一個(gè)嚴(yán)格模式,可以防止用戶執(zhí)行“高尉倩”的查詢查排。
嚴(yán)格模式下,一下sql語(yǔ)句不允許執(zhí)行:
1)用戶不允許掃描所有分區(qū)
2)使用了order by語(yǔ)句的查詢抄沮,要求必須使用limit語(yǔ)句
3)限制笛卡爾積的查詢
13.12 JVM重用
mapreduce任務(wù)在運(yùn)行時(shí)跋核,會(huì)開啟大量的JVM,默認(rèn)用完后會(huì)自動(dòng)釋放叛买,新的task需要時(shí)會(huì)重新開啟JVM砂代,JVM頻繁的開啟消耗時(shí)間較多。
開啟JVM重用率挣,一個(gè)JVM結(jié)束后不釋放刻伊,新的task需要時(shí)直接使用,這樣減少了jvm的開啟次數(shù)。從而起到了調(diào)優(yōu)的效果捶箱≈鞘玻【每個(gè)jvm啟動(dòng)的時(shí)間大約1s】
開啟jvm在MapRed-site.xml中添加參數(shù):
<property>
<name>mapreduce.job.jvm.numtasks</name>
<value>10</value>
<description>How many tasks to run per jvm. If set to -1, there is
no limit.
</description>
</property>
也可以在hive當(dāng)中通過(guò):set mapred.job.reuse.jvm.num.tasks=10;這個(gè)設(shè)置來(lái)設(shè)置我們的jvm重用
13.13 推測(cè)執(zhí)行【謹(jǐn)慎使用】
開啟map推測(cè)執(zhí)行:
Hadoop的mapred-site.xml文件中進(jìn)行配置:
<property>
<name>mapreduce.map.speculative</name>
<value>true</value>
<description>If true, then multiple instances of some map tasks
may be executed in parallel.</description>
</property>
<property>
<name>mapreduce.reduce.speculative</name>
<value>true</value>
<description>If true, then multiple instances of some reduce tasks
may be executed in parallel.</description>
</property>
開啟reduce的推測(cè)執(zhí)行:
reduce-side的推測(cè)執(zhí)行:
<property>
<name>hive.mapred.reduce.tasks.speculative.execution</name>
<value>**true**</value>
<description>Whether speculative execution for reducers should be turned on. </description>
</property>