zz-hive的基本原理

原文鏈接:http://www.cnblogs.com/uttu/archive/2013/02/28/2936953.html

1、組件:

  元存儲(Metastore )-存儲“系統(tǒng)目錄以及關(guān)于表、列、分區(qū)等的元數(shù)據(jù)”的組件。

  驅(qū)動(dòng)(Driver )- 控制 HiveQL 生命周期的組件,當(dāng) HiveQL 查詢穿過 Hive時(shí)。該驅(qū)動(dòng)管理著會話句柄以及任何會話的統(tǒng)計(jì)。

  查詢編譯器(Query Compiler) - 是一個(gè)組件,將HiveQL編譯成有向無環(huán)圖(directed acyclic graph, DAG)形式的map/reduce任務(wù)。

  執(zhí)行引擎 Execution Engine - 是一個(gè)組件,依相依性順序(dependency order)執(zhí)行由編譯器產(chǎn)生的任務(wù)。

  Hive 服務(wù)器 HiveServer - 一個(gè)提供“健壯的接口(thrift interface )、JDBC/ODBC 服務(wù)器以及提供一種整合 Hive 和其它應(yīng)用的”組件。

  客戶端組件 -類似命令行接口CLI(Command Line Interface), web UI 以及JDBC/ODBC驅(qū)動(dòng)。包含了正反序列化(SerDe)以及對象觀察器(ObjectInspector)接口的可擴(kuò)展接口,類似于前述用戶定義函數(shù) UDF (User Defined Function)以及用戶定義聚合函數(shù)UDAF(User Defined AggregateFunction)接口,允許用戶定義自己的列函數(shù)。

2、執(zhí)行的過程:

  HiveQL通過CLI/web UI或者thrift 、 odbc 或 jdbc接口的外部接口提交,經(jīng)過complier編譯器,運(yùn)用Metastore中的云數(shù)據(jù)進(jìn)行類型檢測和語法分析,生成一個(gè)邏輯方案(logical plan),然后通過簡單的優(yōu)化處理,產(chǎn)生一個(gè)以有向無環(huán)圖DAG數(shù)據(jù)結(jié)構(gòu)形式展現(xiàn)的map-reduce任務(wù)

3、元存儲(Metastore)

  存儲列所有關(guān)于表、表的分區(qū)、模式、列及其類型、表地址等的表的元數(shù)據(jù),可以通過thrift接口查詢得到,由于需要快速的提供到編譯器中,所以使用RDBMS

4、查詢編譯器(query complier)

  用云存儲中的元數(shù)據(jù)來生成執(zhí)行計(jì)劃,步驟如下:

    1).解析(parse)-anlr解析其生成語法樹AST(hibernate也是這個(gè)):將HQL轉(zhuǎn)化為抽象語法樹AST

    2).類型檢查和語法分析(type checking and semantic analysis):將抽象語法樹轉(zhuǎn)換此查詢塊(query block tree),并將查詢塊轉(zhuǎn)換成邏輯查詢計(jì)劃(logic plan Generator);

    3).優(yōu)化(optimization):重寫查詢計(jì)劃(logical optimizer)-->將邏輯查詢計(jì)劃轉(zhuǎn)成物理計(jì)劃(physical plan generator)-->選擇最佳的join策略(physical optimizer)

  parse   sa   ?lpg      ?lo        ppg      ?po

hql------->AST------>QB----->OP TREE------->OP TREE------->task tree------->task tree

  首先進(jìn)行hql語句解析,構(gòu)造一顆AST樹,從AST樹中得到QueryBlock,再將QB轉(zhuǎn)為對應(yīng)的操作符,生成邏輯查詢計(jì)劃,對邏輯查詢計(jì)劃進(jìn)行優(yōu)化(謂詞下推),生成物理查詢計(jì)劃,對物理查詢計(jì)劃進(jìn)行優(yōu)化(MapJoinResolver/SkewJoinResolver/CommonJoinResolver),得到最后的執(zhí)行計(jì)劃。

  MapJoinResolver:將小表的MR結(jié)果放入HashTableFiles-->DistributedCache,大表從分布式緩存中取得數(shù)據(jù)進(jìn)行join;當(dāng)hash數(shù)據(jù)較大時(shí),分布式緩存查詢效率降低,同時(shí)大表的Map都>在等待hash files;所以對其進(jìn)行列優(yōu)化處理小表的結(jié)果放到DC中進(jìn)行壓縮和更新,大表遍歷時(shí)從DC中取出tar包>,然后解壓讀取本地的hash files

  Hive完成列以下轉(zhuǎn)換,作為優(yōu)化階段的一部分:

    1).列剪輯(column pruning):查詢處理中唯一需要的列確實(shí)從行中投射出去

    2).謂語下推(Predicate pushdown):將只于一張表有關(guān)的過濾操作下推至TableScanOperator之后,

    3).分區(qū)剪輯(Partition pruning):過濾掉分區(qū)上不符合條件的字段

    4).Map 端的連接(Map side joins):當(dāng)join的表很小時(shí),在map段先復(fù)制它然后再進(jìn)行join,格式如下:

      SELECT /*+ MAPJOIN(t2) */ t1.c1, t2.c1 FROM t1 JOIN t2 ON(t1.c2 = t2.c2);

      由hive.mapjoin.size.key以及hive.mapjoin.cache.numrows控制“任何時(shí)間保存在內(nèi)存中的”表中行的數(shù)量,以及提供給系統(tǒng)聯(lián)合鍵的大小

    5).連接再排序(Join reordering):把較小的表保存在內(nèi)存中,較大的表進(jìn)行遍歷操作,保證系統(tǒng)內(nèi)存不溢出

5、MapJoin的進(jìn)一步優(yōu)化

  1).數(shù)據(jù)再分區(qū)以把控GROUPBY形成的非對稱(skews):用兩個(gè)MapReduce來做,第一個(gè)階段將數(shù)據(jù)隨機(jī)分發(fā)(或者按DISTINCT列分發(fā)在DISTINCT聚合的情況下)至reducers,并且計(jì)算聚合值;然后這些聚合結(jié)果按照GROUP BY 列分發(fā)給在第二個(gè)Reducer;

    ?set hive.groupby.skewindata= true ;

    SELECT t1.c1, sum(t1.c2)

    FROM t1

    GROUP BY t1.c1;

  2).mappers中的基于哈希的局部聚合:相當(dāng)于combiner,在map端內(nèi)存中進(jìn)行聚合,然后發(fā)送給reducers,參數(shù)hive.map.aggr.hash.percentmemory說明了mapper 內(nèi)存中可用于把控哈希表那部分的數(shù)量。如0.5能確保哈希表大小一旦超過用于mapper的最大內(nèi)存的一半,存儲在那兒的部分聚合就被發(fā)送到reducers了。hive.map.aggr.hash.min.reduction參數(shù)同樣也用來控制用于mappers的內(nèi)存數(shù)量


6、執(zhí)行引擎(execution engine):

  按照任務(wù)的依賴關(guān)系序列來執(zhí)行

7.其它優(yōu)化:

  1).Left Semi Join實(shí)現(xiàn)in/exists子查詢:

    SELECT A.* FROM A LEFT SEMI JOIN B ON(A.KEY = B.KEY AND B.KEY > 100);

    等同于SELECT A.* FROM A WHERE A.KEY IN(SELECT B.KEY FORM B WHERE B.KEY > 100);

    作用:map端用group by減少流入reduce端的數(shù)據(jù)量

  2).Bucket Map Join:

    set hive.optimize.bucketmapjoin = true;

    和Map join一起工作;

    所有join的表都做列分桶,同時(shí)大表桶的數(shù)量是小表桶的整數(shù)倍;

    做bucket的列必須是join的列;

    SELECT /*+MAPJOIN(a,c)*/ a.*, b.*, c.*

    a join b on a.key = b.key

    join c on a.key=c.key;

    在現(xiàn)實(shí)的生產(chǎn)環(huán)境中,會有成百上千個(gè)buckets;

  3).Skew join:

    join時(shí)數(shù)據(jù)傾斜,造成Reduce端OOM

    set hive.optimize.skewjoin = true;

    set hive.skewjoin.key = 閥值;

    當(dāng)JOIN得到的map超過閥值時(shí),將內(nèi)存中的a-k1/b-k1數(shù)據(jù)分別存入hdfs中,然后遍歷完后再對hdfs上的兩塊數(shù)據(jù)做Map Join,和其它key一起組成最后結(jié)果

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容