1. Hive基礎
<!-- TOC -->java
<!-- /TOC -->node
Hive基本概念
引入緣由:
- – 對存在HDFS上的文件或HBase中的表進行查詢時,是要手工寫一堆MapReduce碼
- – 對於統計任務,只能由動MapReduce的程序員才能搞定
- – 耗時耗力,更多精力沒有有效的釋放出來
Hive是什麼
-
Hive基於一個統一的查詢分析層,經過SQL語句的方式對HDFS上的數據進行查詢、統計和分析程序員
-
Hive是一個SQL解析引擎,將SQL語句轉譯成MR而後再Hadoop平臺上運行,達到快速開發的目的sql
-
Hive中的表是 純邏輯 表,就只是表的定義等,即表的元數據。本質就是Hadoop的目錄/文件,達到了元數據與數據存儲分離的目的數據庫
-
Hive自己不存儲數據,它徹底依賴HDFS和MapReduce。apache
-
Hive的內容是讀多寫少,不支持對數據的改寫和刪除(0.14版本以後,Hive支持更新刪除功能,但須要手動進行配置 )服務器
-
Hive中沒有定義專門的數據格式,由用戶指定,須要指定三個屬性:分佈式
-
列分隔符oop
- \n****
-
行分隔符優化
- 空格、\t、\001
-
讀取文件數據的方法
- TextFile、SequenceFile(二進制,是hadoop提供的一種二進制文件,<key,value>形式序列化到文件中,java writeable接口進行序列化和反序列化)、RCFile(是Hive專門推出的一種面向列的數據格式)
-
-
爲何選擇Hive
由於簡單!!
select word, count(*) from ( select explode(split(sentence, ' ')) as word from article ) t group by word
-
Hsql與傳統sql區別
Hsql sql 數據存儲 HDFS、 Hbase Local FS 數據格式 用戶自定義 系統決定 數據更新 不支持(把以前的數據覆蓋) 支持 索引 有(0.8版以後增長) 有 執行 MapReduce Executor 執行延遲 高 低 可擴展性 高(UDF、 UDAF,UDTF) 低 數據規模 大(數據大於TB) 小 數據檢查 讀時模式 寫時模式 -
UDF,UDAF,UDTF
-
UDF:直接應用於select語句,一般查詢的時候,須要對字段作一些格式化處理(大小寫轉換),特色:一進一出,1比1
-
UDAF:多對一場景,group by
-
UDTF:一對多場景
-
-
讀時模式 vs 寫時模式
-
讀時模式:只有hive讀的時候纔會檢查、解析字段和schema,優勢:加載數據很迅速,由於在寫的過程當中是不須要解析數據
-
寫時模式:缺點:寫的慢,須要創建一些索引、壓縮、數據一致性、字段檢查等,優勢:讀的時候會獲得優化
-
-
與傳統關係型數據庫特色比較
-
hive和關係數據庫存儲文件的系統不一樣,hive使用的是hadoop的HDFS(hadoop的分佈式文件系統),關係數據庫則是服務器本地的文件系統;
-
hive使用的計算模型是mapreduce,而關係數據庫則是本身設計的計算模型
-
關係數據庫都是爲實時查詢的業務進行設計的,而hive則是爲海量數據作數據挖掘設計的,實時性不好
-
Hive很容易擴展本身的存儲能力和計算能力,這個是繼承hadoop的,而關係數據庫在這個方面要比數據庫差不少。
-
Hive數據管理
四種數據模型
- Table(默認表,也稱內部表)
- External Table(外部表)
- Partition(分區表)
- Bucket(分桶表)
- Hive會針對某一個列進行桶組織,一般對列值作hash
- 優化查詢、方便採樣
Hive內部表和外部表
-
Hive的create建立表的時候,選擇的建立方式:
- create table(內部表)
- create external table(外部表)
-
內部表 vs 外部表
- 差異:在對內部表操做的時候若是經過Hive對錶進行刪除,那麼表結構和表中的數據也會刪除,反之使用外部表的的話作刪除操做時不會刪除數據,只會刪除表結構,
因此儘可能使用外部表
- 差異:在對內部表操做的時候若是經過Hive對錶進行刪除,那麼表結構和表中的數據也會刪除,反之使用外部表的的話作刪除操做時不會刪除數據,只會刪除表結構,
Hive數據類型
-
原生數據類型
- TINYINT
- SMALLINT
- INT
- BIGINT
- BOOLEAN
- FLOAT
- DOUBLE
- STRING
- BINARY(Hive 0.8.0以上纔可用)
- TIMESTAMP(Hive 0.8.0以上纔可用)
-
複合類型
- Arrays:ARRAY<data_type>
- Maps:MAP<primitive_type, data_type>
- Structs:STRUCT<col_name: data_type[COMMENT col_comment],……>
- Union:UNIONTYPE<data_type, data_type,……>
-
複合類型的做用
-
Hive Sql -- join in MR
Hive的優化
Map的優化:
-
– 做業會經過input的目錄產生一個或者多個map任務。 set dfs.block.size(=128)
-
– Map越多越好嗎?是否是保證每一個map處理接近文件塊的大小?
-
– 如何合併小文件,減小map數?
set mapred.max.split.size=100000000; set mapred.min.split.size.per.node=100000000; set mapred.min.split.size.per.rack=100000000; set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHive`InputFormat;
- – 如何適當的增長map數?
set mapred.map.tasks=10;
- – Map端聚合 hive.map.aggr=true ,Mr中的Combiners
Reduce 的優化
-
hive.exec.reducers.bytes.per.reducer;reduce任務處理的數據量
-
調整reduce的個數:
-
設置reduce處理的數據量
-
set mapred.reduce.tasks=10
select pt,count(1) from popt_tbaccountcopy_mes where pt = '2012-07-04' group by pt; 寫成 select count(1) from popt_tbaccountcopy_mes where pt = '2012-07-04';
-
一個Reduce:
-
沒有group by
-
order by(可使用distribute by和sort by)
-
笛卡爾積
分區裁剪(partition)
- – Where中的分區條件,會提早生效,沒必要特地作子查詢,直接Join和GroupBy
笛卡爾積
- – join的時候不加on條件或者無效的on條件,Hive只能使用1個reducer來完成笛卡爾積
Map join
-
/*+ MAPJOIN(tablelist) */,必須是小表,不要超過1G,或者50萬條
-
假設有A表、B表,有A.join(B),若是A表示小表的話,可考慮是否將A表放入到內存中(小表儘可能少於1G),
Union all
-
先作union all再作join或group by等操做能夠有效減小MR過程,儘管是多個Select,最終只有一個mr,數據不去重
-
union操做不會產生重複記錄但效率稍低一些,union all會產生重複數據但效率比union高一些
Multi-insert & multi-group by
-
– 從一份基礎表中按照不一樣的維度,一次組合出不一樣的數據
-
– FROM from_statement
-
– INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1)]select_statement1 group by key1
-
– INSERT OVERWRITE TABLE tablename2 [PARTITION(partcol2=val2 )]select_statement2 group by key2
Automatic merge
-
– 當文件大小比閾值小時,hive會啓動一個mr進行合併
-
– hive.merge.mapfiles = true 是否和並 Map 輸出文件,默認爲 True
-
– hive.merge.mapredfiles = false 是否合併 Reduce 輸出文件,默認爲 False
-
– hive.merge.size.per.task = 25610001000 合併文件的大小
Multi-Count Distinct
-
– 必須設置參數:set hive.groupby.skewindata=true;
-
– select dt, count(distinct uniq_id), count(distinct ip)
-
– from ods_log where dt=20170301 group by dt
Hive優化-- 大小表關聯
-
緣由
- Hive在進行join時,按照join的key進行分發,而在join左邊的表的數據會首先讀入內存,若是左邊表的key相對分散,讀入內存的數據會比較小,join任務執行會比較快;而若是左邊的表key比較集中,而這張表的數據量很大,那麼數據傾斜就會比較嚴重,而若是這張表是小表,則仍是應該把這張表放在join左邊。
-
思路
- 將key相對分散,而且數據量小的表放在join的左邊,這樣能夠有效減小內存溢出錯誤發生的概率
- 使用map join讓小的維度表先進內存。
-
方法
- Small_table join big_table
Hive優化-- 大大表關聯
-
緣由
- 日誌中有一部分的userid是空或者是0的狀況,致使在用user_id進行hash分桶的時候,會將日誌中userid爲0或者空的數據分到一塊兒,致使了過大的斜率。
-
思路
- 把空值的key變成一個字符串加上隨機數,把傾斜的數據分到不一樣的reduce上,因爲null值關聯不上,處理後並不影響最終結果。
-
方法
- on case when (x.uid = '-' or x.uid = '0‘ or x.uid is null) then concat('dp_hive_search',rand()) else x.uid end = f.user_id;