Hadoop技術(三)數據倉庫工具Hive

第一章 hive是什麼

博客用到的所有資料都會分享至底部百度雲

一 數據倉庫工具Hive

背景

hadoop生態系統就是爲處理大數據集而產生的一個合乎成本效益的解決方案。hadoop的MapReduce可以將計算任務分割成多個處理單元然後分散到家用的或服務器級別的硬件上,降低成本並提供水平伸縮性。
問題 : 用戶如何從一個現有的數據基礎架構轉移到hadoop上,而這個基礎架構是基於傳統關係型數據庫和SQL的?

介紹

hive是基於Hadoop的一個數據倉庫工具,可以將結構化的數據文件映射爲一張數據庫表,並提供簡單的sql查詢功能,可以將sql語句轉換爲MapReduce任務進行運行。 其優點是學習成本低,可以通過類SQL語句快速實現簡單的MapReduce統計,不必開發專門的MapReduce應用,十分適合數據倉庫的統計分析Hive官方網址

特點

hive提供了HiveQL方言來查詢存儲在hadoop集羣中的數據。hive可以將大多數的查詢轉換爲MapReduce作業。 eg : select * from tb_user

  • hive最適合於數據倉庫,使用數據倉庫進行相關靜態數據分析,而不需要快速響應出結果,而且數據本身不會頻繁變化。
  • hive不是一個完整的數據庫。其中最大的限制就是hive不支持記錄級別的更新、插入或者刪除操作。 但是可以將查詢生成新表或者將查詢結果導入到文件中。
  • hive查詢延時比較嚴重。
  • hive不支持事務。
  • HiveQL並不符合ANSI SQL標準,和Oracle、MySQL、SQL Server支持的常規SQL方言在很多方面存在差異,不過HiveQL和MySQL提供的SQL方言最接近。
  • Apache Hive™數據倉庫軟件有助於讀取,編寫和管理駐留在分佈式存儲中的大型數據集,並使用SQL語法進行查詢。

Hive構建於Apache Hadoop™之上,提供以下功能:

  • 通過SQL輕鬆訪問數據的工具,從而實現數據倉庫任務,如提取/轉換/加載(ETL),報告和數據分析。
  • 一種在各種數據格式上強加結構的機制
  • 訪問直接存儲在Apache HDFS™或其他數據存儲系統(如Apache HBase™)中的文件 hdfs dfs -ls /
  • 通過Apache Tez™,Apache Spark™或MapReduce執行查詢
  • 使用HPL-SQL的過程語言
  • 通過Hive LLAP,Apache YARN和Apache Slider進行亞秒級查詢檢索。

注意:

  • Hive不適用於聯機事務處理(OLTP)工作負載。它最適用於傳統的數據倉庫任務
  • Hive旨在最大限度地提高可伸縮性(通過動態添加到Hadoop集羣中的更多計算機擴展),性能,可擴展性,容錯性以及與其輸入格式的松耦合。
  • Hive的SQL也可以通過用戶定義的函數(UDF),用戶定義的聚合(UDAF)和用戶定義的表函數(UDTF)使用用戶代碼進行擴展。

二 hive架構

用戶接口主要有三個:CLI,Client 和 WebUI(hwi)。

  • CLI: 最常用,Cli啓動的時候,會同時啓動一個Hive副本。
  • Client : Hive的客戶端,用戶連接至Hive Server。在啓動 Client模式的時候,需要指出Hive Server所在節點,並且在該節點啓動Hive Server。
  • WebUI是可以通過瀏覽器訪問Hive的圖形化界面。

在Hadoop 1.x中Hive的架構圖
在這裏插入圖片描述

架構解釋

  • Hive將元數據存儲在數據庫中,如mysql、derby。Hive中的元數據包括表的名字,表的列和分區及其屬性,表的屬性(是否爲外部表等),表的數據所在目錄等。
  • 解釋器、編譯器、優化器完成HQL查詢語句從詞法分析、語法分析、編譯、優化以及查詢計劃的生成。生成的查詢計劃存儲在HDFS中,並在隨後有MapReduce調用執行。
  • Hive的數據存儲在HDFS中,大部分的查詢、計算由MapReduce完成(包含*的查詢,比如select * from tb不會生成MapRedcue任務)
  • 注意
    ① 編譯器將一個Hive SQL轉換操作符
    ② 操作符是Hive的最小的處理單元
    ③ 每個操作符代表HDFS的一個操作或者一個MapReduce作業

在Hadoop 2.x中Hive的架構圖
在這裏插入圖片描述

Hive的架構簡圖
在這裏插入圖片描述
在這裏可以回顧一下Hadoop的相關知識:
1.x job tracker 既管資源調度又管任務分配
2.x 分爲ResourceManager(資源分配)和DataManager(任務分配)
牢記Hadoop 1.x與2.x架構圖

三 Hive執行流程

在這裏插入圖片描述

  1. UI調用驅動程序的執行接口(圖1中的步驟1)。
  2. 驅動程序爲查詢創建會話句柄,並將查詢發送到編譯器以生成執行計劃(步驟2)。
  3. 編譯器從Metastore獲取必要的元數據(步驟3和4)。此元數據用於檢查查詢樹中的表達式以及基於查詢謂詞的修剪分區。
  4. 由編譯器生成的計劃(步驟5)是階段的DAG(有向無環圖),其中每個階段是mapreduce作業或者元數據操作或者對HDFS的操作。對於map/reduce階段,計劃包含map運算符樹(在mapper上執行的運算符樹)和reduce運算符樹(用於需要reducer的操作)。
  5. 執行引擎將這些階段提交給適當的組件(步驟6,6.1,6.2和6.3)。在每個任務(Mapper/Reducer)中,與表或中間輸出相關聯的反序列化器用於從HDFS文件中讀取行,這些行通過關聯的運算符樹傳遞。生成輸出後,它將通過序列化程序寫入臨時HDFS文件(如果操作不需要reducer,則會在mapper中發生)。臨時文件用於向計劃的後續mapreduce階段提供數據。對於DML操作,最終臨時文件將移動到表的位置。此方案用於確保不讀取髒數據(文件重命名是HDFS中的原子操作)。
  6. 對於查詢,執行引擎直接從HDFS讀取臨時文件的內容,作爲來自驅動程序的查詢的一部分(步驟7,8和9)。

antlr詞法語法分析工具解析hql
在這裏插入圖片描述

第二章 Hive的搭建

一 Hive的搭建模式介紹

1.內嵌式

此模式連接到一個In-memory 的數據庫Derby,一般用於Unit Test。(不常用)

在這裏插入圖片描述
2.單用戶模式

又稱遠程數據庫模式 ,hive(node2)和數據庫(node1)不在同一個節點 . 通過網絡連接到一個數據庫中,是最經常使用到的模式

在這裏插入圖片描述

3.多用戶模式

又稱遠程數據庫服務模式, 用於非Java客戶端訪問元數據庫,在服務器端啓動MetaStoreServer,
客戶端利用Thrift協議通過MetaStoreServer訪問元數據庫

在這裏插入圖片描述

二 單用戶模式搭建

node1 :數據源
noed2 :客戶端

# 1. node1安裝mysql
yum install -y mysql-server
# 啓動mysql服務
service mysqld start
# 進入mysql服務 
mysql

