大資料Hive的案例、引數、動態分割槽、分桶、檢視、索引、執行方式、許可權管理、Hive的優化_03_03
一、案例:統計出掉線率最高的前10基站
需求:統計出掉線率最高的前10基站資料:
record_time:通話時間
imei:基站編號
cell:手機編號
drop_num:掉話的秒數
duration:通話持續總秒數
1.建表
create table cell_monitor(
record_time string,
imei string,
cell string,
ph_num int,
call_num int,
drop_num int,
duration int,
drop_rate DOUBLE,
net_type string,
erl string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS TEXTFILE;
結果表
create table cell_drop_monitor(
imei string,
total_call_num int,
total_drop_num int,
d_rate DOUBLE
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE;
載入資料到cell_monitor表
load data local inpath '/usr/local/cdr_summ_imei_cell_info.csv' OVERWRITE INTO TABLE cell_monitor;
找出掉線率最高的基站
from cell_monitor cm
insert overwrite table cell_drop_monitor
select cm.imei ,sum(cm.drop_num),sum(cm.duration),sum(cm.drop_num)/sum(cm.duration) d_rate
group by cm.imei
sort by d_rate desc;
二、Hive案例Wordcount
1、建表
create table docs(line string);
create table wc(word string, totalword int);
2、載入資料
load data local inpath '/usr/local/words' into table docs;
3、統計
from (select explode(split(line, ' ')) as word from docs) w
insert into table wc
select word, count(1) as totalword
group by word
order by word;
4、查詢結果
select * from wc;
三、hive引數
hive 引數、變數
hive當中的引數、變數,都是以名稱空間開頭
名稱空間 |
讀寫許可權 |
含義 |
hiveconf |
可讀寫 |
hive-site.xml當中的各配置變數 例:hive --hiveconf hive.cli.print.header=true |
system |
可讀寫 |
系統變數,包含JVM執行引數等 例:system:user.name=root |
env |
只讀 |
環境變數 例:env:JAVA_HOME |
hivevar |
可讀寫 |
例:hive -d val=key |
hive 引數設定方式
1、修改配置檔案 ${HIVE_HOME}/conf/hive-site.xml
2、啟動hive cli時,通過--hiveconf key=value的方式進行設定
例:hive --hiveconf hive.cli.print.header=true
3、進入cli之後,通過使用set命令設定
hive set命令
在hive CLI控制檯可以通過set對hive中的引數進行查詢、設定
set設定:
set hive.cli.print.header=true;
set檢視
set hive.cli.print.header
hive引數初始化配置
當前使用者家目錄下的.hiverc檔案
如: ~/.hiverc
如果沒有,可直接建立該檔案,將需要設定的引數寫到該檔案中,hive啟動執行時,會載入改檔案中的配置。
hive歷史操作命令集
~/.hivehistory
四、Hive動態分割槽
分割槽的作用:就是把檔案目錄劃分為一個個的子目錄方便對檔案的管理。 開啟支援動態分割槽set hive.exec.dynamic.partition=true;
預設:false
set hive.exec.dynamic.partition.mode=nostrict;
預設:strict(至少有一個分割槽列是靜態分割槽)
相關引數
set hive.exec.max.dynamic.partitions.pernode;
每一個執行mr節點上,允許建立的動態分割槽的最大數量(100)
set hive.exec.max.dynamic.partitions;
所有執行mr節點上,允許建立的所有動態分割槽的最大數量(1000)
set hive.exec.max.created.files;
所有的mr job允許建立的檔案的最大數量(100000)
示例: 建立表 create table psn10(
id int,
name string, sex string, age int,
likes ARRAY<string>,
address MAP<string, string>
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':'; 基礎資料 data3 1,xiaoming1,man,31,book-sleep-mv,beijing:xisanqi-shanghai:pudong
2,xiaoming2,man,32,book-sleep-mv,beijing:xisanqi-shanghai:pudong
3,xiaoming3,girl,20,book-sleep-mv,beijing:xisanqi-shanghai:pudong
4,xiaoming4,girl,22,book-sleep-mv,beijing:xisanqi-shanghai:pudong
5,xiaoming5,man,42,book-sleep-mv,beijing:xisanqi-shanghai:pudong
載入資料到建立的表中 load data local inpath '/usr/local/data3' into table psn10;
接著建立一張分割槽表(分割槽的欄位是sex、age)
create table psn11 (
id int,
name string,
likes ARRAY<string>,
address MAP<string, string>
)
partitioned by (sex string,age int)
ROW FORMAT DELIMITEDFIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':';
開啟支援動態分割槽
set hive.exec.dynamic.partition=true;
預設:false
set hive.exec.dynamic.partition.mode=nostrict;
預設:strict(至少有一個分割槽列是靜態分割槽)
載入資料
from psn10
insert overwrite table psn11 partition(sex, age)
select id, name, likes, address,sex,age distribute by age, sex;
注意載入時資料欄位的順序 ,如果不知道具體的欄位順序,可以使用命令desc psn11,查看錶中欄位的順序。
檢視MapReduce的執行情況
檢視動態分割槽的目錄結構
注意:動態分割槽和靜態分割槽的區別
靜態的分割槽在使用load data...命令載入資料的時候要指定分割槽,同時給分割槽設定值。
動態分割槽載入資料是從已經建立的某個表中的資料資訊中獲取的,其載入的方式使用from insert...(分割槽的欄位是源資料表中的某個欄位)
同時注意載入欄位的順序,與動態分割槽表中的欄位順序一致。
在動態分割槽載入資料前必須通過set命令開啟支援動態分割槽、以及設定分割槽的模式為非嚴格模式。
動態分割槽使用的情形
比如說有一大批資料,我們需要這些資料按照年份、月份、甚至某一天進行分割槽,這樣方便資料的管理。
這個時候我們就會使用動態分割槽的方式來管理這些資料。
五、分桶
hive 分桶分桶表是對列值取雜湊值的方式,將不同資料放到不同檔案中儲存。
對於hive中每一個表、分割槽都可以進一步進行分桶。
由列的雜湊值除以桶的個數來決定每條資料劃分在哪個桶中。
適用場景:
資料抽樣( sampling )、map-join
往分桶表中載入資料
insert into table bucket_table select columns from tbl;
insert overwrite table bucket_table select columns from tbl;
桶表 抽樣查詢
select * from bucket_table tablesample(bucket 1 out of 4 on columns);
TABLESAMPLE語法:
TABLESAMPLE(BUCKET x OUT OF y)
x:表示從哪個bucket開始抽取資料
y:必須為該表總bucket數的倍數或因子 例:
當表總bucket數為32時
TABLESAMPLE(BUCKET 2 OUT OF 16),抽取哪些資料?
共抽取2(32/16)個bucket的資料,抽取第2、第18(16+2)個bucket的資料
TABLESAMPLE(BUCKET 3 OUT OF 256),抽取哪些資料? 抽取第三個桶的1/8資料
示例: 開啟支援分桶 set hive.enforce.bucketing=true;
預設:false;設定為true之後,mr執行時會根據bucket的個數自動分配reduce task個數。(使用者也可以通過mapred.reduce.tasks自己設定reduce任務個數,但分桶時不推薦使用)
注意:一次作業產生的桶(檔案數量)和reduce task個數一致。
CREATE TABLE psn13( id INT, name STRING, age INT) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
測試資料:data4
1,tom,11
2,cat,22
3,dog,33
4,hive,44
5,hbase,55
6,mr,66
7,alice,77
8,scala,88 載入測試資料
load data local inpath '/usr/local/data4' into table psn13;
建立分桶表
CREATE TABLE psnbucket( id INT, name STRING, age INT)
CLUSTERED BY (age) INTO 4 BUCKETS
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
載入源資料資訊到分桶表中
insert into table psnbucket select id, name, age from psn13;
檢視目錄
抽樣
select id, name, age from psnbucket tablesample(bucket 2 out of 4 on age); ####抽取一個桶的資料(4/4)這裡的2是抽取第二個桶的資料。
select id, name, age from psnbucket tablesample(bucket 2 out of 8 on age); ####抽取1/2個桶的資料(4/8)這裡的2是抽取第二個桶的1/2資料。
select id, name, age from psnbucket tablesample(bucket 2 out of 2 on age); ####抽取2個桶的資料(4/2)這裡的2是指從第2、4(2+2)個桶取資料。
總結:
當表總bucket數為32時
TABLESAMPLE(BUCKET 3 OUT OF 16),抽取哪些資料?
1、取多少個桶的資料
桶的個數/Y = 32/16 = 2 個桶
2、X=3 從3個桶開始取資料
第一個 3個桶
第二個 每隔Y=16再取一個桶 16+3=19
當表總bucket數為32時
TABLESAMPLE(BUCKET 3 OUT OF 96),抽取哪些資料?
1、取多少個桶的資料
桶的個數/Y = 32/96 = 1/3 個桶
2、X=3 第3個桶 1/3
六、分割槽的基礎基礎上分桶
為了對資料的更加細化,我們可以將資料在分割槽的基礎上進行分桶。
開啟支援動態分割槽
set hive.exec.dynamic.partition=true;
預設:false
set hive.exec.dynamic.partition.mode=nostrict;
預設:strict(至少有一個分割槽列是靜態分割槽)
預設:false;設定為true之後,mr執行時會根據bucket的個數自動分配reduce task個數。(使用者也可以通過mapred.reduce.tasks自己設定reduce任務個數,但分桶時不推薦使用)
基礎測試資料
11,xiaoming11,man,33,book-sleep-mv,beijing:xisanqi-shanghai:pudong
12,xiaoming12,gril,33,book-sleep-mv,beijing:xisanqi-shanghai:pudong
13,xiaoming13,gril,22,book-sleep-mv,beijing:xisanqi-shanghai:pudong
14,xiaoming14,man,22,book-sleep-mv,beijing:xisanqi-shanghai:pudong
15,xiaoming15,man,33,book-sleep-mv,beijing:xisanqi-shanghai:pudong
16,xiaoming16,man,32,book-sleep-mv,beijing:xisanqi-shanghai:pudong
17,xiaoming17,man,32,book-sleep-mv,beijing:xisanqi-shanghai:pudong
18,xiaoming18,gril,32,book-sleep-mv,beijing:xisanqi-shanghai:pudong
19,xiaoming19,gril,32,book-sleep-mv,beijing:xisanqi-shanghai:pudong
20,xiaoming20,gril,33,book-sleep-mv,beijing:xisanqi-shanghai:pudong
21,xiaoming21,gril,33,book-sleep-mv,beijing:xisanqi-shanghai:pudong
22,xiaoming22,gril,31,book-sleep-mv,beijing:xisanqi-shanghai:pudong
23,xiaoming23,gril,31,book-sleep-mv,beijing:xisanqi-shanghai:pudong
24,xiaoming24,gril,31,book-sleep-mv,beijing:xisanqi-shanghai:pudong
25,xiaoming25,man,31,book-sleep-mv,beijing:xisanqi-shanghai:pudong
26,xiaoming26,man,31,book-sleep-mv,beijing:xisanqi-shanghai:pudong
27,xiaoming27,man,31,book-sleep-mv,beijing:xisanqi-shanghai:pudong
28,xiaoming28,man,33,book-sleep-mv,beijing:xisanqi-shanghai:pudong
29,xiaoming29,man,33,book-sleep-mv,beijing:xisanqi-shanghai:pudong
30,xiaoming30,man,33,book-sleep-mv,beijing:xisanqi-shanghai:pudong
建立源資料表
create table psn14 (
id int,
name string,
sex string,
age int,
likes ARRAY<string>,
address MAP<string, string>
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':';
載入資料
load data local inpath '/usr/local/data5' into table psn14;
建立分割槽分桶表
create table psnbucket2 (
id int,
name string,
age int,
likes ARRAY<string>,
address MAP<string, string>
)
PARTITIONED BY (sex string)
CLUSTERED BY (age) INTO 4 BUCKETS
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':';
載入源資料到分割槽分桶表
from psn14
insert overwrite table psnbucket2 partition(sex)
select id, name, age, likes, address, sex distribute by sex;
七、Hive Lateral View
ive Lateral ViewLateral View用於和UDTF函式(explode、split)結合來使用。
首先通過UDTF函式拆分成多行,再將多行結果組合成一個支援別名的虛擬表。
主要解決在select使用UTF做查詢過程中,查詢只能包含單個UDTF,不能包含其他欄位、以及多個UDTF的問題
語法:
LATERAL VIEW udtf(expression) tableAlias AS columnAlias (',' columnAlias)
八、hive View檢視
和關係型資料庫中的普通檢視一樣,hive也支援檢視
特點:
不支援物化檢視
只能查詢,不能做載入資料操作
檢視的建立,只是儲存一份元資料,查詢檢視時才執行對應的子查詢
view定義中若包含了ORDER BY/LIMIT語句,當查詢檢視時也進行ORDER BY/LIMIT語句操作,view當中定義的優先順序更高
view支援迭代檢視
View語法
建立檢視:
CREATE VIEW [IF NOT EXISTS] [db_name.]view_name
[(column_name [COMMENT column_comment], ...) ]
[COMMENT view_comment]
[TBLPROPERTIES (property_name = property_value, ...)]
AS SELECT ... ;
查詢檢視:
select colums from view;
刪除檢視:
DROP VIEW [IF EXISTS] [db_name.]view_name;
九、Hive 索引
Hive 索引
目的:優化查詢以及檢索效能
建立索引:
create index t1_index on table psn14(name)
as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' with deferred rebuild
in table t1_index_table;
as:指定索引器;
in table:指定索引表,若不指定預設生成在default__psn14_t1_index__表中
create index t1_index on table psn14(name)
as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' with deferred rebuild;
查詢索引
show index on psn2;
重建索引(建立索引之後必須重建索引才能生效)
ALTER INDEX t1_index ON psn14 REBUILD;
刪除索引
DROP INDEX IF EXISTS t1_index ON psn2;
十、Hive的執行方式
Hive執行方式:
命令列方式cli:控制檯模式
指令碼執行方式(實際生產環境中用最多)
JDBC方式:hiveserver2
web GUI介面 (hwi、hue等)
Hive在CLI模式中
與hdfs互動
執行執行dfs命令
例:dfs –ls /
與Linux互動
!開頭
例: !pwd
Hive指令碼執行方式:
hive -e ""
hive -e "">aaa
hive -S -e "">aaa
hive -f file
hive -i /home/my/hive-init.sql
hive> source file (在hive cli中執行)
在/usr/local目錄下建立一個sql檔案
vi sql
select * from psn14 limit 8;
select * from wc ;
然後儲存。
執行指令碼:hive -f /usr/local/sql
Hive GUI介面
Hive Web GUI介面
web介面安裝:
下載原始碼包apache-hive-*-src.tar.gz
在部署hive伺服器的地方設定(也就是weekend11節點上配置)
將hwi war包放在$HIVE_HOME/lib/
製作方法:將hwi/web/*裡面所有的檔案打成war包
cd apache-hive-1.2.1-src/hwi/web
jar -cvf hive-hwi.war *
複製tools.jar(在jdk的lib目錄下)到$HIVE_HOME/lib下
修改hive-site.xml
啟動hwi服務(埠號9999)啟動hive伺服器(weekend11節點上執行)
hive --service hwi
瀏覽器通過以下連結來訪問
http://weekend11:9999/hwi/
修改hive配置檔案hive-site.xml新增以下配置內容:
<property>
<name>hive.hwi.listen.host</name>
<value>0.0.0.0</value>
</property>
<property>
<name>hive.hwi.listen.port</name>
<value>9999</value>
</property>
<property>
<name>hive.hwi.war.file</name>
<value>lib/hive-hwi.war</value>
</property>
此方式體驗度不是很好,不過適合檢視元資料資訊。
十一、Hive許可權管理
Hive 許可權管理
三種授權模型:
1、Storage Based Authorization in the Metastore Server
基於儲存的授權 - 可以對Metastore中的元資料進行保護,但是沒有提供更加細粒度的訪問控制(例如:列級別、行級別)。
2、SQL Standards Based Authorization in HiveServer2
基於SQL標準的Hive授權 - 完全相容SQL的授權模型,推薦使用該模式。
3、Default Hive Authorization (Legacy Mode)
hive預設授權 - 設計目的僅僅只是為了防止使用者產生誤操作,而不是防止惡意使用者訪問未經授權的資料。
Hive - SQL Standards Based Authorization in HiveServer2
完全相容SQL的授權模型
除支援對於使用者的授權認證,還支援角色role的授權認證
role可理解為是一組許可權的集合,通過role為使用者授權
一個使用者可以具有一個或多個角色
預設包含另種角色:public、admin
Hive - SQL Standards Based Authorization in HiveServer2
限制:
1、啟用當前認證方式之後,dfs, add, delete, compile, and reset等命令被禁用。
2、通過set命令設定hive configuration的方式被限制某些使用者使用。
(可通過修改配置檔案hive-site.xml中hive.security.authorization.sqlstd.confwhitelist進行配置)
3、新增、刪除函式以及巨集的操作,僅為具有admin的使用者開放。
4、使用者自定義函式(開放支援永久的自定義函式),可通過具有admin角色的使用者建立,其他使用者都可以使用。
5、Transform功能被禁用。Hive - SQL Standards Based Authorization in HiveServer2
在hive服務端修改配置檔案hive-site.xml新增以下配置內容:
<property>
<name>hive.security.authorization.enabled</name>
<value>true</value>
</property>
<property>
<name>hive.server2.enable.doAs</name>
<value>false</value>
</property>
<property>
<name>hive.users.in.admin.role</name>
<value>root</value>
</property>
<property>
<name>hive.security.authorization.manager</name>
<value>org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactory</value>
</property>
<property>
<name>hive.security.authenticator.manager</name>
<value>org.apache.hadoop.hive.ql.security.SessionStateUserAuthenticator</value>
</property>
服務端啟動hiveserver2;客戶端通過beeline進行連線
Hive許可權管理
角色的新增、刪除、檢視、設定:
CREATE ROLE role_name; -- 建立角色
DROP ROLE role_name; -- 刪除角色
SET ROLE (role_name|ALL|NONE); -- 設定角色
SHOW CURRENT ROLES; -- 檢視當前具有的角色
SHOW ROLES; -- 檢視所有存在的角色
十二、Hive的優化
Hive 優化核心思想:把Hive SQL 當做Mapreduce程式去優化
以下SQL不會轉為Mapreduce來執行
select僅查詢本表字段
where僅對本表字段做條件過濾
Explain 顯示執行計劃
EXPLAIN [EXTENDED] query; #######作用:具體的檢視sql的執行流程。
Hive執行方式:
本地模式
叢集模式 本地模式開啟本地模式:
set hive.exec.mode.local.auto=true;
注意:
hive.exec.mode.local.auto.inputbytes.max預設值為128M
表示載入檔案的最大值,若大於該配置仍會以叢集方式來執行! 平行計算
通過設定以下引數開啟並行模式:
set hive.exec.parallel=true;
注意:hive.exec.parallel.thread.number
(一次SQL計算中允許並行執行的job個數的最大值)
嚴格模式
通過設定以下引數開啟嚴格模式:
set hive.mapred.mode=strict;
(預設為:nonstrict非嚴格模式)
查詢限制:
1、對於分割槽表,必須新增where對於分割槽欄位的條件過濾;
2、order by語句必須包含limit輸出限制;
3、限制執行笛卡爾積的查詢。
Hive排序
Order By - 對於查詢結果做全排序,只允許有一個reduce處理
(當資料量較大時,應慎用。嚴格模式下,必須結合limit來使用)
Sort By - 對於單個reduce的資料進行排序
Distribute By - 分割槽排序,經常和Sort By結合使用
Cluster By - 相當於 Sort By + Distribute By
(Cluster By不能通過asc、desc的方式指定排序規則;
可通過 distribute by column sort by column asc|desc 的方式)
Hive Join
Join計算時,將小表(驅動表)放在join的左邊
Map Join:在Map端完成Join
兩種實現方式:
1、SQL方式,在SQL語句中新增MapJoin標記(mapjoin hint)
語法:
SELECT /*+ MAPJOIN(smallTable) */ smallTable.key, bigTable.value
FROM smallTable JOIN bigTable ON smallTable.key = bigTable.key;
2、開啟自動的MapJoin
Hive Join
自動的mapjoin
通過修改以下配置啟用自動的mapjoin:
set hive.auto.convert.join = true;
(該引數為true時,Hive自動對左邊的表統計量,如果是小表就加入記憶體,即對小表使用Map join)
相關配置引數:
hive.mapjoin.smalltable.filesize;
(大表小表判斷的閾值,如果表的大小小於該值則會被載入到記憶體中執行)
hive.ignore.mapjoin.hint;
(預設值:true;是否忽略mapjoin hint 即mapjoin標記)
hive.auto.convert.join.noconditionaltask;
(預設值:true;將普通的join轉化為普通的mapjoin時,是否將多個mapjoin轉化為一個mapjoin)
hive.auto.convert.join.noconditionaltask.size;
(將多個mapjoin轉化為一個mapjoin時,其表的最大值)
Map-Side聚合
通過設定以下引數開啟在Map端的聚合:
set hive.map.aggr=true;
相關配置引數:
hive.groupby.mapaggr.checkinterval:
map端group by執行聚合時處理的多少行資料(預設:100000)
hive.map.aggr.hash.min.reduction:
進行聚合的最小比例(預先對100000條資料做聚合,若聚合之後的資料量/100000的值大於該配置0.5,則不會聚合)
hive.map.aggr.hash.percentmemory:
map端聚合使用的記憶體的最大值
hive.map.aggr.hash.force.flush.memory.threshold:
map端做聚合操作是hash表的最大可用內容,大於該值則會觸發flush
hive.groupby.skewindata
是否對GroupBy產生的資料傾斜做優化,預設為false
控制Hive中Map以及Reduce的數量
Map數量相關的引數
mapred.max.split.size
一個split的最大值,即每個map處理檔案的最大值
mapred.min.split.size.per.node
一個節點上split的最小值
mapred.min.split.size.per.rack
一個機架上split的最小值
Reduce數量相關的引數
mapred.reduce.tasks
強制指定reduce任務的數量
hive.exec.reducers.bytes.per.reducer
每個reduce任務處理的資料量
hive.exec.reducers.max
每個任務最大的reduce數
Hive - JVM重用
適用場景:
1、小檔案個數過多
2、task個數過多
通過 set mapred.job.reuse.jvm.num.tasks=n; 來設定
(n為task插槽個數)
缺點:設定開啟之後,task插槽會一直佔用資源,不論是否有task執行,直到所有的task即整個job全部執行完成時,才會釋放所有的task插槽資源!