天天看點

應該在什麼時候使用Hadoop

有人問我,“你在大資料和Hadoop方面有多少經驗?”我告訴他們,我一直在使用Hadoop,但是我處理的資料集很少有大于幾個TB的。

他們又問我,“你能使用Hadoop做簡單的分組和統計嗎?”我說當然可以,我隻是告訴他們我需要看一些檔案格式的例子。

他們遞給我一個包含600MB資料的閃盤,看起來這些資料并非樣本資料,由于一些我不能了解的原因,當我的解決方案涉及到pandas.read_csv檔案,而不是Hadoop,他們很不愉快。

Hadoop實際上是有很多局限的。Hadoop允許你運作一個通用的計算,下面我用僞碼進行說明:

Scala風格的僞碼:

collection.flatMap( (k,v) => F(k,v) ).groupBy( _._1 ).map( _.reduce( (k,v) => G(k,v) ) )  

SQL風格的僞碼:

SELECT G(...) FROM table GROUP BY F(...)  

目标:計算圖書館書籍的數量

Map:你統計奇數書架上書的數量,我統計偶數書架上書的數量。(人越多,統計越快)

Reduce:把我們單獨統計後的資料加在一起。

我們所做的隻有兩個:F(k,v)和G(k,v),除開在中間步驟中的性能優化,一切都是固定的。

它會迫使你在Map中進行所有的計算,分組和統計,執行運算的方式像是穿上了緊身衣,其實很多計算更适合選用其它模型。穿上緊身衣的唯一原因是這可能會擴充到非常大的資料集上,而大多數情況下,你的資料量可能會小幾個數量級。

但是由于“大資料”和“Hadoop”這兩個熱門詞,即使很多人實際上不需要Hadoop,他們也願意穿上“緊身衣”。

一、如果我的資料量是幾百兆,Excel可能沒法加載它

對于Excel軟體來說的“很大的資料”并非大資料,其實還有其它極好的工具可以使用——我喜歡的Pandas。Pandas建構于Numpy庫之上,可以以矢量格式的方式有效地把數百兆的資料載入到記憶體中。在我購買已3年的筆記本上,它可以用Numpy在一眨眼的功夫把1億的浮點數乘在一起。Matlab和R也是極好的工具。

對于幾百兆的資料量,典型的做法是寫一個簡單的Python腳本按行讀取檔案行,并處理它,向另一個檔案寫入。

二、如果我的資料是10GB呢

我買了個新筆記本,它有16GB的記憶體和256GB的SSD。如果你要載入一個10GB的CSV檔案到Pandas,它占用的記憶體實際上是很小的——其結果是以數字類型的字元串儲存的,如“17284832583”作為4位元組貨8位元組的整數,或存儲“284572452.2435723”字元串作為8位元組的雙精度浮點數。

最壞的情況是你或許不能把所有的資料都同時載入到記憶體中。

三、如果我的資料是100GB、500GB或1TB呢

買個2TB或4TB的硬碟,在桌面PC或伺服器上安裝一個Postgre來解決它。

四、Hadoop遠遠比不上SQL或Python腳本

在計算的表達方面,Hadoop弱于SQL,也弱于Python腳本。

SQL是一個很直接的查詢語言,适合做業務分析,SQL的查詢相當簡單,而且還非常快——如果你的資料庫使用了正确的索引,二級查詢或多級查詢另當别論。

Hadoop沒有索引的概念,Hadoop隻有全表掃描,Hadoop有高度洩露抽象——我花了很多時間來處理Java的記憶體錯誤、檔案碎片以及叢集競争,這些時間遠大于我花在資料分析上的時間。

如果你的資料并不是像SQL表那樣的結構化資料(比如純文字、JSON對象、二進制對象),通常是直接寫一個小的Python腳本來按行處理你的資料。把資料存儲于檔案,處理每一個檔案,等等。如果換成是Hadoop就很麻煩。

相比于SQL或Python腳本,Hadoop要慢的多。正确的使用索引後,SQL查詢總是非快——PostgreSQL簡單的查找索引,檢索确切的鍵值。而Hadoop是全表掃描的,它會把整個表進行重新排序。通過把資料表分片到多台計算機上後,重排序是很快的。另一方面,處理二進制對象,Hadoop需要重複往返于命名節點,目的是查找和處理資料。這适合用Python腳本來實作。

五、我的資料超過了5TB

你應該考慮使用Hadoop,而無需做過多的選擇。

使用Hadoop唯一的好處是可伸縮性非常好。如果你有一個包含了數TB資料的表,Hadoop有一個适合全表掃描的選項。如果你沒有這樣大資料量的表,那麼你應該像躲避瘟疫那樣避免使用Hadoop。這樣使用傳統的方法來解決問題會更輕松。

六、Hadoop是一個極好的工具

我并不讨厭Hadoop,當我用其它工具不能很好處理資料時我會選擇Hadoop。另外,我推薦使用Scalding,不要使用Hive或Pig。Scalding支援使用Scala語言來編寫Hadoop任務鍊,隐藏了其下的MapReduce。