大數(shù)據(jù)生態(tài)圈到底是一個(gè)什么概念?
大數(shù)據(jù)這個(gè)概念本身就太大而且太寬,如果一定要嚴(yán)格定義是非常困難的一件事,不過(guò)Hadoop生態(tài)圈或者由其延伸的泛生態(tài)系統(tǒng),基本上都是為了處理大量數(shù)據(jù)誕生的——一般而言,這種數(shù)據(jù)依賴(lài)單機(jī)很難完成。
這個(gè)圈子里的工具,就像是我們廚房里的各種廚具——各自都有不同的用處,但也有一部分功能重合,比如盆和豌都可以用來(lái)喝湯,削皮刀和菜刀都可以用來(lái)去皮。
但是,盆用來(lái)喝湯未免奇怪,削皮刀切菜也是萬(wàn)萬(wàn)不能。即使你強(qiáng)行要?jiǎng)?chuàng)造一些奇異的組合,即使最終完成工作,卻不一定是最快、最好的選擇。
大數(shù)據(jù),首先你要能存的下大數(shù)據(jù)。
對(duì)傳統(tǒng)的單機(jī)文件系統(tǒng)來(lái)說(shuō),橫跨不同機(jī)器幾乎是不可能完成的任務(wù)。而通過(guò)HDFS(Hadoop Distributed FileSystem),你可以通過(guò)橫跨上千甚至上萬(wàn)臺(tái)機(jī)器來(lái)完成大量數(shù)據(jù)得存儲(chǔ),同時(shí)這些數(shù)據(jù)全部都能歸屬在同一個(gè)文件系統(tǒng)之下。你可以通過(guò)引用一個(gè)文件路徑獲取存儲(chǔ)在許多臺(tái)機(jī)器上的數(shù)據(jù)文件。作為一個(gè)使用者,你完全不用去計(jì)較文件具體存儲(chǔ)的位置,這個(gè)文件系統(tǒng)會(huì)為你搞定一切。
我們當(dāng)然不是為了搜集數(shù)據(jù)而進(jìn)行存儲(chǔ),我們還要用數(shù)據(jù)做一些事情。雖然我們通過(guò)HDFS存下了橫跨上千臺(tái)機(jī)器的數(shù)據(jù),我們依然面臨一個(gè)問(wèn)題——這些數(shù)據(jù)過(guò)于龐大,如果只交給一臺(tái)機(jī)器處理,我們可能得等上幾周甚至更長(zhǎng)。這些可能以T甚至于P來(lái)計(jì)量單位的數(shù)據(jù),只靠一臺(tái)機(jī)器真的能跑到地老天荒。
對(duì)于很多公司,這是無(wú)法接受的事情——我們都知道有各種熱度排行,加入一臺(tái)機(jī)器處理這個(gè)數(shù)據(jù)、計(jì)算熱度、進(jìn)行發(fā)布,可能一周之后出來(lái)結(jié)果,但大家早已經(jīng)不關(guān)心了。
所以使用大量機(jī)器進(jìn)行處理是必然的選擇。在大量機(jī)器處理過(guò)程中,必須處理一些事務(wù):任務(wù)分配、緊急情況處理、信息互通等等,這時(shí)候必須引入MapReduce / Tez / Spark 。這其中,前者可以成為計(jì)算引擎的第一代產(chǎn)品,后兩者則是經(jīng)過(guò)優(yōu)化后的下一代。MapReduce采用了非常簡(jiǎn)單的計(jì)算模型設(shè)計(jì),可以說(shuō)只用了兩個(gè)計(jì)算的處理過(guò)程,但是這個(gè)工具已經(jīng)足夠應(yīng)付大部分的大數(shù)據(jù)工作了。
什么是Map?什么是Reduce?
考慮如果你要統(tǒng)計(jì)一個(gè)巨大的文本文件存儲(chǔ)在類(lèi)似HDFS上,你想要知道這個(gè)文本里各個(gè)詞的出現(xiàn)頻率。你啟動(dòng)了一個(gè)MapReduce程序。Map階段,幾百臺(tái)機(jī)器同時(shí)讀取這個(gè)文件的各個(gè)部分,分別把各自讀到的部分分別統(tǒng)計(jì)出詞頻,產(chǎn)生類(lèi)似
(hello, 12100次),(world,15214次)等等這樣的Pair(我這里把Map和Combine放在一起說(shuō)以便簡(jiǎn)化);這幾百臺(tái)機(jī)器各自都產(chǎn)生了如上的集合,然后又有幾百臺(tái)機(jī)器啟動(dòng)Reduce處理。Reducer機(jī)器A將從Mapper機(jī)器收到所有以A開(kāi)頭的統(tǒng)計(jì)結(jié)果,機(jī)器B將收到B開(kāi)頭的詞匯統(tǒng)計(jì)結(jié)果(當(dāng)然實(shí)際上不會(huì)真的以字母開(kāi)頭做依據(jù),而是用函數(shù)產(chǎn)生Hash值以避免數(shù)據(jù)串化。因?yàn)轭?lèi)似X開(kāi)頭的詞肯定比其他要少得多,而你不希望數(shù)據(jù)處理各個(gè)機(jī)器的工作量相差懸殊)。然后這些Reducer將再次匯總,(hello,12100)+(hello,12311)+(hello,345881)= (hello,370292)。每個(gè)Reducer都如上處理,你就得到了整個(gè)文件的詞頻結(jié)果。
這看似是個(gè)很簡(jiǎn)單的模型,但很多算法都可以用這個(gè)模型描述了。
Map+Reduce的簡(jiǎn)單模型很黃很暴力,雖然好用,但是很笨重。第二代的Tez和Spark除了內(nèi)存Cache之類(lèi)的新feature,本質(zhì)上來(lái)說(shuō),是讓Map/Reduce模型更通用,讓Map和Reduce之間的界限更模糊,數(shù)據(jù)交換更靈活,更少的磁盤(pán)讀寫(xiě),以便更方便地描述復(fù)雜算法,取得更高的吞吐量。
有了MapReduce,Tez和Spark之后,程序員發(fā)現(xiàn),MapReduce的程序?qū)懫饋?lái)真麻煩。他們希望簡(jiǎn)化這個(gè)過(guò)程。這就好比你有了匯編語(yǔ)言,雖然你幾乎什么都能干了,但是你還是覺(jué)得繁瑣。你希望有個(gè)更高層更抽象的語(yǔ)言層來(lái)描述算法和數(shù)據(jù)處理流程。于是就有了Pig和Hive。Pig是接近腳本方式去描述MapReduce,Hive則用的是SQL。它們把腳本和SQL語(yǔ)言翻譯成MapReduce程序,丟給計(jì)算引擎去計(jì)算,而你就從繁瑣的MapReduce程序中解脫出來(lái),用更簡(jiǎn)單更直觀的語(yǔ)言去寫(xiě)程序了。
有了Hive之后,人們發(fā)現(xiàn)SQL對(duì)比Java有巨大的優(yōu)勢(shì)。一個(gè)是它太容易寫(xiě)了。剛才詞頻的東西,用SQL描述就只有一兩行,MapReduce寫(xiě)起來(lái)大約要幾十上百行。而更重要的是,非計(jì)算機(jī)背景的用戶(hù)終于感受到了愛(ài):我也會(huì)寫(xiě)SQL!于是數(shù)據(jù)分析人員終于從乞求工程師幫忙的窘境解脫出來(lái),工程師也從寫(xiě)奇怪的一次性的處理程序中解脫出來(lái)。大家都開(kāi)心了。Hive逐漸成長(zhǎng)成了大數(shù)據(jù)倉(cāng)庫(kù)的核心組件。甚至很多公司的流水線作業(yè)集完全是用SQL描述,因?yàn)橐讓?xiě)易改,一看就懂,容易維護(hù)。
自從數(shù)據(jù)分析人員開(kāi)始用Hive分析數(shù)據(jù)之后,它們發(fā)現(xiàn),Hive在MapReduce上跑,真雞巴慢!流水線作業(yè)集也許沒(méi)啥關(guān)系,比如24小時(shí)更新的推薦,反正24小時(shí)內(nèi)跑完就算了。但是數(shù)據(jù)分析,人們總是希望能跑更快一些。比如我希望看過(guò)去一個(gè)小時(shí)內(nèi)多少人在充氣娃娃頁(yè)面駐足,分別停留了多久,對(duì)于一個(gè)巨型網(wǎng)站海量數(shù)據(jù)下,這個(gè)處理過(guò)程也許要花幾十分鐘甚至很多小時(shí)。而這個(gè)分析也許只是你萬(wàn)里長(zhǎng)征的第一步,你還要看多少人瀏覽了跳蛋多少人看了拉赫曼尼諾夫的CD,以便跟老板匯報(bào),我們的用戶(hù)是猥瑣男悶騷女更多還是文藝青年/少女更多。你無(wú)法忍受等待的折磨,只能跟帥帥的工程師蟈蟈說(shuō),快,快,再快一點(diǎn)!
于是Impala,Presto,Drill誕生了(當(dāng)然還有無(wú)數(shù)非著名的交互SQL引擎,就不一一列舉了)。三個(gè)系統(tǒng)的核心理念是,MapReduce引擎太慢,因?yàn)樗ㄓ茫珡?qiáng)壯,太保守,我們SQL需要更輕量,更激進(jìn)地獲取資源,更專(zhuān)門(mén)地對(duì)SQL做優(yōu)化,而且不需要那么多容錯(cuò)性保證(因?yàn)橄到y(tǒng)出錯(cuò)了大不了重新啟動(dòng)任務(wù),如果整個(gè)處理時(shí)間更短的話,比如幾分鐘之內(nèi))。這些系統(tǒng)讓用戶(hù)更快速地處理SQL任務(wù),犧牲了通用性穩(wěn)定性等特性。如果說(shuō)MapReduce是大砍刀,砍啥都不怕,那上面三個(gè)就是剔骨刀,靈巧鋒利,但是不能搞太大太硬的東西。
這些系統(tǒng),說(shuō)實(shí)話,一直沒(méi)有達(dá)到人們期望的流行度。因?yàn)檫@時(shí)候又兩個(gè)異類(lèi)被造出來(lái)了。他們是Hive on Tez / Spark和SparkSQL。它們的設(shè)計(jì)理念是,MapReduce慢,但是如果我用新一代通用計(jì)算引擎Tez或者Spark來(lái)跑SQL,那我就能跑的更快。而且用戶(hù)不需要維護(hù)兩套系統(tǒng)。這就好比如果你廚房小,人又懶,對(duì)吃的精細(xì)程度要求有限,那你可以買(mǎi)個(gè)電飯煲,能蒸能煲能燒,省了好多廚具。
上面的介紹,基本就是一個(gè)數(shù)據(jù)倉(cāng)庫(kù)的構(gòu)架了。底層HDFS,上面跑MapReduce/Tez/Spark,在上面跑Hive,Pig。或者HDFS上直接跑Impala,Drill,Presto。這解決了中低速數(shù)據(jù)處理的要求。
如何更高速的處理?
考慮一下,如果我需要更高的處理速度,我要展示的數(shù)據(jù)不再是24小時(shí)甚至更長(zhǎng)尺度的數(shù)據(jù)報(bào)告,而是一個(gè)隨時(shí)更新、隨時(shí)變化的榜單,這個(gè)榜單的更新最好在1分鐘甚至更短,那么上述手段就無(wú)發(fā)滿(mǎn)足我的需要。
這時(shí)候,另一個(gè)工具即將登場(chǎng)——Streaming計(jì)算模型。這種模型通常被稱(chēng)為流計(jì)算模型,使用最多的平臺(tái)式Storm。這種模型會(huì)在數(shù)據(jù)開(kāi)始搜集的時(shí)候進(jìn)行計(jì)算,而不是在搜集完成后——你每獲得一個(gè)數(shù)據(jù)都會(huì)加入到實(shí)時(shí)計(jì)算中成為最終成果的一份子。這種方式處理的數(shù)據(jù)基本不會(huì)存在延遲問(wèn)題。
但它并不是盡善盡美。在使用流計(jì)算之前,我們必須預(yù)先找到統(tǒng)計(jì)的核心,因?yàn)橐欢螖?shù)據(jù)經(jīng)過(guò)處理就會(huì)放在一邊——正如流過(guò)的河水無(wú)法倒回一樣——未能提前找到統(tǒng)計(jì)核心的時(shí)候數(shù)據(jù)就被浪費(fèi)掉了。這也是流計(jì)算無(wú)法完全替代我們前文講過(guò)的工具的原因。
另一個(gè)比較獨(dú)立的工具是KV Store,類(lèi)似于Cassandra,HBase,MongoDB等等非常非常多的其他東西。他是什么意思呢,假如你有一堆鍵值,你就能通過(guò)某種方式快速獲得鍵值背后的一大堆數(shù)據(jù)。就好像你去銀行插入銀行卡就能取到錢(qián)一樣。
假如你特立獨(dú)行,使用MapReduce完成也沒(méi)有任何問(wèn)題,但是由此帶來(lái)的不便就是掃描數(shù)據(jù)庫(kù)的時(shí)間會(huì)很長(zhǎng)。如果我們采用了KV Store,這種專(zhuān)門(mén)為了鍵值存取而設(shè)定的工具,那這個(gè)速度就會(huì)非常快。這個(gè)工具的核心就是快,其他的事情他一概不管,就是要快。
除此之外,還有一些更特制的系統(tǒng)/組件,比如Mahout是分布式機(jī)器學(xué)習(xí)庫(kù),Protobuf是數(shù)據(jù)交換的編碼和庫(kù),ZooKeeper是高一致性的分布存取協(xié)同系統(tǒng),等等。
當(dāng)你拿到這么多工具(甚至多到連很多東西的名字都寫(xiě)不熟練)之后,你把他們拼裝在一起,如果沒(méi)有一個(gè)完美的安排大家就會(huì)互相打架,造成效率低下,所以這個(gè)時(shí)候還要引入一個(gè)調(diào)度系統(tǒng),專(zhuān)門(mén)給大家安排任務(wù)、安排時(shí)間,使系統(tǒng)能夠良好運(yùn)轉(zhuǎn)。