Spark:超越Hadoop MapReduce

引言:和 Hadoop 一樣,Spark 提供了一個 Map/Reduce API(分佈式計算)和分佈式存儲。二者主要的不同點是,Spark 在集羣的內存中保存數據,而 Hadoop 在集羣的磁盤中存儲數據。 
本文選自《SparkGraphX實戰》。

  大數據對一些數據科學團隊來說是 主要的挑戰,因爲在要求的可擴展性方面單機沒有能力和容量來運行大規模數據處 理。此外,即使專爲大數據設計的系統,如 Hadoop,由於一些數據的屬性問題也很難有效地處理圖數據,我們將在本章的其他部分看到這方面的內容。
  Apache Spark 與 Hadoop 類似,數據分佈式存儲在服務器的集羣或者是“節點”上。 不同的是,Spark 將數據保存在內存(RAM)中,Hadoop 把數據保存在磁盤(機械 硬盤或者 SSD 固態硬盤)中。
  定義 :在圖和集羣計算方面,“節點”這個詞有兩種截然不同的意思。 圖數據由頂點和邊組成,在這裏“節點”與頂點的意思相近。在集羣計算 方面,組成集羣的物理機器也被稱爲“節點”。爲避免混淆,我們稱圖的 節點爲頂點,這也是 Spark 中的專有名詞。而本書中的“節點”這個詞我 們嚴格定義爲集羣中的單個物理計算節點。
           圖片描述
  大數據因爲數據量大單機無法處理。Hadoop 和 Spark 都是把數據分佈在集羣節點上的分 布式框架中。Spark 把分佈式數據集存放在內存中,所以比 Hadoop 把數據存放在磁盤中 處理速度要快很多。
  除了將要計算的數據保存的位置不同(內存和磁盤),Spark 的 API 比 Hadoop的 Map/Reduce API 更容易使用。Spark 使用簡潔且表達力較好的 Scala 作爲原生編程語言,寫 Hadoop Map/Reduce 的 Java 代碼行數與寫 Spark 的 Scala 的代碼行的數 量比一般是 10:1。
  雖然本書主要使用 Scala,但是你對 Scala 不熟悉也不用擔心,我們在第 3 章提 供了快速入門,包括怪異、晦澀和簡練的 Scala 語法。進一步熟悉 Java、C++、C#、 Python 等至少一門編程語言是必要的。

模糊的大數據定義

  現在的“大數據”概念已經被很大程度地誇大了。大數據的概念可以追溯到Google 在 2003 年發表的 Google 文件系統的論文和 2004 年發表的 Map/Reduce 論文。
  大數據這個術語有多種不同的定義,並且有些定義已經失去了大數據所應有的意 義。但是簡單的核心且至關重要的意義是:大數據是因數據本身太大,單機無法處理。
  數據量已經呈爆炸性增長。數據來自網站的點擊、服務器日誌和帶有傳感器的 硬件等,這些稱爲數據源。有些數據是圖數據(graph data),意味着由邊和頂點組成, 如一些協作類網站(屬於“Web 2.0”的社交媒體的一種)。大的圖數據集實際上是 衆包的,例如知識互相連接的 Wikipedia、Facebook 的朋友數據、LinkedIn 的連接數 據,或者 Twitter 的粉絲數據。

Hadoop :Spark 之前的世界

  在討論 Spark 之前,我們總結一下 Hadoop 是如何解決大數據問題的,因爲Spark 是建立在下面將要描述的核心 Hadoop 概念之上的。
  Hadoop 提供了在集羣機器中實現容錯、並行處理的框架。Hadoop 有兩個關鍵 能力 :

  • HDFS—分佈式存儲

  • MapReduce—分佈式計算

