高可用Hadoop平臺-探索

哥不是小蘿莉發表於2015-03-18

1.概述

  上篇《高可用Hadoop平臺-啟航》部落格已經讓我們初步瞭解了Hadoop平臺;接下來,我們對Hadoop做進一步的探索,一步一步的揭開Hadoop的神祕面紗。下面,我們開始贅述今天的探索之路。

2.探索

  在探索之前,我們來看一下Hadoop解決了什麼問題,Hadoop就是解決了大資料(大到單臺伺服器無法進行儲存,單臺伺服器無法在限定的時間內進行處理)的可靠儲存和處理。

  • HDFS:在由普通或廉價的伺服器(或PC)組成的叢集上提供高可用的檔案儲存,通過將塊儲存多個副本的辦法解決伺服器或硬碟壞掉的問題。
  • MapReduce:通過簡單的Mapper和Reducer的抽象提供一個程式設計模型,可以在一個由幾十臺或上百臺的伺服器組成的叢集上進行併發,分散式的處理大量的資料集;而併發,分散式(如:機器間通訊)和故障恢復等計算細節隱藏起來。而Mapper和Reducer的抽象,又是各種各樣的複雜資料處理都可以分解為基本元素。這樣,複雜的資料處理可以分解為由多個Job(包含一個Mapper和一個Reducer)組成的有向無環圖(DAG),然後每個Mapper和Reducer放到Hadoop叢集上執行,就可以得出如下圖所示的結果:

  在Hadoop的原始碼中,提供了一個很經典的例子:WordCount,具體原始碼可以參見上篇文章,如果對MapReduce不熟悉,通過該示例對MapReduce進行一些瞭解對理解下文會由幫助。在MapReduce中,Shuffle是一個非常重要的過程,正是有了看不見的Shuffle過程,才可以使在MapReduce之上寫資料處理的開發者完全感覺不到分散式和併發的存在。

  注:廣義的Shuffle是指圖中在Map和Reduce之間的一系列過程。

2.1Hadoop的侷限和不足

  MapReduce存在以下侷限,使用起來比較困難。

  • 抽象層次低,需要手工編寫程式碼來完成,使用上難以上手,入門門檻較高。
  • 只提供兩個操作,Map和Reduce,表達的力度不夠。
  • 一個Job只有Map和Reduce兩個階段,複雜的計算需要大量的Job來完成。Job之間的依賴關係是由開發者自己來管理的。
  •   處理邏輯隱藏在程式碼細節中,沒有整體邏輯。
  • 中間結果也放在HDFS檔案系統中。
  • ReduceTask需要等待所有的MapTask都完成後才可以開始。
  • 時延高,只適用Batch資料處理,對於互動式資料處理,實時資料處理的支援不夠。
  • 對於迭代式資料處理效能比較差。

  舉個例子,用MapReduce實現表與表之間的join,都是一個很需要技巧來處理的過程,如下圖:

  因此,在Hadoop之後,出現來很多相關技術對其中的侷限進行改進,如:Hive,Oozie,Tez,Spark,Storm等等。

3.Hive

  Hive是Facebook的產品,目前已託管到Apache基金。關於Hive的安裝搭建和使用請參考《那些年使用Hive踩過的坑》和《Hive的安裝部署》,這裡就不多贅述了。Hive是一種底層封裝了Hadoop的資料倉儲處理工具,使用類SQL的HiveSQL語言實現資料查詢,所有Hive的資料都儲存在HDFS中。Hive在載入資料過程中不會對資料進行任何的修改,只是將資料移動到HDFS中Hive的指定目錄下,因此,Hive不支援對資料的改寫和新增,所有的資料都是在載入的時候確定的。

  Hive解決類MapReduce存在的大量手寫程式碼,語義隱藏,提供操作種類少的問題。類似的專案還有Pig,JAQL等。

4.Tez

  Tez是HortonWorks的Stinger Initiative的的一部分。作為執行引擎,Tez也提供了有向無環圖(DAG),DAG由頂點(Vertex)和邊(Edge)組成,Edge是對資料的移動的抽象,提供了One-To-One,BroadCast,和Scatter-Gather三種型別,只有Scatter-Gather才需要進行Shuffle。

  示例:

SELECT a.state, COUNT(*), AVERAGE(c.price) FROM a JOIN b ON (a.id = b.id) JOIN c ON (a.itemId = c.itemId) GROUP BY a.state

  Tez的優化主要體現在:

  1. 去除了連續兩個任務之間的寫屏障
  2. 去除了每個工作流中多餘的Map階段

  通過提供DAG語義和操作,提供了整體的邏輯,通過減少不必要的操作,Tez提升了資料處理的執行效能。

