1. 程式人生 > >Hive 入門

Hive 入門

Hive官網

Hive概述

Hive 的底層執行引擎有 :MapReduce,Tez,Spark - Hive on MapReduce - Hive on Tez - Hive on spark

壓縮:GZIP,LZO,Snappy,Bzip2... 儲存:Textfile,SequenceFile,RcFile,ORC,Parquet UDF:自定義函式

image.png

為什麼要使用Hive: 簡單,容易上手(提供了類SQL的查詢語言HQL) 為超大資料集設計的計算/儲存擴充套件能力(MR計算,HDFS儲存) 統一的元資料管理(可與Pretso/Impala/SparkSQL資料共享)

Hive 的體系結構

1.Hive的元資料

image.png

2.HQL 的執行過程

  • 直譯器、編譯器、優化器完成HQL查詢語句從詞法分析、語法分析、編譯、優化以及查詢計劃(PLAN)的生產,生產的查詢計劃儲存在 HDFS中,並在隨後有MapReduce呼叫執行

image.png

3.體系結構

image.png

image.png

4.Hive 生產環境部署架構

image.png

Hive 安裝

image.png

1.嵌入入模式(元資料儲存在自己維護的dirbe資料庫)

解壓好資料夾後直接進入bin目錄執行hive指令碼
${HIVE_HOME}/bin/hive
複製程式碼

2.本地模式或者遠端模式(元資料儲存在本地或者遠端的mysql庫)

修改hive-site.xml

<!-- jdbc 引數 -->
  <property>
    <name>javax.jdo.option.ConnectionURL</name>
    <value>jdbc:mysql://localhost:3306/hive</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>root</value>
  </property>

複製程式碼

Hive 管理

1.cli模式

# 進入cli
${HIVE_HOME}/bin/hive --service cli

# 1. Hive -S進入靜默模式,不會列印MapReduce作業除錯資訊
# 2. 一般情況下,hive執行SQL都會轉換成MapReduce作業進行執行,但是如果是使用select * 則不會轉換成mr任務
${HIVE_HOME}/bin/hive -S

# 不進入互動模式
${HIVE_HOME}/bin/hive -e {sql語句}

複製程式碼

2.web管理介面模式(只能做查詢)

  1. 進入hive的原始碼目錄的hwi目錄 ${HIVE_SRC_HOME}/hwi

  2. 將其打包編譯 mvn package(需要安裝mvn環境)

  3. 將打好的包放入${HIVE_HOME}/lib/ 目錄下

  4. 修改 hive_site.xml

<!-- web介面監聽的主機地址 -->
  <property>
  <name>hive.hwi.listen.host</name>
  <value>0.0.0.0</value>
  <description>This is the host address the Hive Web Interface will listen on</description>
</property>
 
 <!-- web介面監聽的埠 -->
<property>
  <name>hive.hwi.listen.port</name>
  <value>9999</value>
  <description>This is the port the Hive Web Interface will listen on</description>
</property>
 
 <!-- war包的位置 -->
<property>
  <name>hive.hwi.war.file</name>
  <value>${HIVE_HOME}/lib/hive-hwi-<version>.war</value>
  <description>This is the WAR file with the jsp content for Hive Web Interface</description>
</property>
複製程式碼

6.拷貝jdk目錄下的tools.jar 到hive的lib下

cp ${JAVA_HOME}/lib/tools.jar ${HIVE_HOME}/lib
複製程式碼
  1. 啟動web服務
${HIVE_HOME}/bin/hive --service hwi
複製程式碼

驗證:瀏覽器訪問 http://localhost:9999/hwi/

3.遠端連線

${HIVE_HOME}/bin/hive --service hiveserver
複製程式碼

資料型別

1.基本資料型別

image.png

hive新版本中,新增了兩種字串型別 varchar和char
varchar(20) 最大長度是20 ,可伸縮
char(20) 固定長度20
複製程式碼

2.複雜資料型別

image.png

create table student1
( sid int ,
  sname string,
  score array<float>
)

create table studetnt2
( sid int ,
  sname string,
  score map<string,float>
)