HDFS 提供了分佈式、容錯存儲。NameNode 把單個大文件分割成小塊,典型 的塊大小是 64MB 或 128MB。這些小塊文件被分散在集羣中的不同機器上。容錯性 是將每個文件的小塊複製到一定數量的機器節點上(默認複製到 3 個不同節點, 下圖中爲了表示方便,將複製數設置爲 2)。假如一個機器節點失效,致使這個機器上的 所有文件塊不可用,但其他機器節點可以提供缺失的文件塊。這是 Hadoop 架構的 關鍵理念 :機器出故障是正常運作的一部分。
       圖片描述
  三個分佈式數據塊通過 Hadoop 分佈式文件系統(HDFS)保持兩個副本。
  MapReduce 是提供並行和分佈式計算的 Hadoop 並行處理框架,如下圖 。
           圖片描述
  MapReduce 是被 Hadoop 和 Spark 都用到的一個數據處理範式。圖中表示計算服務器日 志文件中“error”出現的次數,這是一個 MapReduce 操作。通常 Map 操作是一對一的 操作,對每一個源數據項生成一個相應的數據轉換操作。Reduce 是多對一的操作,聚合 Map 階段的輸出。Hadoop 和 Spark 都用到了 MapReduce 範式。
  用 MapReduce 框架,程序員寫一個封裝有 map 和 reduce 函數的獨立代碼片段來處 理 HDFS 上的數據集。爲取到數據位置,代碼打包(jar 格式)分發到數據節點, Map 操作就在這些數據節點上執行,這避免了集羣的數據傳輸導致消耗網絡帶寬。 對於 Reduce 聚合操作,Map 的結果被傳輸到多個 Reduce 節點上做 reduce 操作(稱 之爲 shufing)。首先,Map 階段是並行操作的,Hadoop 提供了一個彈性機制,當 一個機器節點或者一個處理過程失敗時,計算會在其他機器節點上重啓。
  MapReduce 編程框架將數據集抽象爲流式 key-value 鍵值對,然後處理這些鍵 值對並寫回到 HDFS。這是一個有侷限的範式,但它已被用來解決許多數據並行問題, 用鏈接在一起的 MapReduce 進行“讀-處理-寫”操作過程。對於一些簡單的任務,上圖顯示的是比較適合的場景。但是對於一些如機器學習算法中的迭代計算算 法,用這種 MapReduce 範式就很痛苦,這也是選擇使用 Spark 的原因。

Spark :內存中的 MapReduce 處理

  我們來看另一個可選的分佈式處理系統,構建在 Hadoop 基礎之上的 Spark。在這一小節你會瞭解到,在 Spark 處理圖數據時扮演重要角色的彈性分 布式數據集(RDD)導致 Hadoop 衰落的兩類問題是 :

  • 交互式查詢

  • 迭代算法

Hadoop 很適合在一個大的數據集上做單次查詢,而在許多實際場景中,一旦有 了一個想要的答案,我們就想再問數據一個問題,這就是交互式查詢。使用 Hadoop 的話,就意味着要等待重新從磁盤中加載數據,再次處理數據。我們不得不執行一 組相同的計算作爲隨後分析的前提,這不符合常理。
  迭代算法已經被廣泛應用於機器學習任務,如隨機梯度下降算法,以及之後 會看到的 PageRank 這類圖計算算法。迭代算法是在一個數據集上一遍又一遍地做 一組計算,直到滿足一個標準(循環結束條件)才結束迭代。 在 Hadoop 中實現這種算法,一般需要一系列加載數據的 MapReduce 任務,這些 MapReduce 任務要在 每一個迭代過程中重複運行。對於非常大的數據集,每個迭代過程要花費 100 秒或1000 秒,整個迭代過程非常耗時。
  下面你會看到 Spark 如何解決這些問題。如 Hadoop 一樣,Spark 也是運行在 一個常見的硬件配置的機器集羣上。Spark 中的一個核心抽象是彈性分佈式數據集(RDD)。RDD 是由 Spark 應用創建的(在Spark Driver上),由集羣管理,如下圖。
           圖片描述
  Spark 提供一個彈性分佈式數據集,可以認爲它是一個分佈式的常駐內存的數組。
組成 RDD 分佈式數據集的數據分區會被加載到集羣的機器上。

基於內存的數據處理

  Spark 執行的大部分操作都是在隨機訪問內存中(RAM)進行。Spark 是基於內 存的,而 Hadoop Map/Reduce 是順序處理數據,所以 Spark 比 Hadoop 更適合處理 隨機訪問的圖數據。
  Spark 的關鍵好處在於交互式查詢和迭代處理過程中在內存中緩存 RDD。緩存 起來的 RDD 可以避免每次重新處理父 RDD 鏈,而只需要直接返回父 RDD 計算後 的緩存結果。
  自然的,這意味着要用到 Spark 的基於內存的計算處理特性,要求集羣中的機 器內存要足夠大。要是可用內存不夠,那麼 Spark 就會優雅地溢出數據到磁盤,以 保證 Spark 能繼續運行。
  當然 Spark 集羣也需要一個持久化存儲數據的地方,而且還要是分佈式存儲系 統才行,可選的有 HDFS、Cassandra 和亞馬遜的 S3。

  本文選自《Spark GraphX實戰》,點此鏈接可在博文視點官網查看此書。
                    圖片描述
  想及時獲得更多精彩文章,可在微信中搜索“博文視點”或者掃描下方二維碼並關注。
                       圖片描述


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章