5.Spark

 

  Spark也是一個大資料處理的引擎,主要特點是提供了一個叢集的分散式記憶體抽象,以支援需要工作集的應用。

 

  這個抽象就是RDD(Resilient Distributed Dataset),RDD就是一個不可變的帶分割槽的記錄集合,RDD也是Spark中的程式設計模型。Spark提供了RDD上的兩類操作,轉換和動作。轉換是用來定義一個新的RDD,包括map, flatMap, filter, union, sample, join, groupByKey, cogroup, ReduceByKey, cros, sortByKey, mapValues等,動作是返回一個結果,包括collect, reduce, count, save, lookupKey。

 

  Spark支援故障恢復的方式也不同,提供兩種方式,Linage,通過資料的血緣關係,再執行一遍前面的處理,Checkpoint,將資料集儲存到持久儲存中。

 

  Spark的API非常簡單易用,使用Spark,WordCount的示例如下所示:

val spark = new SparkContext(master, appName, [sparkHome], [jars])
val file = spark.textFile("hdfs://nna:9000/hdfs/in/a.txt")
val counts = file.flatMap(line => line.split(" "))
                 .map(word => (word, 1))
                 .reduceByKey(_ + _)
counts.saveAsTextFile("hdfs://nna:9000/hdfs/out")

  其中的file是根據HDFS上的檔案建立的RDD,後面的flatMap,map,reduceByKe都建立出一個新的RDD,一個簡短的程式就能夠執行很多個轉換和動作。在Spark中,所有RDD的轉換都是是惰性求值的。Spark的任務是由相互依賴的多個RDD組成的有向無環圖(DAG),每個RDD又包含多個分割槽,當在RDD上執行動作時,Spark才對任務進行排程。

  Spark對於有向無環圖對任務進行排程,確定階段,分割槽,流水線,任務和快取,進行優化,並在Spark叢集上執行任務。RDD之間的依賴分為寬依賴(依賴多個分割槽)和窄依賴(只依賴一個分割槽),在確定階段時,需要根據寬依賴劃分階段。根據分割槽劃分任務。

  Spark為迭代式資料處理提供更好的支援。每次迭代的資料可以儲存在記憶體中,而不是寫入檔案。

  Spark的效能相比Hadoop有很大提升,2014年10月,Spark完成了一個Daytona Gray類別的Sort Benchmark測試,排序完全是在磁碟上進行的,與Hadoop之前的測試的對比結果如表格所示:

  原圖連結地址:http://databricks.com/blog/2014/11/05/spark-officially-sets-a-new-record-in-large-scale-sorting.html

  從表格中可以看出排序100TB的資料(1萬億條資料),Spark只用了Hadoop所用1/10的計算資源,耗時只有Hadoop的1/3。

  Spark的優勢不僅體現在效能提升上的,Spark框架為批處理(Spark Core),互動式(Spark SQL),流式(Spark Streaming),機器學習(MLlib),圖計算(GraphX)提供一個統一的平臺,這相對於使用Hadoop有很大優勢。

6.總結

  那麼Spark解決了Hadoop的哪些問題?

  • 抽象層次低,需要手工編寫程式碼來完成,使用上難以上手。
    • =>基於RDD的抽象,實資料處理邏輯的程式碼非常簡短。
  • 只提供兩個操作,Map和Reduce,表達力欠缺。
    • =>提供很多轉換和動作,很多基本操作如Join,GroupBy已經在RDD轉換和動作中實現。
  • 一個Job只有Map和Reduce兩個階段,複雜的計算需要大量的Job完成,Job之間的依賴關係是由開發者自己管理的。
    • =>一個Job可以包含RDD的多個轉換操作,在排程時可以生成多個階段,而且如果多個map操作的RDD的分割槽不變,是可以放在同一個Task中進行。
  • 處理邏輯隱藏在程式碼細節中,沒有整體邏輯。
    • =>在Scala中,通過匿名函式和高階函式,RDD的轉換支援流式API,可以提供處理邏輯的整體檢視。
  • 程式碼不包含具體操作的實現細節,邏輯更清晰。 中間結果也放在HDFS檔案系統中。
    • =>中間結果放在記憶體中,記憶體放不下了會寫入本地磁碟,而不是HDFS。
  • ReduceTask需要等待所有MapTask都完成後才可以開始
    • =>它允許使用者單獨為Map Task和Reduce Task設定不同的資源,進而細粒度控制任務佔用資源量,有利於大作業的正常平穩執行。
  • 時延高,只適用Batch資料處理,對於互動式資料處理,實時資料處理的支援不夠。
    • =>通過將流拆成小的batch提供Discretized Stream處理流資料。
  • 對於迭代式資料處理效能比較差。
    • =>通過在記憶體中快取資料,提高迭代式計算的效能。

  這篇文章就分享到這裡,若在研究的過程中有什麼疑問,可以加群討論或傳送郵件給我,我會盡我所能為您解答,與君共勉!

 

相關文章