create table student3
( sid int ,
  info struct<name:string,age:int,sex:string>
)
複製程式碼

3.時間型別

image.png

timestamp 與時區無關,是自從有了unix以來的偏移量
date 描述的是特定的日期 YYYY-MM-DD
複製程式碼

資料模型

1.資料儲存

  • 基於HDFS的 預設儲存在 /user/hive/warehouse/
  • 沒有專門的資料儲存格式
sid sname
1 Tom
2 Mary

這張表在檔案中預設儲存為檔案,使用垂直製表符分割

1 Tom
2 Mary
複製程式碼
  • 儲存結構主要包括:資料庫 檔案 表 檢視
  • 可以直接載入文字檔案(.txt等)進行資料新增
  • 建立表時,可以指定Hive資料的列分隔符和行分隔符
    · Table 內部表
    · Partition 分割槽表
    · External 外部表
    · Bucket Table 桶表
複製程式碼

2.詳解表

  • Table 內部表

image.png

create table student1
( sid int ,
  sname string
)
location '${目錄}' 
row format  delimited fields terminated by '列分隔符'
複製程式碼
  • 分割槽表

image.png

create table partition_table
(
    sid int,
    sname string
) 
partitioned by (gender string)
row format  delimited fields terminated by ',';
複製程式碼
  • 外部表

image.png

image.png

create external table partition_table
(
    sid int,
    sname string
) 
row format  delimited fields terminated by ','
location '/input';

-- input 目錄中有相關資料
複製程式碼
  • 桶表

image.png
image.png

create external table partition_table
(
    sid int,
    sname string
) 
clustered by({hash的欄位}) into {桶的數量} buckets

-- input 目錄中有相關資料
複製程式碼

3.檢視

image.png

image.png

Hive 的資料匯入

1.使用load語句匯入

LOAD DATE [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1,partcol2=val2)]
-- [LOCAL] 代表從本地檔案系統匯入,否則從HDFS中匯入
-- [OVERWRITE] 代表覆蓋原有的資料
-- [PARTITION] 代表分割槽
-- 如果filepah是一個檔案則匯入一個檔案的資料,如果是一個目錄,則匯入該目錄下所有的檔案
複製程式碼

2.Sqoop匯入

Sqoop官網

安裝步驟

  1. 下載並解壓
  2. 設定兩個環境變數
# hadoop目錄
export HADOOP_COMMON_HOME='/Users/gaowenfeng/software/hadoop-2.6.0-cdh5.7.0/'
# MP目錄
export HADOOP_MAPRED_HOME='/Users/gaowenfeng/software/hadoop-2.6.0-cdh5.7.0/'
# HIVE 目錄
export HIVE_CONF_HOME='/Users/gaowenfeng/software/hive-1.2.2/'
複製程式碼

3.使用Sqoop匯入Mysql資料到HDFS中

sqoop import --connect {jdbc_url} --username {username} --password {password} --table {table} --columns {col1,col2...} -m {mp程序數} --target-dir {path}
複製程式碼

4.使用Sqoop匯入Mysql資料Hive中

# 如果不指定表名,會在hive找那個建立一張表,表名與源表名一樣
sqoop import --hive-import --connect {jdbc_url} --username {username} --password {password} --table {table} --columns '{col1,col2...}' -m {mp程序數} --columns '{col1,col2...}' --table {target_table} --where '{where條件}' 
複製程式碼

5.使用Sqoop匯入Mysql資料到Hive中並使用查詢

# 如果不指定表名,會在hive找那個建立一張表,表名與源表名一樣
sqoop import --hive-import --connect {jdbc_url} --username {username} --password {password} --table {table} --columns '{col1,col2...}' -m {mp程序數} --columns '{col1,col2...}' --table {target_table} --query 'sql語句'

# sql語句必須有 and $CONDITIONS
複製程式碼

Hive 調優