# 通過yum安裝的本機可以直接進入而不需要密碼, 所以要修改密碼
# 查看所有系統數據庫
show database;
# 選擇mysql數據庫
use mysql;
# 查看mysql數據庫下的所有系統表(1)
show tables;
# 查詢mysql系統用戶表信息(2) ,我們要根據這裏修改權限信息 . 但是不要直接update修改表,因爲這裏的顯示密碼都是被加密後的字符
select host,user,password from user;
# 授權(讓其他節點能通過 賬號root密碼123 遠程訪問mysql)
grant all privileges on *.* to 'root'@'%' identified by '123' with grant option;
# 刪除本地可以無密碼訪問的賬號(作用是讓我們只能通過賬號密碼才能登陸),然後再次查詢這個表(3)
delete from user where host!='%';
# 刷新權限
flush privileges;

# 退出,重新登,使用mysql進行無密碼登陸測試,然後通過賬號密碼登陸測試
quit;
mysql
mysql -uroot -p123


# 2. 啓動hdfs+zookeeper+yarn集羣環境
# 啓動zookeeper(node2,3,4)
zKserver.sh start
# 啓動hdfs服務(node1)
start-all.sh
# 啓動yarn集羣(node1)
start-yarn.sh
# 啓動resourcemanager(node3,node4主機節點, 並且注意datanode是否啓動)
yarn-daemon.sh start resourcemanager



# 3.安裝Hive
# 解壓並安裝到node2節點 ( 軟件見底部,此後都在node2操作 )
# 配置環境變量 (目的: 1找到可執行文件; 2:方便其他軟件找到hive服務)
export HIVE_HOME=/opt/chy/apache-hive-1.2.1-bin
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_PREFIX/bin:$HADOOP_PREFIX/sbin:$ZOOKEEPER_HOME/bin:$HIVE_HOME/bin

# 重載
. /etc/profile
# 測試環境變量配置是否生效
hive + tab +tab
eg:
[root@node2 apache-hive-1.2.1-bin]# hive
hive            hive-config.sh  hiveserver2  


# 4.修改配置文件(conf目錄下, 配置文件必須改名才能生效)
# 一定要注意修改自己mysql的地址jdbc:mysql://node1:3306/hive_remote?createDatabaseIfNotExist=true
# /user/hive_remote/warehouse :生成的數據庫表存放的hdfs中的目錄
mv hive-default.xml.template hive-site.xml
vi hive-site.xml

-----------------在vi hive-site.xml的configuration標籤中添加如下內容-----------------
<property>  
  <name>hive.metastore.warehouse.dir</name>  
  <value>/user/hive_remote/warehouse</value>  
</property>  
   
<property>
  <name>javax.jdo.option.ConnectionURL</name>
  <value>jdbc:mysql://node1:3306/hive_remote?createDatabaseIfNotExist=true</value>
</property>
   
<property>  
  <name>javax.jdo.option.ConnectionDriverName</name>  
  <value>com.mysql.jdbc.Driver</value>  
</property>  
   
<property>  
  <name>javax.jdo.option.ConnectionUserName</name>  
  <value>root</value>  
</property>  
   
<property>  
  <name>javax.jdo.option.ConnectionPassword</name>  
  <value>123</value>  
</property>  
-----------------在vi hive-site.xml的configuration標籤中添加如下內容-----------------


# 5.將jdbc連接驅動包放入hive的lib目錄下 ( 分享jar見底部 )
cp mysql-connector-java-5.1.32-bin.jar /opt/chy/apache-hive-1.2.1-bin/lib/


# 6.在命令行輸入 hive ,測試能否啓動成功,如果出現下面的異常 ,這說明自己hive的jline和hadoop的jline的jar版本不一致 
Exception in thread "main" java.lang.IncompatibleClassChangeError: Found class jline.Terminal, but interface was expected

# 7.解決辦法: 將高版本的jar複製到低版本的jar上, 並刪除低版本的jar
cd /opt/chy/apache-hive-1.2.1-bin/lib/    #hive的jar所在目錄
cd /opt/chy/hadoop/share/hadoop/yarn/lib/ #hadoop的jar所在目錄

# 圖5,6可以看出hadoop中的 jline-0.9.94.jar 比hive 中的低, 因此刪除hadoop中的jline,並將高版本的jline複製到低版本的jline
rm -f jline-0.9.94.jar 
cp /opt/chy/apache-hive-1.2.1-bin/lib/jline-2.12.jar /opt/chy/hadoop/share/hadoop/yarn/lib/


# 8. 測試是否成功(7),也可以通過hdfs的可視化界面查看
hive

圖1
在這裏插入圖片描述

圖2
在這裏插入圖片描述

圖3 :可以看到只有一個root用戶了
在這裏插入圖片描述

圖4
在這裏插入圖片描述
圖5

在這裏插入圖片描述
圖6
在這裏插入圖片描述
圖7
在這裏插入圖片描述

三 多用戶模式搭建

node1 :MySQL數據庫
node3 服務端
node4 客戶端
在單用戶模式的基礎上搭建,但是與node2上的hive客戶端無關
官方安裝文檔

# 0. 前提
需要安裝mysql數據庫並啓動數據庫服務 service mysqld start

# 1. 在單用戶模式的基礎上, 將配置好的hive的整個文件夾從node2分發到node3,node4對應目錄下
scp -r apache-hive-1.2.1-bin/ node3:`pwd`
scp -r apache-hive-1.2.1-bin/ node4:`pwd`


# 2. 在node3,node4中
## 配置環境變量 (目的: 1找到可執行文件; 2:方便其他軟件找到hive服務)
export HIVE_HOME=/opt/chy/apache-hive-1.2.1-bin
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_PREFIX/bin:$HADOOP_PREFIX/sbin:$ZOOKEEPER_HOME/bin:$HIVE_HOME/bin

## 重載
. /etc/profile
## 測試環境變量配置是否生效
hive + tab +tab
eg:hive +tab鍵+tab鍵
[root@node3 apache-hive-1.2.1-bin]# hive 
hive            hive-config.sh  hiveserver2  


# 3. 修改node3的hive配置文件 
# 爲了便於在hdfs中區分,修改了hive.metastore.warehouse.dir和javax.jdo.option.ConnectionURL下面的路徑,加上了當前節點名稱
-------------------------hive-site.xml--------------------------
<property>
  <name>hive.metastore.warehouse.dir</name>
  <value>/user/hive_remote_node3/warehouse</value>
</property>

<property>
  <name>javax.jdo.option.ConnectionURL</name>
  <value>jdbc:mysql://node1:3306/hive_remote_node3?createDatabaseIfNotExist=true</value>
</property>

<property>
  <name>javax.jdo.option.ConnectionDriverName</name>
  <value>com.mysql.jdbc.Driver</value>
</property>

<property>
  <name>javax.jdo.option.ConnectionUserName</name>
  <value>root</value>
</property>

<property>
  <name>javax.jdo.option.ConnectionPassword</name>
  <value>123</value>
</property>
-------------------------hive-site.xml--------------------------



# 4. 修改node4的hive配置文件.configuration標籤下只有這些內容
-------------------------hive-site.xml--------------------------
<property>
  <name>hive.metastore.warehouse.dir</name>
  <value>/user/hive_remote_node4/warehouse</value>
