應(yīng)該在什么時(shí)候使用Hadoop
有人問我,“你在大數(shù)據(jù)和Hadoop方面有多少經(jīng)驗(yàn)寸莫?”我告訴他們尖滚,我一直在使用Hadoop,但是我處理的數(shù)據(jù)集很少有大于幾個(gè)TB的庐氮。
他們又問我语稠,“你能使用Hadoop做簡單的分組和統(tǒng)計(jì)嗎?”我說當(dāng)然可以弄砍,我只是告訴他們我需要看一些文件格式的例子仙畦。
他們遞給我一個(gè)包含600MB數(shù)據(jù)的閃盤,看起來這些數(shù)據(jù)并非樣本數(shù)據(jù)音婶,由于一些我不能理解的原因慨畸,當(dāng)我的解決方案涉及到pandas.read_csv文件,而不是Hadoop衣式,他們很不愉快寸士。
Hadoop實(shí)際上是有很多局限的。Hadoop允許你運(yùn)行一個(gè)通用的計(jì)算碴卧,下面我用偽碼進(jìn)行說明:
Scala風(fēng)格的偽碼:
collection.flatMap( (k,v) => F(k,v) ).groupBy( _._1 ).map( _.reduce( (k,v) => G(k,v) ) )
SQL風(fēng)格的偽碼:
SELECT G(...) FROM table GROUP BY F(...)
目標(biāo):計(jì)算圖書館書籍的數(shù)量
Map:你統(tǒng)計(jì)奇數(shù)書架上書的數(shù)量碉京,我統(tǒng)計(jì)偶數(shù)書架上書的數(shù)量。(人越多螟深,統(tǒng)計(jì)越快)
Reduce:把我們單獨(dú)統(tǒng)計(jì)后的數(shù)據(jù)加在一起谐宙。
我們所做的只有兩個(gè):F(k,v)和G(k,v),除開在中間步驟中的性能優(yōu)化界弧,一切都是固定的凡蜻。
它會迫使你在Map中進(jìn)行所有的計(jì)算搭综,分組和統(tǒng)計(jì),執(zhí)行運(yùn)算的方式像是穿上了緊身衣划栓,其實(shí)很多計(jì)算更適合選用其它模型兑巾。穿上緊身衣的唯一原因是這可能會擴(kuò)展到非常大的數(shù)據(jù)集上,而大多數(shù)情況下忠荞,你的數(shù)據(jù)量可能會小幾個(gè)數(shù)量級蒋歌。
但是由于“大數(shù)據(jù)”和“Hadoop”這兩個(gè)熱門詞,即使很多人實(shí)際上不需要Hadoop委煤,他們也愿意穿上“緊身衣”堂油。
一、如果我的數(shù)據(jù)量是幾百兆碧绞,Excel可能沒法加載它
對于Excel軟件來說的“很大的數(shù)據(jù)”并非大數(shù)據(jù)府框,其實(shí)還有其它極好的工具可以使用——我喜歡的Pandas。Pandas構(gòu)建于Numpy庫之上讥邻,可以以矢量格式的方式有效地把數(shù)百兆的數(shù)據(jù)載入到內(nèi)存中迫靖。在我購買已3年的筆記本上,它可以用Numpy在一眨眼的功夫把1億的浮點(diǎn)數(shù)乘在一起兴使。Matlab和R也是極好的工具系宜。
對于幾百兆的數(shù)據(jù)量,典型的做法是寫一個(gè)簡單的Python腳本按行讀取文件行发魄,并處理它盹牧,向另一個(gè)文件寫入。
二欠母、如果我的數(shù)據(jù)是10GB呢
我買了個(gè)新筆記本欢策,它有16GB的內(nèi)存和256GB的SSD吆寨。如果你要載入一個(gè)10GB的CSV文件到Pandas赏淌,它占用的內(nèi)存實(shí)際上是很小的——其結(jié)果是以數(shù)字類型的字符串保存的,如“17284832583”作為4字節(jié)貨8字節(jié)的整數(shù)啄清,或存儲“284572452.2435723”字符串作為8字節(jié)的雙精度浮點(diǎn)數(shù)六水。
最壞的情況是你或許不能把所有的數(shù)據(jù)都同時(shí)載入到內(nèi)存中。
三辣卒、如果我的數(shù)據(jù)是100GB掷贾、500GB或1TB呢
買個(gè)2TB或4TB的硬盤,在桌面PC或服務(wù)器上安裝一個(gè)Postgre來解決它荣茫。
四想帅、Hadoop遠(yuǎn)遠(yuǎn)比不上SQL或Python腳本
在計(jì)算的表達(dá)方面,Hadoop弱于SQL啡莉,也弱于Python腳本港准。
SQL是一個(gè)很直接的查詢語言旨剥,適合做業(yè)務(wù)分析,SQL的查詢相當(dāng)簡單浅缸,而且還非彻熘模快——如果你的數(shù)據(jù)庫使用了正確的索引,二級查詢或多級查詢另當(dāng)別論衩椒。
Hadoop沒有索引的概念蚌父,Hadoop只有全表掃描,Hadoop有高度泄露抽象——我花了很多時(shí)間來處理Java的內(nèi)存錯誤毛萌、文件碎片以及集群競爭苟弛,這些時(shí)間遠(yuǎn)大于我花在數(shù)據(jù)分析上的時(shí)間。
如果你的數(shù)據(jù)并不是像SQL表那樣的結(jié)構(gòu)化數(shù)據(jù)(比如純文本朝聋、JSON對象嗡午、二進(jìn)制對象),通常是直接寫一個(gè)小的Python腳本來按行處理你的數(shù)據(jù)冀痕。把數(shù)據(jù)存儲于文件荔睹,處理每一個(gè)文件,等等言蛇。如果換成是Hadoop就很麻煩僻他。
相比于SQL或Python腳本,Hadoop要慢的多腊尚。正確的使用索引后吨拗,SQL查詢總是非快——PostgreSQL簡單的查找索引,檢索確切的鍵值婿斥。而Hadoop是全表掃描的劝篷,它會把整個(gè)表進(jìn)行重新排序。通過把數(shù)據(jù)表分片到多臺計(jì)算機(jī)上后民宿,重排序是很快的娇妓。另一方面,處理二進(jìn)制對象活鹰,Hadoop需要重復(fù)往返于命名節(jié)點(diǎn)哈恰,目的是查找和處理數(shù)據(jù)。這適合用Python腳本來實(shí)現(xiàn)志群。
五着绷、我的數(shù)據(jù)超過了5TB
你應(yīng)該考慮使用Hadoop,而無需做過多的選擇锌云。
使用Hadoop唯一的好處是可伸縮性非常好荠医。如果你有一個(gè)包含了數(shù)TB數(shù)據(jù)的表,Hadoop有一個(gè)適合全表掃描的選項(xiàng)。如果你沒有這樣大數(shù)據(jù)量的表彬向,那么你應(yīng)該像躲避瘟疫那樣避免使用Hadoop豫喧。這樣使用傳統(tǒng)的方法來解決問題會更輕松。