-- 動態分割槽,根據插入的記錄自動分割槽
SET hive.exec.dynamic.partition=true;
SET hive.exec.dynamic.partition.mode=nonstrict;
-- 並行執行,子查詢可以並行執行
SET hive.exec.parallel=true;
-- 計算結束以後將小檔案合併
SET hive.merge.mapredfiles=true;
-- 如果某個維表小於100000000B(100M),就做MAP關聯,不用到reduce階段
SET hive.mapjoin.smalltable.filesize=100000000;
-- 超時時間
SET mapred.task.timeout=1800000;
-- 新增自定義jar包
ADD jar viewfs://hadoop-meituan/user/hadoop-hotel/user_upload/gaowenfeng02_hive-udf-zhaoxiang.jar;
-- 建立UDF
CREATE TEMPORARY FUNCTION get_tag_list as 'com.meituan.hive.udf.common.ResolveTagUdf';

-- map jvm記憶體設定3G
-- SET mapred.map.child.java.opts="-Xmx3072m"; 
-- map task 的記憶體 約等於4G
-- SET mapreduce.map.memory.mb=4000;
-- reduce jvm記憶體設定3G
-- SET mapred.reduce.child.java.opts="-Xmx3072m";
-- reduce task 的記憶體 約等於4G
-- SET mapreduce.reduce.memory.mb=4000;
複製程式碼

Hive教程:www.yiibai.com/hive/

ETL的優化

hive.exec.reducers.bytes.per.reducer    這個引數控制一個job會有多少個reducer來處理,依據的是輸入檔案的總大小。預設1GB。(即每個reduce任務處理的資料量。)

hive.exec.reducers.max     這個引數控制最大的reducer的數量, 如果 input / bytes per reduce > max  則會啟動這個引數所指定的reduce個數。  這個並不會影響mapre.reduce.tasks引數的設定。預設的max是999。

mapred.reduce.tasks  這個引數如果指定了,hive就不會用它的estimation函式來自動計算reduce的個數,而是用這個引數來啟動reducer。預設是-1.

reduce的個數設定其實對執行效率有很大的影響: 1、如果reduce太少: 如果資料量很大,會導致這個reduce異常的慢,從而導致這個任務不能結束,也有可能會OOM 2、如果reduce太多: 產生的小檔案太多,合併起來代價太高,namenode的記憶體佔用也會增大。

如果我們不指定mapred.reduce.tasks, hive會自動計算需要多少個reducer。 計算的公式:  reduce個數 =  InputFileSize   /   bytes per reducer

mapreduce.map.memory.mb    每個Map Task需要的記憶體量 mapreduce.reduce.memory.mb    每個Reduce Task需要的記憶體量

檢視任務執行的日誌: XT平臺生產運維欄目中,排程管理下的執行日誌 測試引數:

  • -delta 1 -v

測試的表名:ba_hotel_test.topic_log_mt_order_trade_entrance 線上的表名:ba_hotel.topic_log_mt_order_trade_entrance 測試流量:頁面流量,模組流量(某個頁面之前前的頁面流量一定是大於該頁面的流量)

任務流程—測試及上線: 測試完再上線,測試包括線下測試和線上測試 提交稽核,稽核通過後就自動上線了 在XT平臺中,該任務下點執行計劃,再進行線上測試

map、reduce java程式碼講解 ba_hotel.topic_log_mt_order_trade_entrance.mpt_track ba_hotel.topic_log_mt_order_trade_entrance.patch_track ba_hotel.topic_log_mt_order_trade_entrance.mge_track

ba_travel.topic_log_tag_moudle fact_log_tag_pv

優化排查: 1.最後一個map少,時間長 2.reduce一直在99%,發生了資料傾斜 3.job交接時間長,說明碎片多

優化: 1.ETL語句執行問題:問Hadoop小客服 2.子查詢,精簡資料 3.子查詢之間的關聯,是否資料傾斜 4.引數調高

測試程式碼: 線上庫: select count(uuid),       count(DISTINCT uuid)  from ba_hotel.topic_log_mt_order_trade_entrance where datekey='20180422'   and partition_entrance_type= 'mpt' limit 10 測試庫: select count(uuid),       count(DISTINCT uuid)  from ba_hotel_test.topic_log_mt_order_trade_entrance where datekey='20180422'   and partition_entrance_type= 'mpt'