</property>
<property>
   <name>hive.metastore.uris</name>
   <value>thrift://node3:9083</value>
</property>
-------------------------hive-site.xml--------------------------


# 5. 啓動node3 中的hive ,將其作爲源數據, 但是這種啓動方式是前置啓動 ,佔用當前窗口
hive --service metastore 
## 我們可以另起一個shell窗口.查看端口9083 是否運行 (1)
ss -nal



# 6.在node4中,在命令行輸入 hive ,測試能否啓動成功,如果出現下面的異常 ,這說明自己hive的jline和hadoop的jline的jar版本不一致 
Exception in thread "main" java.lang.IncompatibleClassChangeError: Found class jline.Terminal, but interface was expected

# 6.1.將高版本的jar複製到低版本的jar上
cd /opt/chy/apache-hive-1.2.1-bin/lib/    #hive的jar所在目錄
ls

cd /opt/chy/hadoop/share/hadoop/yarn/lib/ #hadoop的jar所在目錄
ls

# 6.2 可以看出hadoop中的 jline-0.9.94.jar 比hive 中的低, 因此刪除hadoop中的jline,並將高版本的jline複製到低版本的jline
rm -f jline-0.9.94.jar 
cp /opt/chy/apache-hive-1.2.1-bin/lib/jline-2.12.jar /opt/chy/hadoop/share/hadoop/yarn/lib/

# 6.3 測試是否安裝成功,並建表(2)
hive

# 6.4 我們可以訪問hdfs中namenode的圖形化界面查看我們新建的表所存放在哪裏(3) 
# 6.5 我們可以在表中插入數據然後訪問hdfs中namenode的圖形化界面查看我們新建的表中的數據(數據插入時間很漫長~~~後面會優化)

圖1
在這裏插入圖片描述

圖2
在這裏插入圖片描述
圖3
在這裏插入圖片描述

第三章 Hive語法

在第二章中選擇單用戶模式搭建和多用戶模式搭建中的任意一種,進行學習 ,語法基本同數據庫一致
官網語法介紹

一 DDL操作

建庫語法

# 查看所有數據庫
show databases;

# 創建數據庫
create database 數據庫名;

# 使用當前數據庫
use 數據庫名;

# 刪除數據庫
drop database 數據庫名;

建表語法

CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name    -- (Note: TEMPORARY available in Hive 0.14.0 and later)
  [(col_name data_type [column_constraint_specification] [COMMENT col_comment], ... [constraint_specification])]
  [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]
  [SKEWED BY (col_name, col_name, ...)                  -- (Note: Available in Hive 0.10.0 and later)]
     ON ((col_value, col_value, ...), (col_value, col_value, ...), ...)
     [STORED AS DIRECTORIES]
  [
   [ROW FORMAT row_format] 
   [STORED AS file_format]
     | STORED BY 'storage.handler.class.name' [WITH SERDEPROPERTIES (...)]  -- (Note: Available in Hive 0.6.0 and later)
  ]
  [LOCATION hdfs_path]
  [TBLPROPERTIES (property_name=property_value, ...)]   -- (Note: Available in Hive 0.6.0 and later)
  [AS select_statement];   -- (Note: Available in Hive 0.5.0 and later; not supported for external tables)
 
CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
  LIKE existing_table_or_view_name
  [LOCATION hdfs_path];
 
data_type
  : primitive_type
  | array_type
  | map_type
  | struct_type
  | union_type  -- (Note: Available in Hive 0.7.0 and later)
 
primitive_type
  : TINYINT
  | SMALLINT
  | INT
  | BIGINT
  | BOOLEAN
  | FLOAT
  | DOUBLE
  | DOUBLE PRECISION -- (Note: Available in Hive 2.2.0 and later)
  | STRING
  | BINARY      -- (Note: Available in Hive 0.8.0 and later)
  | TIMESTAMP   -- (Note: Available in Hive 0.8.0 and later)
  | DECIMAL     -- (Note: Available in Hive 0.11.0 and later)
  | DECIMAL(precision, scale)  -- (Note: Available in Hive 0.13.0 and later)
  | DATE        -- (Note: Available in Hive 0.12.0 and later)
  | VARCHAR     -- (Note: Available in Hive 0.12.0 and later)
  | CHAR        -- (Note: Available in Hive 0.13.0 and later)
 
array_type
  : ARRAY < data_type >
 
map_type
  : MAP < primitive_type, data_type >
 
struct_type
  : STRUCT < col_name : data_type [COMMENT col_comment], ...>
 
union_type
   : UNIONTYPE < data_type, data_type, ... >  -- (Note: Available in Hive 0.7.0 and later)
 
row_format
  : DELIMITED [FIELDS TERMINATED BY char [ESCAPED BY char]] [COLLECTION ITEMS TERMINATED BY char]
        [MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char]
        [NULL DEFINED AS char]   -- (Note: Available in Hive 0.13 and later)
  | SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value, property_name=property_value, ...)]
 
file_format:
  : SEQUENCEFILE
  | TEXTFILE    -- (Default, depending on hive.default.fileformat configuration)
  | RCFILE      -- (Note: Available in Hive 0.6.0 and later)
  | ORC         -- (Note: Available in Hive 0.11.0 and later)
  | PARQUET     -- (Note: Available in Hive 0.13.0 and later)
  | AVRO        -- (Note: Available in Hive 0.14.0 and later)
  | JSONFILE    -- (Note: Available in Hive 4.0.0 and later)
  | INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname
 
column_constraint_specification:
  : [ PRIMARY KEY|UNIQUE|NOT NULL|DEFAULT [default_value]|CHECK  [check_expression] ENABLE|DISABLE NOVALIDATE RELY/NORELY ]
 
default_value:
  : [ LITERAL|CURRENT_USER()|CURRENT_DATE()|CURRENT_TIMESTAMP()|NULL ] 
 
constraint_specification:
  : [, PRIMARY KEY (col_name, ...) DISABLE NOVALIDATE RELY/NORELY ]
    [, PRIMARY KEY (col_name, ...) DISABLE NOVALIDATE RELY/NORELY ]
    [, CONSTRAINT constraint_name FOREIGN KEY (col_name, ...) REFERENCES table_name(col_name, ...) DISABLE NOVALIDATE 
    [, CONSTRAINT constraint_name UNIQUE (col_name, ...) DISABLE NOVALIDATE RELY/NORELY ]
    [, CONSTRAINT constraint_name CHECK [check_expression] ENABLE|DISABLE NOVALIDATE RELY/NORELY ]

建表舉例

# 創建表psn (內部表)
create table tn_emp
(
id int,
name string,
likes array<string>,  -- 愛好採用數組類型
address map<string,string> -- 地址採取map類型
)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':';


# 查看錶結構以及表信息( 圖1, 可以看到不同類型屬性之間的分隔符 )
desc formatted 表名  

# 插入指定目錄下文件的數據(避免使用insert插入數據帶來的數據緩慢的問題)
load data local inpath '/root/data/data' into table tb_emp;# local :指定的是本地文件目錄



# 創建指定目錄文件data
mkdir /root.data
vi data
-------------------data---------------------------
1,小海,dnf-wzry-programer,csdn:timepause-ah:suzhou
2,小海2,dnf-wzry-programer,csdn:timepause-ah:suzhou
3,小海3,dnf-wzry-programer,csdn:timepause-ah:suzhou
4,小海4,dnf-wzry-programer,csdn:timepause-ah:suzhou
5,小海5,dnf-wzry-programer,csdn:timepause-ah:suzhou
6,小海7,dnf-wzry-programer,csdn:timepause-ah:suzhou
8,小海8,dnf-wzry-programer,csdn:timepause-ah:suzhou
8,小海8,dnf-wzry-programer,csdn:timepause-ah:suzhou
9,小海9,dnf-wzry-programer,csdn:timepause-ah:suzhou
-------------------data---------------------------

# 查看插入的結果( 圖2 )
select * from tb_emp;

圖1
在這裏插入圖片描述

圖2
在這裏插入圖片描述

二 DML操作

官方文檔 : DML操作

Insert

注意:
load data local inpath +本地url into table 表名; 將本地文件數據插入到數據表
load data inpath +hdfs_url into table 表名; 將hdfs文件數據插入到數據表

向數據庫表插入數據的兩種方式

# 1. 通過load data local
load data local inpath '本地文件路徑' into table 表名;


# 2. 通過 from...insert...select
from 有數據的列名
insert overwrite table 無數據的表名(但列名是有數據列的一個或多個)
select1,2...
insert into 另一個無數據的表名
select1,2...


# 舉例: 
## 含有數據的表 (通過上面第一種方式插入數據)
create table tb_emp
(
id int,
name string,
likes array<string>,  -- 愛好採用數組類型
address map<string,string> -- 地址採取map類型
)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':';

## 第一個無數據的表
create table tb_emp6
(
id int,
name string
)
row format delimited
fields terminated by ',';

## 第二個無數據的表
create table tb_emp7
(
id int,
likes array<string>
)
row format delimited
fields terminated by ','
collection items terminated by '-';

## 利用第二種方式插入數據(圖1)
from tb_emp
insert overwrite table tb_emp6
select id,name
insert into tb_emp7
select id,likes

在這裏插入圖片描述
將數據表中的數據寫入到本地文件中

這樣做的目的是形成目錄 ,然後通過目錄在構建數據表 ,不建議使用 ,瞭解即可

# 要寫入的文件目錄一定不能是 /root , 不然會將 /root下的文件覆蓋 ,可以寫成/root/xx
insert overwrite local directory '要寫入的文件目錄'   select * from 表名;

# 舉例(下圖)
hive> insert overwrite local directory '/root/result'
    > select * from tb_emp;

在這裏插入圖片描述

Update

默認不支持事務 ,因此對update操作不友好
我們可以認爲不支持update ,如果想開啓需要手動配置
但是一般不會這樣做 ,都會採用追加並覆蓋的方式

Other DML

  • 清空數據庫表 truncate table 表名(不經過事務)
  • 我們需要知道的是, Hive的所有DML操作都必須經過事務 , 而想要開啓事務必須經過相關的配置,但是不建議開啓

三 內部表

我們可以看到上面例子中我們創建( 正常方式創建 )的就是內部表 ,如下圖

在這裏插入圖片描述

四 外部表

在建表時使用關鍵字 external

創建外部表

# 繼續使用上面的data文件 ,上傳到hdfs的 /usr目錄下
[root@node4 data]# hdfs dfs -mkdir /usr
[root@node4 data]# hdfs dfs -put data /usr/

# 打開hive ,創建外部表
create external table tb_emp2
(
id int,
name string,
likes array<string>,  -- 愛好採用數組類型
address map<string,string> -- 地址採取map類型
)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':'
location '/usr/';    -- 注意: location



# 查看錶的詳細描述信息 (圖1).	EXTERNAL_TABLE 代表外部表
# 而且可以看到 ,通過創建表時用location 指定了表的地址 ,然後該表自動讀取了我們放入這個目錄下的data文件(圖2)

圖1
在這裏插入圖片描述
圖2
在這裏插入圖片描述

刪除表(包括內部表, 外部表)

drop table 表名;

區分內外部表(面試會問) :

  • 創建表時 ,內部表直接存儲在默認的hdfs路徑 .外部表需要自己指定路徑
  • 刪除表時 ,內部表將數據和元數據全部刪除 ,外部表只刪除元數據,HDFS數據不刪除
  • 內部表外部表使用原則
    先有表,後有數據,使用內部表。先有數據,後有表,使用外部表。

注意:

  • 關係數據庫 寫時檢查( mysql / oracle,在我們向數據庫中插入數據時會進行sql語句的檢查 )
  • Hive 讀時檢查(讀取數據時 ,符合規則的才能被讀取到 ,否則爲null ; 作用: 解耦,便於數據讀取)
    # eg: 案例中的定義的表的規則
    row format delimited
    fields terminated by ','
    collection items terminated by '-'
    map keys terminated by ':'
    

五 Hive分區(靜態)

注意:

  • 分區表的意義在於優化查詢( 例如經常按天查詢, 建議按天進行分區 )。
  • 查詢時儘量利用分區字段。如果不使用分區字段,就會全部掃描。
  • 分區屬於元數據,不能通過外部表直接從 HDFS 加載 Hive 中,必須在表定義時指定對應的partition字段
  • 分區列也是一個普通的列 ,也就是說我們書寫了分區列後在建表中不用再寫一次

元數據(Metadata),又稱中介數據、中繼數據,爲描述數據的數據(data about data),主要是描述數據屬性(property)的信息,用來支持如指示存儲位置、歷史數據、資源查找、文件記錄等功能。元數據算是一種電子式目錄,爲了達到編制目錄的目的,必須在描述並收藏數據的內容或特色,進而達成協助數據檢索的目的。

單分區

語法

partitioned by(列名 列類型)

舉例

create table tb_emp3
(
id int,
name string,
likes array<string>,
address map<string,string>
)
partitioned by(age int)
row format delimited 
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':';

查看錶的詳細信息 ( 分區信息,下圖 )
在這裏插入圖片描述

單分區中的DML操作

語法

# 向單分區的數據表中插入data文件中的數據 ,並指定年齡爲10
load data local inpath '/root/data/data' into table 表名 partition(分區列名=分區列的值);

在這裏插入圖片描述

雙分區

理論上分區的個數沒有限制, 但是分區數越多, 在hdfs中創建的目錄越多
找數據會越難找 ,因此建議將需要經常被查詢的字段設置成分區

語法

partitioned by(列名 列類型,列名 列類型...)

舉例

create table tb_emp4
(
id int,
name string,
likes array<string>,
address map<string,string>
)
partitioned by(age int,sex string)
row format delimited 
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':';

查看錶結構詳情
在這裏插入圖片描述

雙分區中的DML操作

添加分區時, 我們必須指定兩個字段
但是在刪除分區, 我們至少指定一個字段即可

官方文檔 : DML操作

語法

# 1.添加分區
# 爲分區列賦值時,與列的順序無關(創建目錄並導入數據 )
load data local inpath '/root/data/data' into table 表名 partition(分區列名=分區列的值,分區列名=分區列的值...);

# 只創建相關分區目錄,不導入數據
alter table 表名 add partition partition(分區列名=分區列的值,分區列名=分區列的值...);


# 2.刪除分區 (至少指定一個字段, 但是對應賦值的都會被刪除!!!)
alter table 表名 drop partition partition(分區列名=分區列的值);

1. 添加分區成功後, 查看錶內容
在這裏插入圖片描述

2. 在HDFS文件系統圖形化界面查看分區表信息

從下圖我們可以看到每個分區目錄下會將我們給分區賦的值創建爲它的子目錄
而我們的表信息就存儲在這些子目錄下

在這裏插入圖片描述
在這裏插入圖片描述

在這裏插入圖片描述

六 Hive SerDe(序列化與反序列化)

Hive SerDe - Serializer and Deserializer
SerDe 用於做序列化和反序列化。
構建在數據存儲和執行引擎之間,對兩者實現解耦。

Hive通過ROW FORMAT DELIMITED以及SERDE進行內容的讀寫。

語法

row_format
: DELIMITED 
          [FIELDS TERMINATED BY char [ESCAPED BY char]] 
          [COLLECTION ITEMS TERMINATED BY char] 
          [MAP KEYS TERMINATED BY char] 
          [LINES TERMINATED BY char] 
: SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value, property_name=property_value, ...)]

舉例( 使用正則只是序列化反序列化的一種手段 )

# 1. 新建一個表logtbl,並指定插入數據的規則
 CREATE TABLE logtbl (
    host STRING,
    identity STRING,
    t_user STRING,
    time STRING,
    request STRING,
    referer STRING,
    agent STRING)
  ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
  WITH SERDEPROPERTIES (
    "input.regex" = "([^ ]*) ([^ ]*) ([^ ]*) \\[(.*)\\] \"(.*)\" (-|[0-9]*) (-|[0-9]*)"
  )
  STORED AS TEXTFILE;


# 2. 在/root/data下創建文件
# log.txt
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-upper.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-nav.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /asf-logo.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-button.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-middle.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET / HTTP/1.1" 200 11217
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET / HTTP/1.1" 200 11217
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /tomcat.css HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /tomcat.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /asf-logo.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /bg-middle.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /bg-button.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] "GET /bg-nav.png HTTP/1.1" 304 -


# 3. 通過load方式加載本地文件向表中插入數據
load data local inpath '/root/data/log.txt' into table logtbl;


# 4.查看數據表, 下圖

在這裏插入圖片描述

七 Hive Beeline

beenline 提供了 JDBC 的訪問方式, 不能用於 DML 操作,只能執行一些查詢操作
Beeline和其他工具有一些不同,執行查詢都是正常的SQL輸入
但是如果是一些管理的命令,比如進行連接,中斷,退出,執行Beeline命令需要帶上“!”,不需要終止符。常用命令介紹:

# 1. beeline的可以使用在內嵌模式,也可以使用再遠程模式,只需要在含有hive工具的虛擬機中啓動hiveserver2便可通過jdbc訪問
# 前置式啓動,阻塞窗口
hiveserver2  



# 2. beeline的使用 !connect jdbc:hive2://url ,url中需要有類似用戶名密碼的字符串,但不一定是用戶名和密碼
## 第一種方式
[root@node4 ~]# beeline
beeline> !connect jdbc:hive2://node3:10000/default root 123
!connect jdbc:hive2://node3:10000/default suibian 123456
### 第一次訪問進入後利用hive查詢當前表(show tables;)可能會報如下異常 ,解決方式是退出重新登陸一下即可
### Error: Error while compiling statement: FAILED: ParseException line 2:5 extraneous input 'tables' expecting EOF near '<EOF>' (state=42000,code=40000)


## 第二種方式 beeline -u  jdbc:hive2://url, url可以不用謝四類用戶名和密碼的字符串
beeline -u  jdbc:hive2://node3:10000/default (-n root:以管理員方式訪問)


## 退出 
!quit  # 直接退出到虛擬機的bash shell
!close # 退出到beeline shell,然後ctrl+c 退出到虛擬機的bash shell

注意:
1. beeline的可以使用在內嵌模式,也可以使用再遠程模式,只需要在含有hive工具的虛擬機中啓動hiveserver2便可通過jdbc訪問
2. 如果想通過jdbc訪問 , 同樣也要有hive的相關jar包
3. 通過這種方式訪問,只能查詢

八 Hive JDBC

測試代碼

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class HiveJdbcClient {

	private static String driverName = "org.apache.hive.jdbc.HiveDriver";

	public static void main(String[] args) throws SQLException {
		try {
			Class.forName(driverName);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		Connection conn = DriverManager.getConnection("jdbc:hive2://node4:10000/default", "root", "");
		Statement stmt = conn.createStatement();
		String sql = "select * from tb_emp limit 5";
		ResultSet res = stmt.executeQuery(sql);
		while (res.next()) {
			System.out.println(res.getString(1) + "-" + res.getString("name"));
		}
	}
}

測試結果
在這裏插入圖片描述

注意 :項目的運行需要有hive的jar包支持, 如下
在這裏插入圖片描述

第四章 Hive函數

一 常用函數

hive函數:官方文檔

舉例

# 查看 tb_emp表中likes列中,數組值爲0的列
 select likes[0] from tb_emp;

# 查看 tb_emp表中address列中,mqp值爲csdn的列
select address['csdn'] from tb_emp;
# 查看 tb_emp表中address列中,mqp值爲csdn , ah的列
select address['csdn'],address['ah'] from tb_emp;

# size函數: 計數
select size(likes),size(address) from tb_emp;

# lpad:填充函數
hive> select lpad(name,30,'@') from tb_emp;
OK
@@@@@@@@@@@@@@@@@@@@@@@@小海
@@@@@@@@@@@@@@@@@@@@@@@小海2
@@@@@@@@@@@@@@@@@@@@@@@小海3
@@@@@@@@@@@@@@@@@@@@@@@小海4
@@@@@@@@@@@@@@@@@@@@@@@小海5
@@@@@@@@@@@@@@@@@@@@@@@小海7
@@@@@@@@@@@@@@@@@@@@@@@小海8
@@@@@@@@@@@@@@@@@@@@@@@小海8
@@@@@@@@@@@@@@@@@@@@@@@小海9


# explode: 將制定列下的值,顯示成一行,然後輸出( 圖1 )
hive> select explode(likes) from tb_emp;

在這裏插入圖片描述

二 自定義函數(案例: 數據脫敏)

以脫敏功能爲例, 演示自定義函數步驟
脫敏 對敏感數據部分進行加密處理:,使其可以被我們用來進行數據分析

三 案例補充:

No1. 實現struct例子(根據要求,在創建表時插入struct類型的數據並查詢)

1.建表

create table student(id int, info struct<name:string, age:int>)
row format delimited
fields terminated by ','
collection items terminated by ':';

2.在本地創建文件

vi stu.txt
-----stu.txt----
1,chx:22
2,xhy:33
3,cxy:44
4,cxx:55
-----stu.txt----

3.插入數據load data local inpath '/root/data/stu.txt' into table student;
4.查詢
在這裏插入圖片描述

No2. 基站掉話率:找出掉線率最高的前10基站

record_time:通話時間
imei:基站編號
cell:手機編號
drop_num:掉話的秒數
duration:通話持續總秒數

1.創建word文本文件,並上傳到hdfs上

# 文件見底部資料分享
cdr.txt

# hdfs 上傳
hdfs dfs -put cdr.txt /user/root/hive/wc

2.創建基站表,存放基站信息


create external table jizhan(
record_time  string,
imei string,
cell string,
ph_num int,
call_num int,
drop_num int,
duration int,
drop_rate int,
net_type string,
erl int
)
row format delimited 
fields terminated by ','
location '/user/hive/cdr';

3 查看數據是否插入成功

 select * from jizhan limit 10;

在這裏插入圖片描述
4.創建掉話率結果表

create table jizhan_result(
imei string,  -- 基站數
drop_num int, -- 掉話數
duration int,  --通話數
drop_rate double -- 掉話率
);

5.統計掉話數,總通話數, 掉話率信息,插入到掉話結果表中

from jizhan
insert into jizhan_result
select imei,sum(drop_num) sdrop,sum(duration) sdura,sum(drop_num)/sum(duration) drate
group by imei 
order by drate desc;

在這裏插入圖片描述

No3. 使用hive實現wordcount

1.創建word文本文件,並上傳到hdfs上

# 文件的生成(內容 hello csdn1-100000 )
for i in `seq 100000`;do echo "hello csdn $i" >> testhive.txt;done 
# hdfs 上傳
hdfs dfs -put testhadoop.txt /user/root/hive/wc

2.創建外部表,location指定該文件 ,作用是將內容插入到數據表中

create external table wc(
line string
)
location '/user/root/hive/wc'

3.表中所有數據平鋪成一列顯示

-- split分割函數. explode將函數體內的字段排成一行
select explode(split(line,' ')) from wc;

4.創建結果表,存放查詢結果

create table wc_result( 
word string,    -- 單詞
ct int			--單詞數
);

5.調用count()函數,對每個單詞分別進行統計,然後通過word進行分組 ,將結果放入結果表

from ( select explode(split(line,' ')) word from wc ) t
insert into wc_result
select word,count(word) group by word;

在這裏插入圖片描述
1.定義函數

需要繼承UDF類
該函數的作用 : 對第一個字符之後的數據進行加密, 用" * "處理

package ah.szxy.hive;

import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;

public class TuoMin extends UDF {

	public Text evaluate(final Text s) {
		if (s == null) {
			return null;
		}
		//substring:包前不包後,也就是說是保留字符串前1字符,後面的用***表示
		String str = s.toString().substring(0, 1) + "***";
		return new Text(str);
	}

}

2.打成jar包並上傳到hdfs指定目錄hdfs dfs -put tm.jar /usr
3.在hive中創建臨時函數(通過指定目錄下的jar)
create temporary function tm as 'ah.szxy.hive.TuoMin' using jar 'hdfs://node1:8020/usr/tm.jar';
4.測試效果select tm(name) from tb_emp;
在這裏插入圖片描述

第五章 拓展功能

一 Hive 參數

在這裏插入圖片描述
注意:

  • hive當中的參數、變量,都是以命名空間開頭
  • 通過${}方式進行引用,其中system、env下的變量必須以前綴開頭

舉例

# hiveconf 類似在xml配置文件進行相關配置 ,不過只在當前會話有效
## hive.cli.header=true 顯示當前數據表的表頭
[root@node2 ~]# hive --hiveconf hive.cli.header=true

## hive命令行下顯示錶頭
hive> set hive.cli.print.header=true;

## 顯示所有設置信息
hive> set;


# 查看相hive幫助(下圖)
hive --help
hive --cli # 顯示hive的cli幫助

# 在hive中未變量賦值
## 方式一
hive --d abc=1
## 方式二
hive --hivevar abc=1
hive> select * from emp where id=${abc};

在這裏插入圖片描述

hive參數初始化配置

當前用戶家目錄下的.hiverc文件
如: ~/.hiverc

如果沒有,可直接創建該文件,將需要設置的參數寫到該文件中,hive啓動運行時,會加載改文件中的配置。

# 例如將這裏的set語句寫入~/.hiverc文件中,則運行時會自動讀取該文件 ,爲我們顯示數據表列名信息
---------------.hiverc-----------------
set hive.cli.print.header=true;

hive歷史操作命令集

# 如果是root用戶.則是在/root目錄下 
cat /root/.hivehistory
# 如果是普通用戶,則是在 /home目錄下
cat /home/.hivehistory

在這裏插入圖片描述

二 hive 動態分區

用於接入離線的數據 ,而不是實時數據

開啓支持動態分區

  • set hive.exec.dynamic.partition=true;
    默認:true
  • 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)

舉例

# 1.創建數據表
create table emp
(
id int,
name string,
age int,
sex string,
likes array<string>,  -- 愛好採用數組類型
address map<string,string> -- 地址採取map類型
)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':';


# 2.用於插入表的數據文件
1,小海1,12,man,dnf-wzry-programer,csdn:timepause-ah:suzhou
2,小海2,13,man,dnf-wzry-programer,csdn:timepause-ah:suzhou
3,小海3,14,man,dnf-wzry-programer,csdn:timepause-ah:suzhou
4,小海4,15,woman,dnf-wzry-programer,csdn:timepause-ah:suzhou
5,小海5,16,man,dnf-wzry-programer,csdn:timepause-ah:suzhou
6,小海7,17,man,dnf-wzry-programer,csdn:timepause-ah:suzhou
8,小海8,11,woman,dnf-wzry-programer,csdn:timepause-ah:suzhou
8,小海8,12,man,dnf-wzry-programer,csdn:timepause-ah:suzhou
9,小海9,11,woman,dnf-wzry-programer,csdn:timepause-ah:suzhou

# 3.將數據導入
load data local inpath '/root/data/data' into table emp;

# 4.創建動態分區數據表
create table emp2
(
id int,
name string,
likes array<string>,  -- 愛好採用數組類型
address map<string,string> -- 地址採取map類型
)
partitioned by(age int,sex string)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':';

# 5,爲動態分區數據表插入數據
## 方式一
from emp
insert into emp2 partition(age ,sex )
select id,name,likes,address,age,sex;
## 方式二
insert into emp2 partition(age ,sex )
select id,name,likes,address,age,sex from emp;

# 6.插入後,可以看到每個分區文件存放分區結果相同的數據存放到同一個文件

注意 : 我們可通過 hdfs dfs -cat 指定目錄(類似下圖) 查看分區下面的數據文件,保存的是分區信息相同的數據
在這裏插入圖片描述

三 hive 分桶

分桶表是對列值取哈希值的方式,將不同數據放到不同文件中存儲。
對於hive中每一個表、分區都可以進一步進行分桶。
由列的哈希值除以桶的個數來決定每條數據劃分在哪個桶中。

  • 適用場景:
    數據抽樣( sampling )

  • 開啓支持分桶set hive.enforce.bucketing=true;
    默認:false;設置爲true之後,mr運行時會根據bucket的個數自動分配reduce task個數。(用戶也可以通過mapred.reduce.tasks自己設置reduce任務個數,但分桶時不推薦使用)

  • 注意:一次作業產生的桶(文件數量)和reduce task個數一致。

  • 往分桶表中加載數據

    insert into table bucket_table select columns from tbl;
    insert overwrite table bucket_table select columns from tbl;
    
  • 分區分桶是相互獨立的, 可以單獨設計

TABLESAMPLE語法:

TABLESAMPLE(BUCKET x OUT OF y)
x:表示從哪個bucket開始抽取數據
y:必須爲該表總bucket數的倍數或因子

TABLESAMPLE舉例
在這裏插入圖片描述

分桶案例實現

  1. 開啓分桶set hive.enforce.bucketing=true;

  2. 創建數據表

    CREATE TABLE stu( id INT, name STRING, age INT)
    ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
    
  3. 數據表中的數據

    1,tom,11
    2,cat,22
    3,dog,33
    4,hive,44
    5,hbase,55
    6,mr,66
    7,alice,77
    8,scala,88
    
  4. 創建分桶表(指定4個分桶)

    CREATE TABLE psnbucket( id INT, name STRING, age INT)
    CLUSTERED BY (age) INTO 4 BUCKETS 
    ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
    
  5. 加載數據:insert into table psnbucket select id, name, age from stu;

  6. 從分桶表抽樣 select id, name, age from psnbucket tablesample(bucket 2 out of 4 on age);

  7. 測試
    在dhfs中查看分桶文件
    在這裏插入圖片描述
    查看該文件的具體內容
    在這裏插入圖片描述
    分桶表信息
    在這裏插入圖片描述
    抽樣結果
    在這裏插入圖片描述

四 hive Lateral View

Lateral View用於和UDTF函數(explode、split)結合來使用。
首先通過UDTF函數拆分成多行,再將多行結果組合成一個支持別名的虛擬表。
主要解決在select使用UDTF做查詢過程中,查詢只能包含單個UDTF,不能包含其他字段、以及多個UDTF的問題

在這裏插入圖片描述

語法:

LATERAL VIEW udtf(expression) tableAlias AS columnAlias (',' columnAlias)

舉例

select  id,myCol1,myCol2,myCol3 from emp 
LATERAL VIEW explode(likes) myTable1 AS myCol1 -- myTable1 表別名, myCol1  列likes別名
LATERAL VIEW explode(address) myTable2 AS myCol2, myCol3;  -- myTable2 表別名, myCol2,myCol3列address別名

在這裏插入圖片描述

五 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 index索引

目的:優化查詢以及檢索性能( 一般在數據量巨大的時候使用 )

  • 創建索引:
create index t1_index on table emp(name) 
as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' with deferred rebuild 
in table t1_index_table;
as:指定索引器;
in table:指定索引表,若不指定默認生成在default__emp_t1_index__表中
  • 查詢索引show index on emp;
  • 重建索引(建立索引之後必須重建索引才能生效)
    ALTER INDEX t1_index ON emp REBUILD;
    
  • 刪除索引DROP INDEX IF EXISTS t1_index ON emp;( 刪除索引後才能刪除索引表 )

舉例

-- 1.存放索引新的表格,指定表存放index
create index t1_index on table emp(name) 
as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' with deferred rebuild 
in table t1_index_table ;  


-- 2.不指定表存放index
create index t2_index on table emp2(name) 
as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' with deferred rebuild;  


-- 3.令索引生效
ALTER INDEX t1_index ON emp REBUILD;

-- 4. 查詢生效後的索引表( 圖1)
select * from t1_index_table;

-- 5. 根據索引表的name屬性查詢對應的信息( 圖2 )
select * from emp where name='小海1';

在這裏插入圖片描述
根據索引表的name屬性查詢對應的信息
在這裏插入圖片描述

第六章 Hive運行方式:

  1. 命令行方式cli:控制檯模式
  2. 腳本運行方式(實際生產環境中用最多)
  3. JDBC方式:hiveserver2
  4. web GUI接口 (hwi、hue等)

一 命令行方式

在這裏插入圖片描述

# 1. hive的cli下dfs命令
## hdfs 查詢文件內容
hdfs dfs -cat /user/hive_remote/warehouse/emp/emp;
## Hive在CLI模式中與hdfs交互 ,執行執行dfs命令
hive> dfs -cat /user/hive_remote/warehouse/emp/emp;



# 2. Hive腳本運行方式:
hive -e ""    						# hive -e: 可以跟多個查詢語句,執行命令後退出hive shell
hive -e "">aaa						# 執行""內hive命令 ,輸出到aaa文件
hive -S -e "">aaa   				# 靜默模式輸出,參數順序不能改
hive -f file 						# 從文件中讀取hive命令(例如 hiveQL語句)
hive -i /home/my/hive-init.sql  	# 讀取初始化hive命令文件 ,執行命令後不會退出 hive shell
hive> source file (在hive cli中運行) # 在hive shell 中執行外部命令文件

二 腳本方式

舉例

  1. 在bash shell中執行查詢數據庫表操作 ,並在腳本中運行

    # 1.編寫腳本
    vim show_emp_table
    ----------------- show_emp_table---------------
    hive -e "select * from emp;"
    ----------------- show_emp_table---------------
    
    # 2.賦予執行權限
    chmod +x hive.sh
    
    # 3. 運行腳本(徐圖)
    ./show_emp_table
    

    在這裏插入圖片描述

  2. 在bash shell中執行查詢數據庫表操作 ,並在腳本中運行,並在另一個文件中輸出( 文本重定向 )

    # 1.修改上個例子show_emp_table文件中的內容
    hive -e "select * from emp;" >>a.txt
    
    # 2.運行,並查看該文件(下圖)
    

    在這裏插入圖片描述

三 JDBC方式:hiveserver2

見第三章 第七節,第八節

四 Hive Web GUI接口

hwi界面安裝:

這裏不建議使用hwi ,因爲查詢結果會疊加顯示,另外操作不方便
更多情況會使用 hue,hue的搭建在後面會提到

下載源碼包apache-hive-*-src.tar.gz
將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 --service hwi
瀏覽器通過以下鏈接來訪問
http://node3: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

hive官方文檔:基於SQL基準的權限授予語法

特點:

  • 完全兼容SQL的授權模型
  • 除支持對於用戶的授權認證,還支持角色role的授權認證
  • role可理解爲是一組權限的集合,通過role爲用戶授權
  • 一個用戶可以具有一個或多個角色
  • 默認包含兩種角色:public、admin

限制:

  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服務端(node3)修改配置文件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>

Hive權限管理

角色的添加、刪除、查看、設置:

  • CREATE ROLE role_name; – 創建角色
  • DROP ROLE role_name; – 刪除角色
  • SET ROLE (role_name|ALL|NONE); – 設置角色
  • SHOW CURRENT ROLES; – 查看當前具有的角色(所有用戶可用)
  • SHOW ROLES; – 查看所有存在的角色(admin/root用戶可用)

使用

# 1. 啓動服務端
[root@node3 conf]# hive --service metastore


# 2.另開一個shell 窗口
[root@node3 ~]# hiveserver2


# 3.通過jdbc方式登入hive的cli (使用的是普通用戶abc,可以隨便寫)
[root@node2 ~]# beeline
beeline> !connect jdbc:hive2://node3:10000/default abc abc


# 4. 測試該角色的權限 (下圖1)
show tables;
show current roles;
create roles test;


# 5.使用root用戶登陸,測試相關權限(2)
[root@node2 ~]# beeline
beeline> !connect jdbc:hive2://node3:10000/default abc abc
## 發現下面命令還是不能夠執行
show  roles;
create roles test;
## 雖然是admin ,但是沒有設置角色所包含的權限,因此需要授予角色權限
set role admin;
## 再次測試發現成功

圖1
在這裏插入圖片描述
圖2
在這裏插入圖片描述

角色管理

授予角色

將一個或多個角色授予其他角色或用戶。
如果指定了“ WITH ADMIN OPTION”,則用戶將獲得將角色授予其他用戶/角色的特權。
如果Grant語句最終在角色之間創建了循環關係,則該命令將失敗並顯示錯誤。

GRANT role_name [, role_name] ...
TO principal_specification [, principal_specification] ...
[ WITH ADMIN OPTION ];
 
principal_specification
  : USER user
  | ROLE role

在這裏插入圖片描述

撤銷角色

在FROM子句中從用戶/角色撤消角色的成員資格。
從Hive 0.14.0開始,可以使用REVOKE ADMIN OPTION FOR (HIVE-6252)撤消ADMIN OPTION 。

REVOKE [ADMIN OPTION FOR] role_name [, role_name] ...
FROM principal_specification [, principal_specification] ... ;
 
principal_specification
  : USER user
  | ROLE role

顯示角色授予

列出已授予給定用戶或角色的所有角色。
當前,任何用戶都可以運行此命令。但這將來可能會改變,以允許用戶僅查看自己的角色授予,並且需要其他特權才能查看其他用戶的角色授予。

SHOW ROLE GRANT (USER|ROLE) principal_name;
principal_name用戶或角色的名稱在哪裏。

在這裏插入圖片描述

管理對象權限

對象授權與撤銷

如果授予用戶對錶或視圖的WITH GRANT OPTION特權,則該用戶還可以授予/撤消其他用戶的特權以及這些對象上的角色。與標準SQL不同,在Hive中,必須在principal_specification中指定USER或ROLE。

-- 授權
GRANT
    priv_type [, priv_type ] ...
    ON table_or_view_name
    TO principal_specification [, principal_specification] ...
    [WITH GRANT OPTION];

--撤消
REVOKE [GRANT OPTION FOR]
    priv_type [, priv_type ] ...
    ON table_or_view_name
    FROM principal_specification [, principal_specification] ... ;


principal_specification
  : USER user
  | ROLE role
  
priv_type
  : INSERT | SELECT | UPDATE | DELETE | ALL

例子:

0: jdbc:hive2://localhost:10000/default> grant select on table secured_table to role my_role;
No rows affected (0.046 seconds)
0: jdbc:hive2://localhost:10000/default> revoke update, select on table secured_table from role my_role;
No rows affected (0.028 seconds)

在這裏插入圖片描述

顯示授權(表)信息

當前,任何用戶都可以運行此命令。但這在將來可能會改變,以允許用戶僅查看自己的特權,並且需要其他特權才能查看其他用戶的特權。

SHOW GRANT [principal_specification] ON (ALL | [TABLE] table_or_view_name);
  
principal_specification
  : USER user
  | ROLE role

在這裏插入圖片描述

第八章 Hive優化

面試很可能會遇到這些問題, 儘量結合真實環境去講解
簡歷,設計,讓面試官通過你的簡歷能夠了解你能學到什麼 ,寫即爲會
而且問的都是你要讓他們問你的東西!!!

  • 核心思想:把Hive SQL 當做Mapreduce程序去優化
  • 以下SQL不會轉爲Mapreduce來執行
    select僅查詢本表字段
    where僅對本表字段做條件過濾
  • Explain 顯示執行計劃 EXPLAIN [EXTENDED] query

一 Hive抓取策略:

Hive中對某些情況的查詢不需要使用MapReduce計算

抓取策略命令

Set hive.fetch.task.conversion=none/more;
# more(默認):開啓此策略
# none : 關閉此策略,即每次執行簡單的sql操作都會進行mr計算操作

二 Hive運行方式:

本地模式

開啓本地模式:

開啓本地模式後,計算會在本地,而不是在集羣中
這樣做的作用是提高hive查詢效率(開發,測試環境常用)

使用

set hive.exec.mode.local.auto=true;

注意:
hive.exec.mode.local.auto.inputbytes.max 默認值爲128M ,表示加載文件的最大值,若大於該配置仍會以集羣方式來運行!

集羣模式

未開啓本地模式之前, 使用的就是集羣模式(默認此模式)

利用集羣模式進行MapReduce計算, 用時如下圖
在這裏插入圖片描述
開啓本地模式之後
可以看到, 開啓本地模式後, sql語句的運行速率提升了很高

在這裏插入圖片描述

並行計算

通過設置以下參數開啓並行模式:

set hive.exec.parallel=true;

注意:
hive.exec.parallel.thread.number;一次SQL計算中允許並行執行的job個數的最大值,默認值爲8

嚴格模式

通過設置以下參數開啓嚴格模式(默認爲:nonstrict非嚴格模式):

set hive.mapred.mode=strict;

查詢限制:

  1. 對於分區表,必須添加where對於分區字段的條件過濾(圖1);
  2. order by語句必須包含limit輸出限制(圖2);
  3. 限制執行笛卡爾積的查詢。
  4. 這些限制的目的是幫助我們提升查詢效率

圖1
在這裏插入圖片描述
圖2
在這裏插入圖片描述

三 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

官方文檔:jion語法

  • 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
    通過修改以下配置啓用自動的mapjoin:

    set hive.auto.convert.join = true;
    

    注意 :

    1. 該參數爲true時,Hive自動對左邊的表統計量,如果是小表就加入內存,即對小表使用Map join
    2. 儘可能使用相同的連接鍵(會轉化爲一個MapReduce作業)

    相關配置參數:

    • hive.mapjoin.smalltable.filesize;
      (大表小表判斷的閾值(約25MB),如果表的大小小於該值則會被加載到內存中運行)
    • 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時,其表的最大值)

五 大表join大表

-Hive優化(面試可能會用)

空key過濾:
有時join超時是因爲某些key對應的數據太多,而相同key對應的數據都會發送到相同的reducer上,從而導致內存不夠。此時我們應該仔細分析這些異常的key,很多情況下,這些key對應的數據是異常數據,我們需要在SQL語句中進行過濾。
空key轉換:
有時雖然某個key爲空對應的數據很多,但是相應的數據不是異常數據,必須要包含在join的結果中,此時我們可以表a中key爲空的字段賦一個隨機的值,使得數據隨機均勻地分不到不同的reducer上

六 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(建議開啓)

七 合併小文件

文件數目小,容易在文件存儲端造成壓力,給hdfs造成壓力,影響效率

設置合併屬性

  • 是否合併map輸出文件:hive.merge.mapfiles=true
  • 是否合併reduce輸出文件:hive.merge.mapredfiles=true;
  • 合併文件的大小:hive.merge.size.per.task=256*1000*1000

去重統計

數據量小的時候無所謂,數據量大的情況下,由於COUNT DISTINCT操作需要用一個Reduce Task來完成,這一個Reduce需要處理的數據量太大,就會導致整個Job很難完成,一般COUNT DISTINCT使用先GROUP BY再COUNT的方式替換

八 控制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插槽資源!


思維導圖總結

直接查看不清晰可保存查看

在這裏插入圖片描述

十 相關資料分享

所有資料分享至百度雲

在這裏插入圖片描述

鏈接:https://pan.baidu.com/s/1AiS2MsA7zheKQk9isXVniw
點贊私聊即可獲取提取碼~~~
提取碼:q838
複製這段內容後打開百度網盤手機App,操作更方便哦

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章