1. 程式人生 > >大資料Hive的案例、引數、動態分割槽、分桶、檢視、索引、執行方式、許可權管理、Hive的優化_03_03

大資料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啟動客戶端時 帶上引數hive --hiveconf hive.cli.print.header=true 那麼在使用引數查詢資料的時候就會出現表頭資訊


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 DELIMITED 
FIELDS 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(至少有一個分割槽列是靜態分割槽)

開啟支援分桶 set hive.enforce.bucketing=true;
預設: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 View
Lateral 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插槽資源!

總結: