從早期的互聯(lián)網(wǎng)主流大爆發(fā)開始,主要的搜索引擎公司和電子商務(wù)公司就一直在和不斷增長的數(shù)據(jù)進(jìn)行較量因块。最近殴玛,社交網(wǎng)站也遇到了同樣的問題。如今束析,許多組織已經(jīng)意識到他們所收集的數(shù)據(jù)是讓他們了解他們的用戶,提高業(yè)務(wù)在市場上的表現(xiàn)以及提高基礎(chǔ)架構(gòu)效率的一個寶貴的資源憎亚。
Hadoop生態(tài)系統(tǒng)就是為處理如此大數(shù)據(jù)集而產(chǎn)生的一個合乎成本效益的解決方案员寇。Hadoop實(shí)現(xiàn)了一個特別的計算模型,也就是MapReduce第美,其可以將計算任務(wù)分割成多個處理單元然后分散到一群家用的或服務(wù)器級別的硬件機(jī)器上蝶锋,從而降低成本并提供水平可伸縮性。這個計算模型的下面是一個被稱為Hadoop分布式文件系統(tǒng)(HDFS)的分布式文件系統(tǒng)什往。這個文件系統(tǒng)是“可插拔的”扳缕,而且現(xiàn)在已經(jīng)出現(xiàn)了幾個商用的和開源的替代方案。
不過,仍然存在一個挑戰(zhàn)躯舔,那就是用戶如何從一個現(xiàn)有的數(shù)據(jù)基礎(chǔ)架構(gòu)轉(zhuǎn)移到Hadoop上贡必,而這個基礎(chǔ)架構(gòu)是基于傳統(tǒng)關(guān)系型數(shù)據(jù)庫和結(jié)構(gòu)化查詢語句(SQL)的。對于大量的SQL用戶(包括專業(yè)數(shù)據(jù)庫設(shè)計師和管理員庸毫,也包括那些使用SQL從數(shù)據(jù)倉庫中抽取信息的臨時用戶)來說,這時就需要Hive了衫樊。Hive提供了一個被稱為Hive查詢語言(簡稱HiveQL或HQL)的SQL方言飒赃,來查詢存儲在Hadoop集群中的數(shù)據(jù)。
SQL知識分布廣泛的一個原因是:它是一個可以有效地科侈、合理地且直觀地組織和使用數(shù)據(jù)的模型载佳。即使對于經(jīng)驗(yàn)豐富的Java開發(fā)工程師來說,將這些常見的數(shù)據(jù)運(yùn)算對應(yīng)到底層的MapReduce Java API也是令人畏縮的臀栈。Hive可以幫助用戶來做這些苦活蔫慧,這樣用戶就可以集中精力關(guān)注于查詢本身了。Hive可以將大多數(shù)的查詢轉(zhuǎn)換為MapReduce任務(wù)权薯,進(jìn)而在介紹一個令人熟悉的SQL抽象的同時姑躲,拓寬Hadoop的可擴(kuò)展性。
Hive最適合于數(shù)據(jù)倉庫應(yīng)用程序盟蚣,使用該應(yīng)用程序進(jìn)行相關(guān)的靜態(tài)數(shù)據(jù)分析黍析,不需要快速響應(yīng)給出結(jié)果,而且數(shù)據(jù)本身不會頻繁變化屎开。
Hive不是一個完整的數(shù)據(jù)庫阐枣。Hadoop以及HDFS的設(shè)計本身約束和局限性地限制了Hive所能勝任的工作。其中最大的限制就是Hive不支持記錄級別的更新奄抽、插入或者刪除操作蔼两。但是用戶可以通過查詢生成新表或者將查詢結(jié)果導(dǎo)入到文件中。同時逞度,因?yàn)镠adoop是一個面向批處理的系統(tǒng)额划,而MapReduce任務(wù)的啟動過程需要消耗較長的時間,所以Hive查詢延時比較嚴(yán)重档泽。傳統(tǒng)數(shù)據(jù)庫中在秒級別可以完成的查詢锁孟,在Hive中,即使數(shù)據(jù)集相對較小茁瘦,往往也需要執(zhí)行更長的時間品抽。最后需要說明的是,Hive不支持事務(wù)甜熔。因此圆恤,Hive不支持OLTP(聯(lián)機(jī)事務(wù)處理)所需的關(guān)鍵功能,而更接近成為一個OLAP(聯(lián)機(jī)分析技術(shù))工具。但是我們將會看到盆昙,由于Hadoop本身的時間開銷很大羽历,并且Hadoop所被設(shè)計用來處理的數(shù)據(jù)規(guī)模非常大,因此提交查詢和返回結(jié)果是可能具有非常大的延時的淡喜,所以Hive并沒有滿足OLAP中的“聯(lián)機(jī)”部分秕磷,至少目前并沒有滿足。
如果用戶需要對大規(guī)模數(shù)據(jù)使用OLTP功能的話炼团,那么應(yīng)該選擇使用一個NoSQL數(shù)據(jù)庫澎嚣,例如,和Hadoop結(jié)合使用的HBase及Cassandra瘟芝。如果用戶使用的是Amazon彈性MapReduce計算系統(tǒng)(EMR)或者彈性計算云服務(wù)(EC2)的話易桃,也可以使用DynamoDB。用戶甚至可以和這些數(shù)據(jù)庫(還包括其他一些數(shù)據(jù)庫)結(jié)合來使用Hive锌俱。
因此晤郑,Hive是最適合數(shù)據(jù)倉庫應(yīng)用程序的,其可以維護(hù)海量數(shù)據(jù)贸宏,而且可以對數(shù)據(jù)進(jìn)行挖掘造寝,然后形成意見和報告等。因?yàn)榇蠖鄶?shù)的數(shù)據(jù)倉庫應(yīng)用程序是使用基于SQL的關(guān)系型數(shù)據(jù)庫實(shí)現(xiàn)的吭练,所以Hive降低了將這些應(yīng)用程序移植到Hadoop上的障礙匹舞。用戶如果懂得SQL,那么學(xué)習(xí)使用Hive將會很容易线脚。如果沒有Hive赐稽,那么這些用戶就需要去重新學(xué)習(xí)新的語言和新的工具后才能進(jìn)行生產(chǎn)。
同樣地浑侥,相對于其他Hadoop語言和工具來說姊舵,Hive也使得開發(fā)者將基于SQL的應(yīng)用程序移植到Hadoop變得更加容易。不過寓落,和大多數(shù)SQL方言一樣括丁,HiveQL并不符合ANSI SQL標(biāo)準(zhǔn),其和Oracle伶选,MySQL史飞,SQL Server支持的常規(guī)SQL方言在很多方面存在差異(不過,HiveQL和MySQL提供的SQL方言最接近)仰税。
因此构资,本博客商業(yè)智能的《數(shù)據(jù)倉庫Hive編程》系列共有兩個目的。其一陨簇,提供了一個針對所有讀者的介紹吐绵。這個介紹會比較綜合,并且會使用例子來進(jìn)行講解。適用的讀者包括開發(fā)者己单、數(shù)據(jù)庫管理員和架構(gòu)師唉窃,以及其他(如商業(yè)分析師等)非技術(shù)類用戶。其二纹笼,針對開發(fā)者和Hadoop管理員等需要深入了解Hive技術(shù)細(xì)節(jié)的用戶提供了更詳盡的講述纹份,以幫助這些讀者學(xué)習(xí)如何優(yōu)化Hive查詢性能,如何通過用戶自定義函數(shù)和自定義數(shù)據(jù)格式等廷痘,來個性化使用Hive蔓涧。
Hadoop生態(tài)綜述
我們在《Hadoop與Spark等大數(shù)據(jù)框架介紹》介紹了Hadoop生態(tài),這里在以介紹Hive為目再次介紹一下Hadoop生態(tài)牍疏。
MapReduce
雖然用戶無需精通MapReduce就可以使用Hive,但是理解MapReduce的基本原理將幫有助于用戶了解Hive在底層是如何運(yùn)作的拨齐,以及了解如何才能更高效地使用Hive鳞陨。
MapReduce是一種計算模型,該模型可將大型數(shù)據(jù)處理任務(wù)分解成很多單個的瞻惋、可以在服務(wù)器集群中并行執(zhí)行的任務(wù)厦滤。這些任務(wù)的計算結(jié)果可以合并在一起來計算最終的結(jié)果。
MapReduce編程模型是由谷歌(Google)開發(fā)的歼狼。Google通過一篇很有影響力的論文對這個計算模型進(jìn)行了描述掏导,本書附錄部分可查看到該論文,名為《MapReduce:大數(shù)據(jù)之上的簡化數(shù)據(jù)處理》羽峰。一年后趟咆,另一篇名為《Google文件系統(tǒng)》的論文介紹了Google文件系統(tǒng)。這兩篇論文啟發(fā)了道·卡睹诽搿(Doug Cutting)開發(fā)了Hadoop值纱。
MapReduce這個術(shù)語來自于兩個基本的數(shù)據(jù)轉(zhuǎn)換操作:map過程和reduce過程。一個map操作會將集合中的元素從一種形式轉(zhuǎn)換成另一種形式坯汤。在這種情況下虐唠,輸入的鍵-值對會被轉(zhuǎn)換成零到多個鍵-值對輸出。其中惰聂,輸入和輸出的鍵必須完全不同疆偿,而輸入和輸出的值則可能完全不同。
在MapReduce計算框架中搓幌,某個鍵的所有鍵-值對都會被分發(fā)到同一個reduce操作中杆故。確切地說,這個鍵和這個鍵所對應(yīng)的所有值都會被傳遞給同一個Reducer溉愁。reduce過程的目的是將值的集合轉(zhuǎn)換成一個值(例如對一組數(shù)值求和或求平均值)反番,或者轉(zhuǎn)換成另一個集合。這個Reducer最終會產(chǎn)生一個鍵-值對。再次說明一下罢缸,輸入和輸出的鍵和值可能是不同的篙贸。需要說明的是,如果job不需要reduce過程的話枫疆,那么也是可以無reduce過程的爵川。
Hadoop提供了一套基礎(chǔ)設(shè)施來處理大多數(shù)困難的工作以保證任務(wù)能夠執(zhí)行成功。例如息楔,Hadoop決定如果將提交的job分解成多個獨(dú)立的map和reduce任務(wù)來執(zhí)行寝贡,它就會對這些task進(jìn)行調(diào)度并為其分配合適的資源,決定將某個task分配到集群中哪個位置(如果可能值依,通常是這個task所要處理的數(shù)據(jù)所在的位置圃泡,這樣可以最小化網(wǎng)絡(luò)開銷)。它會監(jiān)控每一個task以確保其成功完成愿险,并重啟一些失敗的task颇蜡。
Hadoop分布式文件系統(tǒng)(也就是HDFS),或者一個同類的分布式文件系統(tǒng)辆亏,管理著集群中的數(shù)據(jù)风秤。每個數(shù)據(jù)塊(block)都會被冗余多份(通常默認(rèn)會冗余3份),這樣可以保證不會因單個硬盤或服務(wù)器的損壞導(dǎo)致數(shù)據(jù)丟失扮叨。同時缤弦,因?yàn)槠淠繕?biāo)是優(yōu)化處理非常大的數(shù)據(jù)集,所以HDFS以及類似的文件系統(tǒng)所使用的數(shù)據(jù)塊都非常大彻磁,通常是64MB或是這個值的若干倍碍沐。這么大的數(shù)據(jù)塊可以在硬盤上連續(xù)進(jìn)行存儲,這樣可以保證以最少的磁盤尋址次數(shù)來進(jìn)行寫入和讀取衷蜓,從而最大化提高讀寫性能抢韭。
MapReduce計算框架中的輸入和輸出的基本數(shù)據(jù)結(jié)構(gòu)是鍵值對。當(dāng)Mapper進(jìn)程啟動后恍箭,其將會被頻繁調(diào)用來處理文件中的每行文本刻恭。每次調(diào)用中,傳遞給Mapper的鍵是文檔中這行的
起始位置的字符偏移量扯夭。對應(yīng)的值是這行對應(yīng)的文本鳍贾。
Hive
當(dāng)用戶真正使用Hadoop的API來實(shí)現(xiàn)算法時,甚至有更多的底層細(xì)節(jié)需要用戶自己來控制交洗。這是一個只適用于有經(jīng)驗(yàn)的Java開發(fā)人員的工作骑科,因此也就將Hadoop潛在地放在了一個非程序員用戶無法觸及的位置,即使這些用戶了解他們想使用的算法构拳。
事實(shí)上咆爽,許多這些底層細(xì)節(jié)實(shí)際上進(jìn)行的是從一個任務(wù)到下一個任務(wù)的重復(fù)性工作梁棠,例如,將Mapper和Reducer一同寫入某些數(shù)據(jù)操作構(gòu)造這樣的底層的繁重的工作斗埂,通過過濾得到所需數(shù)據(jù)的操作符糊,以及執(zhí)行類似SQL中數(shù)據(jù)集鍵的連接 (JOIN)操作等。不過幸運(yùn)的是呛凶,存在一種方式男娄,可以通過使用“高級”工具自動處理這些情況來重用這些通用的處理過程。
這也就是引入Hive的原因漾稀。Hive不僅提供了一個熟悉SQL的用戶所能熟悉的編程模型模闲,還消除了大量的通用代碼,甚至是那些有時是不得不使用Java編寫的令人棘手的代碼崭捍。
這就是為什么Hive對于Hadoop是如此重要的原因尸折,無論用戶是DBA還是Java開發(fā)工程師。Hive可以讓你花費(fèi)相當(dāng)少的精力就可以完成大量的工作殷蛇。
有好幾種方式可以與Hive進(jìn)行交互实夹。在《數(shù)據(jù)倉庫Hive編程》系列中,我們將主要關(guān)注于CLI晾咪,也就是命令行界面收擦。對于那些更喜歡圖形用戶界面的用戶贮配,可以使用現(xiàn)在逐步出現(xiàn)的商業(yè)和開源的解決方案谍倦,例如Karmasphere發(fā)布的一個商業(yè)產(chǎn)品,Cloudera提供的開源的Hue項(xiàng)目泪勒,以及Qubole提供的“Hive即服務(wù)”方式等昼蛀。
Hive發(fā)行版中附帶的模塊有CLI,一個稱為Hive網(wǎng)頁界面(HWI)的簡單網(wǎng)頁界面圆存,以及可通過JDBC叼旋、ODBC和一個Thrift服務(wù)器進(jìn)行編程訪問的幾個模塊。
所有的命令和查詢都會進(jìn)入到Driver(驅(qū)動模塊)沦辙,通過該模塊對輸入進(jìn)行解析編譯夫植,對需求的計算進(jìn)行優(yōu)化,然后按照指定的步驟執(zhí)行(通常是啟動多個MapReduce任務(wù)來執(zhí)行)油讯。當(dāng)需要啟動MapReduce任務(wù)時详民,Hive本身是不會生成Java MapReduce算法程序的。相反陌兑,Hive通過一個表示“job執(zhí)行計劃”的XML文件驅(qū)動執(zhí)行內(nèi)置的沈跨、原生的Mapper和Reducer模塊。換句話說兔综,這些通用的模塊函數(shù)類似于微型的語言翻譯程序饿凛,而這個驅(qū)動計算的“語言”是以XML形式編碼的狞玛。
Hive通過和JobTracker通信來初始化MapReduce任務(wù),而不必部署在JobTracker所在的管理節(jié)點(diǎn)上執(zhí)行涧窒。在大型集群中心肪,通常會有網(wǎng)關(guān)機(jī)專門用于部署像Hive這樣的工具。在這些網(wǎng)關(guān)機(jī)上可遠(yuǎn)程和管理節(jié)點(diǎn)上的JobTracker通信來執(zhí)行任務(wù)杀狡。通常蒙畴,要處理的數(shù)據(jù)文件是存儲在HDFS中的,而HDFS是由NameNode進(jìn)行管理的呜象。
Metastore(元數(shù)據(jù)存儲)是一個獨(dú)立的關(guān)系型數(shù)據(jù)庫(通常是一個MySQL實(shí)例)膳凝,Hive會在其中保存表模式和其他系統(tǒng)元數(shù)據(jù)。在我們將詳細(xì)進(jìn)行討論恭陡。
盡管本書是關(guān)于Hive的蹬音,不過還是有必要提及其他的一些高級工具,這樣用戶可以根據(jù)需求進(jìn)行選擇休玩。Hive最適合于數(shù)據(jù)倉庫程序著淆,對于數(shù)據(jù)倉庫程序不需要實(shí)時響應(yīng)查詢,不需要記錄級別的插入拴疤、更新和刪除永部。當(dāng)然,Hive也非常適合于有一定SQL知識的用戶呐矾。不過苔埋,用戶的某些工作可能采用其他的工具會更容易進(jìn)行處理。
Pig
Hive的替代工具中最有名的就是Pig了蜒犯。Pig是由Yahoo!開發(fā)完成的组橄,而同時期Fackbook正在開發(fā)Hive。Pig現(xiàn)在同樣也是一個和Hadoop緊密聯(lián)系的頂級Apache項(xiàng)目罚随。
假設(shè)用戶的輸入數(shù)據(jù)具有一個或者多個源玉工,而用戶需要進(jìn)行一組復(fù)雜的轉(zhuǎn)換來生成一個或者多個輸出數(shù)據(jù)集。如果使用Hive淘菩,用戶可能會使用嵌套查詢(正如我們將看到的)來解決這個問題遵班,但是在某些時刻會需要重新保存臨時表來控制復(fù)雜度。
Pig被描述成一種數(shù)據(jù)流語言潮改,而不是一種查詢語言狭郑。在Pig中,用戶需要寫一系列的聲明語句來定義某些關(guān)系和其他一些關(guān)系之間的聯(lián)系进陡,這里每個新的關(guān)系都會執(zhí)行新的數(shù)據(jù)轉(zhuǎn)換過程愿阐。Pig會查找這些聲明,然后創(chuàng)建一系列有次序的MapReduce任務(wù)趾疚,來對這些數(shù)據(jù)進(jìn)行轉(zhuǎn)換缨历,直到產(chǎn)生符合用戶預(yù)期的計算方式所得到的最終結(jié)果以蕴。
這種步進(jìn)式的數(shù)據(jù)“流”可以比一組復(fù)雜的查詢更加直觀。也因此辛孵,Pig常用于ETL(數(shù)據(jù)抽取丛肮,數(shù)據(jù)轉(zhuǎn)換和數(shù)據(jù)裝載)過程的一部分,也就是將外部數(shù)據(jù)裝載到Hadoop集群中魄缚,然后轉(zhuǎn)換成所期望的數(shù)據(jù)格式宝与。
Pig的一個缺點(diǎn)就是其所使用的定制語言不是基于SQL的。這是可以理解的冶匹,因?yàn)镻ig本身就不是被設(shè)計為一種查詢語言的习劫,但是這也意味著不適合將SQL應(yīng)用程序移植到Pig中,而經(jīng)驗(yàn)豐富的SQL用戶可能需要投入更高的學(xué)習(xí)成本來學(xué)習(xí)Pig嚼隘。然而诽里, Hadoop團(tuán)隊(duì)通常會將Hive和Pig結(jié)合使用,對于特定的工作選擇合適的工具飞蛹。
HBase
如果用戶需要Hive無法提供的數(shù)據(jù)庫特性,如行級別的更新谤狡,快速的查詢響應(yīng)時間,以及支持事務(wù)的話卧檐,就需要考慮HBase了墓懂。 HBase是一個分布式的、可伸縮的數(shù)據(jù)存儲霉囚,其支持行級別的數(shù)據(jù)更新捕仔、快速查詢和行級事務(wù),但其不支持多行事務(wù)佛嬉。
HBase的設(shè)計靈感來自于谷歌的BigTable逻澳,不過HBase并沒有實(shí)現(xiàn)BigTable的所有特性闸天。HBase支持的一個重要特性就是列存儲暖呕,其中的列可以組織成列族。列族在分布式集群中物理上是存儲在一起的苞氮。這就使得當(dāng)查詢場景涉及的列只是所有列的一個子集時湾揽,讀寫速度會快得多。因?yàn)椴恍枰x取所有的行然后丟棄大部分的列笼吟,而是只需讀取需要的列库物。
可以像鍵值存儲一樣來使用HBase,其每一行都使用了一個唯一鍵來提供非炒铮快的速度讀寫這一行的列或者列族戚揭。HBase還會對每個列保留多個版本的值(按照時間戳進(jìn)行標(biāo)記),版本數(shù)量是可以配置的撵枢,因此民晒,如果需要精居,可以“時光倒流”回退到之前的某個版本的值。
HBase使用HDFS(或其他某種分布式文件系統(tǒng))來持久化存儲數(shù)據(jù)潜必。為了可以提供行級別的數(shù)據(jù)更新和快速查詢靴姿,HBase也使用了內(nèi)存緩存技術(shù)對數(shù)據(jù)和本地文件進(jìn)行追加數(shù)據(jù)更新操作日志。持久化文件將定期地使用附加日志更新進(jìn)行更新等操作磁滚。HBase沒有提供類似于SQL的查詢語言佛吓,但是Hive現(xiàn)在已經(jīng)可以和HBase結(jié)合使用了。
Cascading垂攘、Crunch及其他
Apache Hadoop生態(tài)系統(tǒng)之外還有幾個“高級”語言维雇,它們也在Hadoop之上提供了不錯的抽象來減少對于特定任務(wù)的底層編碼工作。為了敘述的完整性晒他,下面我們列舉其中的一些來進(jìn)行介紹谆沃。所有這些都是JVM(Java虛擬機(jī))庫,可用于像Java仪芒、Clojure唁影、Scala、JRuby掂名、Groovy和Jython据沈,而不是像Hive和Pig一樣使用自己的語言工具。
使用這些編程語言既有好處也有弊端饺蔑。它使這些工具很難吸引熟悉SQL的非程序員用戶锌介。不過,對于開發(fā)工程師來說猾警,這些工具提供了圖靈完全的編程語言的完全控制孔祸。Hive和Pig都是圖靈完全性的。當(dāng)我們需要Hive本身沒有提供的額外功能時发皿,我們需要學(xué)習(xí)如何用Java編碼來擴(kuò)展Hive功能崔慧。