1. 程式人生 > >hadoop介紹(關於hadoop技術知識的學習筆記)

hadoop介紹(關於hadoop技術知識的學習筆記)

1.1            雲平臺hadoop基礎資訊

Hadoop[1]是一個能夠對大量資料進行分散式處理的軟體框架。主要是由HDFS和MapReduce組成。

Hadoop是N個開源專案的總稱[4]。主要是由HDFS和MapReduce組成。

HDFS是Google File System(GFS)的開源實現。

MapReduce是Google MapReduce的開源實現。這個分散式框架很有創造性,而且有極大的擴充套件性,使得Google在系統吞吐量上有很大的競爭力。因此Apache基金會用Java實現了一個開源版本,支援Fedora、Ubuntu等Linux平臺。雅虎和矽谷風險投資公司Benchmark Capital 聯合成立一家名為Hortonworks的新公司,接管被廣泛應用的資料分析軟體Hadoop的開發工作。

Hadoop實現了HDFS檔案系統和MapRecue。使用者只要繼承MapReduceBase,提供分別實現Map和Reduce的兩個類,並註冊Job即可自動分散式執行。

hadoop其他開源子專案的名稱:

HBase: 類似Google BigTable的分散式NoSQL列資料庫。(HBaseAvro已經於20105月成為頂級Apache專案)

Hive:資料倉庫工具,由Facebook貢獻。

Zookeeper:分散式鎖設施,提供類似Google Chubby的功能,由Facebook貢獻。

Avro:新的資料序列化格式與傳輸工具,將逐步取代Hadoop原有的IPC機制。

Pig:大資料分析平臺,為使用者提供多種介面。

Ambari[5]Hadoop管理工具,可以快捷的監控、部署、管理叢集。

Sqoop:於在HADOOP與傳統的資料庫間進行資料的傳遞。

Hadoop[1]是一個能夠對大量資料進行分散式處理的軟體框架。但是 Hadoop是以一種可靠、高效、可伸縮的方式進行處理的。Hadoop是可靠的,因為它假設計算元素和儲存會失敗,因此它維護多個工作資料副本,確保能夠針對失敗的節點重新分佈處理。Hadoop是高效的,因為它以並行的方式工作,通過並行處理加快處理速度。Hadoop還是可伸縮的,能夠處理 PB 級資料。此外,Hadoop 依賴於社群伺服器,因此它的成本比較低,任何人都可以使用。

Hadoop

是一個能夠讓使用者輕鬆架構和使用的分散式計算平臺。使用者可以輕鬆地在Hadoop上開發和執行處理海量資料的應用程式。它主要有以下幾個優點:

⒈高可靠性。Hadoop按位儲存和處理資料的能力值得人們信賴。

⒉高擴充套件性。Hadoop是在可用的計算機集簇間分配資料並完成計算任務的,這些集簇可以方便地擴充套件到數以千計的節點中。

⒊高效性。Hadoop能夠在節點之間動態地移動資料,並保證各個節點的動態平衡,因此處理速度非常快。

⒋高容錯性。Hadoop能夠自動儲存資料的多個副本,並且能夠自動將失敗的任務重新分配。

Hadoop帶有用 Java語言編寫的框架,因此執行在 Linux生產平臺上是非常理想的。Hadoop上的應用程式也可以使用其他語言編寫,比如 C++

Google的資料中心使用廉價的Linux PC機組成叢集,在上面執行各種應用。即使是分散式開發的新手也可以迅速使用Google的基礎設施。核心元件是3個:

GFSGoogleFile System)。一個分散式檔案系統,隱藏下層負載均衡,冗餘複製等細節,對上層程式提供一個統一的檔案系統API介面。Google根據自己的需求對它進行了特別優化,包括:超大檔案的訪問,讀操作比例遠超過寫操作,PC機極易發生故障造成節點失效等。GFS把檔案分成64MB的塊,分佈在叢集的機器上,使用Linux的檔案系統存放。同時每塊檔案至少有3份以上的冗餘。中心是一個Master節點,根據檔案索引,找尋檔案塊。詳見Google的工程師釋出的GFS論文。

MapReduceGoogle發現大多數分散式運算可以抽象為MapReduce操作。Map是把輸入Input分解成中間的Key/Value對,ReduceKey/Value合成最終輸出Output。這兩個函式由程式設計師提供給系統,下層設施把MapReduce操作分佈在叢集上執行,並把結果儲存在GFS上。

BigTable。一個大型的分散式資料庫,這個資料庫不是關係式的資料庫。像它的名字一樣,就是一個巨大的表格,用來儲存結構化的資料。

以上三個設施Google均有論文發表。

Hadoop 的最常見用法之一是 Web搜尋。雖然它不是惟一的軟體框架應用程式,但作為一個並行資料處理引擎,它的表現非常突出。Hadoop最有趣的方面之一是 Map andReduce流程,它受到Google開發的啟發。這個流程稱為建立索引,它將Web爬行器檢索到的文字 Web頁面作為輸入,並且將這些頁面上的單詞的頻率報告作為結果。然後可以在整個 Web搜尋過程中使用這個結果從已定義的搜尋引數中識別內容。

MapReduce

使用這個抽象模型,我們只要表述我們想要執行的簡單運算即可,而不必關心平行計算、容錯、資料分佈、負載均衡等複雜的細節,這些問題都被封裝在了一個庫裡面。設計這個抽象模型的靈感來自Lisp和許多其他函式式語言的MapReduce的原語。我們意識到我們大多數的運算都包含這樣的操作:在輸入資料的“邏輯”記錄上應用Map操作得出一箇中間key/value pair集合,然後在所有具有相同key值的value值上應用Reduce操作,從而達到合併中間的資料,得到一個想要的結果的目的。使用MapReduce模型,再結合使用者實現的MapReduce函式,我們就可以非常容易的實現大規模並行化計算;通過MapReduce模型自帶的“再次執行”(re-execution)功能,也提供了初級的容災實現方案。

MapReduce

最簡單的 MapReduce應用程式至少包含 3個部分:一個 Map 函式、一個 Reduce 函式和一個 main函式。main 函式將作業控制和檔案輸入/輸出結合起來。在這點上,Hadoop提供了大量的介面和抽象類,從而為 Hadoop應用程式開發人員提供許多工具,可用於除錯和效能度量等。

MapReduce 本身就是用於並行處理大資料集的軟體框架。MapReduce的根源是函式性程式設計中的 mapreduce 函式。它由兩個可能包含有許多例項(許多 Map Reduce)的操作組成。Map函式接受一組資料並將其轉換為一個鍵/值對列表,輸入域中的每個元素對應一個鍵/值對。Reduce函式接受 Map 函式生成的列表,然後根據它們的鍵(為每個鍵生成一個鍵/值對)縮小鍵/值對列表。

這裡提供一個示例,幫助您理解它。假設輸入域是one small step for man,one giant leap for mankind。在這個域上執行 Map函式將得出以下的鍵/值對列表:

one,1(small,1 (step,1 (for,1 (man,1

MapReduce 流程的概念流

MapReduce 流程的概念流

(one,1 (giant,1 (leap,1(for,1 (mankind,1

如果對這個鍵/值對列表應用Reduce函式,將得到以下一組鍵/值對:

one,2(small,1 (step,1 (for,2 (man,1)(giant,1(leap,1 (mankind,1

結果是對輸入域中的單詞進行計數,這無疑對處理索引十分有用。但是,假

顯示處理和儲存的物理分佈的 Hadoop叢集

顯示處理和儲存的物理分佈的 Hadoop叢集

設有兩個輸入域,第一個是 one smallstep for man,第二個是 one giant leap for mankind。您可以在每個域上執行 Map 函式和 Reduce函式,然後將這兩個鍵/值對列表應用到另一個 Reduce函式,這時得到與前面一樣的結果。換句話說,可以在輸入域並行使用相同的操作,得到的結果是一樣的,但速度更快。這便是 MapReduce的威力;它的並行功能可在任意數量的系統上使用。圖2以區段和迭代的形式演示這種思想。

回到 Hadoop 上,它是如何實現這個功能的?一個代表客戶機在單個主系統上啟動的 MapReduce應用程式稱為 JobTracker。類似於NameNode,它是 Hadoop 叢集中惟一負責控制 MapReduce應用程式的系統。在應用程式提交之後,將提供包含在 HDFS中的輸入和輸出目錄。JobTracker使用檔案塊資訊(物理量和位置)確定如何建立其他TaskTracker從屬任務。MapReduce應用程式被複制到每個出現輸入檔案塊的節點。將為特定節點上的每個檔案塊建立一個惟一的從屬任務。每個 TaskTracker將狀態和完成資訊報告給 JobTracker。圖 3顯示一個示例叢集中的工作分佈。

Hadoop 的這個特點非常重要,因為它並沒有將儲存移動到某個位置以供處理,而是將處理移動到儲存。這通過根據叢集中的節點數調節處理,因此支援高效的資料處理。

1.2            雲平臺hadoop子專案MapReduce

MapReduce是一種可用於資料處理的程式設計模型,支援多種語言,包括JavaRubyPythonC++,最重要的是MapReduce程式的本質是並行執行,可以將大規模的資料分析任務交給任何一個擁有足夠多機器的運營商。

最簡單的 MapReduce應用程式至少包含 3個部分:一個 Map函式(個人理解為取出key/value的對映函式)、一個 Reduce函式(value進行處理比較,得到目標的key/vlaue)和一個 main 函式。main 函式將作業控制和檔案輸入/輸出結合起來。在這點上,Hadoop提供了大量的介面和抽象類,從而為 Hadoop應用程式開發人員提供許多工具,可用於除錯和效能度量等。

一個MapReduce關於氣象資料收集處理的小例項:

http://www.china-cloud.com/yunzixun/yunjisuanxinwen/20111101_7321.htm

如上例項也是一個縱向擴充套件的例項。

為了實現橫向擴充套件(scaling out),我們需要把資料儲存在分散式檔案系統中,一般為HDFS,由此允許Hadoop將MapReduce 計算移到儲存有部分資料的各臺機器上。下面我們看看具體過程。

資料流

  首先定義一些術語。MapReduce作業(job) 是客戶端需要執行的一個工作單元:它包括輸入資料、MapReduce程式和配置資訊。Hadoop將作業分成若干個小任務(task)來執行,其中包括兩類任務:map任務和reduce任務。

  有兩類節點控制著作業執行過程:一個jobtracker及一系列tasktracker。jobtracker通過排程tasktracker上執行的任務,來協調所有執行在系統上的作業。tasktracker在執行任務的同時將執行進度報告發送給jobtracker,jobtracker由此記錄每項作業任務的整體進度情況。如果其中一個任務失敗,jobtracker可以在另外一個tasktracker節點上重新排程該任務。

  Hadoop將MapReduce的輸入資料劃分成等長的小資料塊,稱為輸入分片(input split)或簡稱分片。Hadoop為每個分片構建一個map任務,並由該任務來執行使用者自定義的map 函式從而處理分片中的每條記錄。

  擁有許多分片,意味著處理每個分片所需要的時間少於處理整個輸入資料所花的時間。因此,如果我們並行處理每個分片,且每個分片資料比較小,那麼整個處理過程將獲得更好的負載平衡,因為一臺較快的計算機能夠處理的資料分片比一臺較慢的計算機更多,且成一定的比例。即使使用相同的機器,處理失敗的作業或其他同時執行的作業也能夠實現負載平衡,並且如果分片被切分得更細,負載平衡的質量會更好。

我們將用C++重寫貫穿本章的示例,然後,我們將看到如何使用Pipes來執行它。例 2-12 顯示了用C++語言編寫的map函式和reduce 函式的原始碼。

  例2-12. 用C++語言編寫的MaxTemperature程式

  #include

  #include

  #include

  #include

  #include "hadoop/Pipes.hh"

  #include "hadoop/TemplateFactory.hh"

  #include "hadoop/StringUtils.hh"

  class MaxTemperatureMapper : public HadoopPipes::Mapper {

  public:

  MaxTemperatureMapper(HadoopPipes::TaskContext& context) {

  }

  voidmap(HadoopPipes::MapContext& context) {

  std::string line = context.getInputValue();

  std::string year = line.substr(15, 4);

  std::string airTemperature = line.substr(87, 5);

  std::string q = line.substr(92, 1);

  if (airTemperature != "+9999" &&

  (q == "0" || q == "1" || q == "4" || q== "5" || q == "9")) {

  context.emit(year, airTemperature);

  }

  }

  };

  class MapTemperatureReducer : public HadoopPipes::Reducer {

  public:

  MapTemperatureReducer(HadoopPipes::TaskContext& context) {

  }

  voidreduce(HadoopPipes::ReduceContext& context) {

  int maxValue = INT_MIN;

  while (context.nextValue()) {

  maxValue = std::max(maxValue,HadoopUtils::toInt(context.getInputValue()));

  }

  context.emit(context.getInputKey(),HadoopUtils::toString(maxValue));

  }

  };

  intmain(int argc, char *argv[]) {

  returnHadoopPipes::runTask(HadoopPipes::TemplateFactory());

  }

  應用程式對Hadoop C++庫連結提供了一個與tasktracker 子程序進行通訊的簡單封裝。通過擴充套件HadoopPipes名稱空間中定義的mapper和reducer兩個類,我們定義了map()和reduce()方法,同時我們提供各種情況下map()和reduce()方法的實現。這些方法採用了上下文物件(MapContext型別或ReduceContext型別),進而提供了讀取輸入資料和寫入輸出資料,以及通過JobConf類來訪問作業配置資訊的功能。本例中的處理過程類似於Java的處理方式。

  與Java介面不同,C++介面中的鍵和值按位元組緩衝,用標準模板庫(StandardTemplate Library,STL)中的字串表示。這樣做簡化了介面,但把更重的負擔留給了應用程式開發人員,因為開發人員必須來回封送(marshall)字串與特定應用領域內使用的具體型別。這一點在MapTemperatureReducer中有所體現,我們必須把輸入值轉換為整型值(通過HadoopUtils中定義的方法),然後將找到的最大值轉化為字串後再輸出。在某些情況下,我們可以省略這類轉化,如MaxTemperatureMapper 中的airTemperature值無需轉換為整型,因為map()方法並不將它當作數值型別來處理。

  這個應用程式的入口點是main()方法。它呼叫HadoopPipes::runTask,該函式連線到Java父程序,並在mapper和reducer之間來回封送資料。runTask()方法被傳入一個Factory引數,由此新建mapper或reducer例項。新建mapper還是建立reducer,Java父程序可通過套接字連線進行控制。我們可以用過載模板factory來設定combiner、partitioner、record reader或record writer。

  編譯執行

  現在我們可以用Makerfile編譯連線例2-13中的程式。

  例2-13. C++版本MapReduce程式的Makefile

  CC = g++

  CPPFLAGS = -m32 -I$(HADOOP_INSTALL)/c++/$(PLATFORM)/include

  max_temperature: max_temperature.cpp

  $ (CC) $(CPPFLAGS) $< -Wall-L$(HADOOP_INSTALL)/c++/$(PLATFORM)/lib

  -lhadooppipes \ -lhadooputils -lpthread -g -O2 -o [email protected]

在氣象例項中主要是一個單獨簡單的作業,即比較最大值。

當工作任務分解時需要分解成多個時,需要形成MapReduce工作流。

例子:

假設我們想找到每個氣象臺每年每天的最高氣溫記錄的均值。例如,要計算029070-99999氣象臺的1月1日的每日最高氣溫的均值,我們將從這個氣象臺的1901年1月1日,1902年1月1日,直到2000年的1月1日的氣溫中找出每日最高氣溫的均值。

我們如何使用MapReduce來計算它呢?計算自然分解為下面兩個階段。

(1) 計算每對station-date的每日最高氣溫。

本例中的MapReduce程式是最高氣溫程式的一個變種,不同之處在於本例中的鍵是一個綜合的station-date對,而不只是年份。

(2) 計算每個station-day-month鍵的每日最高氣溫的均值。

mapper從上一個作業得到輸出記錄(station-date,最高氣溫值),丟掉年份部分,將其值投影到記錄(station-day-month,最高氣溫值)。然後reducer為每個station-day-month鍵計算最高氣溫值的均值。

第一階段的輸出看上去就是我們想要的氣象臺的資訊。(示例的mean_max_daily_temp.sh指令碼提供了Hadoop Streaming中的一個實現)

1.3            雲平臺hadoop子專案HDFS

當資料集的大小超過一臺獨立計算機的儲存能力時,就有必要對它進行分割槽(partition)並存儲在若干臺單獨的計算機上。管理網路中的跨多臺計算機儲存的檔案系統稱為分散式的檔案系統(distributed filesystem)。hadoop子專案HDFS為hadoop distributed filesystem。

HDFS的設計:

1、超大檔案。TB、PB的單個檔案儲存在叢集上。

2、流式資料訪問。HDFS的構建思想:一次寫入,多次讀取是最高效的訪問模式。資料集通常是資料來源生成或者從資料來源複製而來,接著長時間的進行讀取做各種分析。

3、硬體環境。便宜的普通硬體,雖然節點故障率高,但是其中設計有容災容錯,使用者感知不到。

4、資料訪問延遲較大。HDFS是為高資料吞度量而設計優化的,這可能會以高時間延遲為代價。

5、多使用者寫入,任意修改檔案。HDFS中檔案可能只有一個writer,而且寫操作總是將資料新增在檔案的末尾。它不支援多個寫入者的操作,也不支援在檔案中任意位置進行修改。

HDFS的塊的概念預設是64MB,目的是為了最小化定址開銷。

HDFS的備份和容錯能力,將少數塊賦值到幾個獨立的機器上(預設是3個)。

HDFS有兩類節點,並以管理者和工作者模式執行,即一個namenode(管理者)和多個datanode(工作者)。namenode管理檔案系統的名稱空間,它維護著整個檔案系統樹及整棵樹內所有的檔案和目錄。

名位元組點和資料節點

HDFS是一個的主從結構,一個HDFS叢集是由一個名位元組點,它是一個管理檔案名稱空間和調節客戶端訪問檔案的主伺服器,當然還有一些資料節點,通常是一個節點一個機器,它來管理對應節點的儲存。HDFS對外開放檔案名稱空間並允許使用者資料以檔案形式儲存。

namenode資料至關重要,他的資料丟失意味著分散式檔案系統的丟失,所以需要做好及時的備份和映象備份。

Hadoop系統中的檔案系統fs 命令有著和ls 等作業系統類似的命令。

檔案系統的許可權三種:只讀、寫入、可執行。每個檔案都有所屬使用者(owner)、組別(group)以及模式(mode)。這個模式是由所屬使用者的許可權、組內成員的許可權以及其他使用者的許可權組成的。

hadoop檔案介面操作提供JAVA、以及Clibhdfs等。

FUSE:使用者空間檔案系統,允許把按照使用者空間實現的檔案系統整合成一個UNIX檔案系統。通過使用hadoop的FUSE的功能,任意一個hadoop檔案系可以和unix系統進行互動掛載。

HDFS上檔案互動介面HTTP和FTP介面定義。

HDFS提供資料操作、寫入、檔案目錄讀取,以及資料同步備份、及時寫入等操作。

HDFS儲存小檔案會非常低效,每個塊的元資料都會佔用namenode管理的記憶體空間。

Hadoop讀取HDFS檔案系統中的壓縮檔案時,需要進行檔案壓縮的格式需要支援分片。因為mapReduce輸入是分片的,hdfs資料讀取也是分片的。

壓縮與輸入分片。

序列化,將結構化物件轉化為位元組流,以便在網路上傳輸和寫到磁碟上進行永久儲存。同時還有反序列化。hadoop有屬於自己的序列化的格式writable。

Avro 是一個獨立於程式語言的資料序列化系統。該專案,需要解決writable的可移植性的不足,允許C和C++、python、ruby和hadoop進行互動。google的protocal Buffers 相比,avro用語言無關的模式進行定義。有Avro自己的程式設計特性和特點,有自己定義的avro IDL描述語言。提供豐富的序列化和反序列化的介面。

KerberOS和hadoop管理提供使用者安全驗證互動的管理服務。

dfsadmin用來可以進行管理hadoop的相關叢集、fsck等檢查整個檔案系統的健康狀況。

1.4            雲平臺hadoop子專案PIG

介紹pig,一個不得不說的hadoop的擴充套件。

1.2 什麼是pig

Pig是一個基於Hadoop的大規模資料分析平臺,它提供的SQL-LIKE語言叫Pig Latin,該語言的編譯器會把類SQL的資料分析請求轉換為一系列經過優化處理的MapReduce運算。Pig為複雜的海量資料平行計算提供了一個簡單的操作和程式設計介面。

1.3 pig的特點

1、專注于于大量資料集分析(ad-hoc analysis , ad-hoc 代表:a solution that has been customdesigned for a specific problem );

      2、執行在叢集的計算架構上,Yahoo Pig 提供了多層抽象,簡化平行計算讓普通使用者使用;這些抽象完成自動把使用者請求queries翻譯成有效的並行評估計劃,然後在物理叢集上執行這些計劃;

     3、提供類似 SQL 的操作語法;

     4、開放原始碼;

1.4 pig的主要使用者

1、yahoo

2、twitter

1.5 關於pig和hive

對於開發人員,直接使用Java APIs可能是乏味或容易出錯的,同時也限制了Java程式設計師在Hadoop上程式設計的運用靈活性。於是Hadoop提供了兩個解決方案,使得Hadoop程式設計變得更加容易。

?Pig是一種程式語言,它簡化了Hadoop常見的工作任務。Pig可載入資料、表達轉換資料以及儲存最終結果。Pig內建的操作使得半結構化資料變得有意義(如日誌檔案)。同時Pig可擴充套件使用Java中新增的自定義資料型別並支援資料轉換。

?Hive在Hadoop中扮演資料倉庫的角色。Hive新增資料的結構在HDFS(hive superimposes structure ondata in HDFS),並允許使用類似於SQL語法進行資料查詢。與Pig一樣,Hive的核心功能是可擴充套件的。

Pig和Hive總是令人困惑的。Hive更適合於資料倉庫的任務,Hive主要用於靜態的結構以及需要經常分析的工作。Hive與SQL相似促使 其成為Hadoop與其他BI工具結合的理想交集。Pig賦予開發人員在大資料集領域更多的靈活性,並允許開發簡潔的指令碼用於轉換資料流以便嵌入到較大的 應用程式。Pig相比Hive相對輕量,它主要的優勢是相比於直接使用Hadoop Java APIs可大幅削減程式碼量。正因為如此,Pig仍然是吸引大量的軟體開發人員。

第2章 安裝pig

2.1 下載pig

下載pig的最新版本:

http://www.apache.org/dyn/closer.cgi/pig

我下載的是pig-0.10.0.tar.gz 

2.2 安裝pig

解壓縮

tar zxvf pig-0.10.0.tar.gz

進入目錄

cd pig-0.10.0

注意,pig是hadoop的工具,所以不需要修改原hadoop的配置。

將pig加入到環境變數中:

輸入

cd ~

進入到使用者主目錄

vi .bashrc

最下邊加入環境變數的配置

儲存然後執行

. .bashrc

輸入 pig -help進行測試,如果設定成功,則出現如下介面

如果想獲取pig的原始碼,可以使用svn下載

http://svn.apache.org/repos/asf/pig/trunk

2.3 配置hadoop

進入目錄$PIG_HOME/conf

修改配置檔案,在pig.properties中加入

fs.default.name=hdfs://localhost:9000

mapred.job.tracker=localhost:9001

指向本地偽分散式的hdfs和mapreduce

在本地執行pig

pig -x local

得到如下介面

和hadoop一起執行

直接輸入pig或者pig -x mapreduce

有可能出現下面的錯誤

Cannot find hadoop configurations in classpath(neither hadoop-site.xml nor core-site.xml was found in the classpath).

需要配置~/.bashrc或者/etc/profile,建議配置.bashrc檔案,加入

export HADOOP_HOME=/home/hadoop/hadoop-1.0.3

export PIG_CLASSPATH=$HADOOP_HOME/conf

配置完成後可正常進入

1.5            雲平臺hadoop子專案HIVE

   hive是基於Hadoop的一個數據倉庫工具,可以將結構化的資料檔案對映為一張資料庫表,並提供完整的sql查詢功能,可以將sql語句轉換為MapReduce任務進行執行。 其優點是學習成本低,可以通過類SQL語句快速實現簡單的MapReduce統計,不必開發專門的MapReduce應用,十分適合資料倉庫的統計分析。

對於mapreduce的深度封裝的介面。

Hadoop是一個儲存計算框架,主要由兩部分組成:

1,儲存(Hadoop分散式檔案系統-HDFS)

2,計算(MapReduce計算框架)

1,Hadoop分散式檔案系統

這是一種檔案系統實現,類似於NTFS,ext3,ext4等等,不過它是建立在更高的層次之上的。在HDFS上儲存的檔案被分成塊(每塊預設未64M,比一般的檔案系統塊大小大的多,可調)分佈在多臺機器上,其中的每塊又會有多塊的冗餘備份(預設為3),以增強檔案系統的容錯能力。這種儲存模式與後面將要說明的MapReduce計算模型相得益彰。HDFS在具體實現中主要有以下幾個部分:

一、名稱節點(NameNode):它的職責在於儲存整個檔案系統的元資料,這是個非常重要的角色。元資料在叢集啟動時會載入到記憶體中,元資料的改變也會寫到磁碟上的一個檔案系統映像檔案中(同時還會維護一個對元資料的編輯日誌)。目前名稱節點還是一個單點。因為HDFS儲存檔案的時候是將檔案劃分成邏輯上的塊來儲存的,模個檔案對應那些塊都儲存在名稱節點上,所以如果它有損壞整個叢集的資料將不可用。當然我們可以採取一些措施來備份名稱節點的元資料(檔案系統映像檔案),比如可以將名稱節點目錄同時設定到本地目錄和一個NFS目錄,這樣任何元資料的改變將寫入到兩個位置做冗餘備份,向兩個目錄冗餘寫的過程是原子的。這樣,在使用中的名稱節點宕機之後,我們可以使用NFS上的備份檔案來恢復檔案系統。

二、第二名稱節點(SecondaryNameNode):這個角色的作用就是定期通過編輯日誌合併名稱空間映像,防止編輯日誌過大。不過第二名稱節點的狀態是滯後於主名稱節點的,所以如果主名稱節點掛掉,也必定會有一些檔案損失。

三、資料節點(DataNode):這是HDFS中具體儲存資料的地方,一般有多臺機器。除了提供儲存服務,它們還定時向名稱節點發送它們儲存的塊的列表,所以名稱節點沒有必要永久儲存每個檔案的每個塊所在的資料節點,這些資訊會在系統啟動後由資料節點重建。

2,MapReduce計算框架

這是一種分散式計算模型,其核心就是將任務分解成小任務由不同的計算者同時參與計算,並將各個計算者的計算結果合併得出最終的結果。模型本身非常簡單,一般只需要實現兩個介面即可;問題的關鍵在於怎樣將實際問題轉化為MapReduce任務。Hadoop的MapReduce部分主要由以下幾部分組成:

一、作業跟蹤節點(JobTracker):負責任務的排程(可以設定不同的排程策略)、狀態跟蹤。它的角色有點類似於HDFS中的名稱節點,JobTracker也是一個單點,在未來的版本中可能會有所改進。

二、任務跟蹤節點(TaskTracker):負責具體的任務的執行。它通過“心跳”的方式告知JobTracker其狀態,並由JobTracker根據其報告的狀態為其分配任務,TaskTracker會啟動一個新的JVM來執行一個任務,當然JVM例項也可以被重用。

以上就是對於Hadoop最重要的兩個部分的簡介,Hadoop存在的理由就是它適應於大資料的儲存計算。一個Hadoop叢集可以看成是一個儲存、計算“資料”的“庫”。

Hive是一個構建於Hadoop叢集之上的“資料倉庫”應用

Hive是Facebook開發的構建於Hadoop叢集之上的資料倉庫應用,它提供了類似於SQL語法的HQL語句作為資料訪問介面,這使得普通分析人員的應用Hadoop的學習曲線變緩。至於Facebook為什麼使用Hadoop和Hive組建其資料倉庫,其內部人員分享了他們的一些經歷,大致的過程是如下的:

1,Facebook的資料倉庫一開始是構建於MySQL之上的,但是隨著資料量的增加某些查詢需要幾個小時甚至幾天的時間才能完成。

2,當資料量接近1T的時候,mysqld後臺程序宕掉,這時他們決定將他們資料倉庫轉移到Oracle。當然這次轉移的過程也是付出了很大的代價的,比如支援的SQL方言不同,修改以前的執行指令碼等等。

3,Oracle應付幾T的資料還是沒有問題的,但是在開始收集使用者點選流的資料(每天大約400G)之後,Oracle也開始撐不住了,由此又要考慮新的資料倉庫方案。

4,內部開發人員花了幾周的時間建立了一個並行日誌處理系統Cheetah,這樣的話勉強可以在24小時之內處理完一天的點選流資料。

5,Cheetah也存在許多缺點。後來發現了Hadoop專案,並開始試著將日誌資料同時載入Cheetah和Hadoop做對比,Hadoop在處理大規模資料時更具優勢,後來將所有的工作流都從Cheetah轉移到了Hadoop,並基於Hadoop做了很多有價值的分析。

6,後來為了使組織中的多數人能夠使用Hadoop,開發了Hive,Hive提供了類似於SQL的查詢介面,非常方便。與此同時還開發了一些其它工具。

7,現在叢集儲存2.5PB的資料,並且以每天15TB的資料在增長,每天提交3000個以上的作業,大約處理55TB的資料...

現在很多大的網際網路公司出於成本考慮都在研究、使用Hadoop;資料的價值正得到越來越多的人的重視,而這種重視,又體現出Hadoop存在的巨大價值。

第一部分:Hive簡介

什麼是Hive

?Hive是基於Hadoop的一個數據倉庫工具,可以將結構化的資料檔案對映為一張資料庫表,並提供類SQL查詢功能。

?本質是將SQL轉換為MapReduce程式

第二部分:為什麼使用Hive

面臨的問題

  人員學習成本太高

  專案週期要求太短

  我只是需要一個簡單的環境

 MapReduce  如何搞定

  複雜查詢好難

  Join如何實現

為什麼要使用Hive

?操作介面採用類SQL語法,提供快速開發的能力

?避免了去寫MapReduce,減少開發人員的學習成本

?擴充套件功能很方便

Hive的特點

?可擴充套件

Hive可以自由的擴充套件叢集的規模,一般情況下不需要重啟服務

?延展性

Hive支援使用者自定義函式,使用者可以根據自己的需求來實現自己的函式

?容錯

良好的容錯性,節點出現問題SQL仍可完成執行

第三部分:Hive與Hadoop的關係

第四部分:Hive與傳統資料庫對比

     Hive     RDBMS

查詢語言   HQL     SQL

資料儲存   HDFS   Raw Device or Local FS

執行    MapReduce        Excutor

執行延遲   高 低

處理資料規模 大 小

索引    0.8版本後加入點陣圖索引      有複雜的索引

第五部分:Hive的歷史

?由FaceBook 實現並開源

?2011年3月,0.7.0版本 釋出,此版本為重大升級版本,增加了簡單索引,HAING等眾多高階特性

?2011年06月,0.7.1 版本釋出,修復了一些BUG,如在Windows上使用JDBC的的問題

? 2011年12月,0.8.0版本釋出,此版本為重大升級版本,增加了insert into 、HA等眾多高階特性

?2012年2月5日,0.8.1版本釋出,修復了一些BUG,如 使 Hive 可以同時執行在 Hadoop0.20.x 與 0.23.0

?2012年4月30日,0.9.0版本釋出,重大改進版本,增加了對Hadoop 1.0.0的支援、實現BETWEEN等特性

第六部分:Hive的未來發展 

?增加更多類似傳統資料庫的功能,如儲存過程

?提高轉換成的MapReduce效能

?擁有真正的資料倉庫的能力

?UI部分加強

1.6            雲平臺hadoop子專案HBASE

HBASE是一個在HDFS上開發的面向列的分散式資料庫,可以隨時讀寫超大規模的資料集。

HBase – HadoopDatabase,是一個高可靠性、高效能、面向列、可伸縮的分散式儲存系統,利用HBase技術可在廉價PC Server上搭建起大規模結構化儲存叢集。

HBase是GoogleBigtable的開源實現,類似Google Bigtable利用GFS作為其檔案儲存系統,HBase利用HadoopHDFS作為其檔案儲存系統;Google執行MapReduce來處理Bigtable中的海量資料,HBase同樣利用Hadoop MapReduce來處理HBase中的海量資料;Google Bigtable利用 Chubby作為協同服務,HBase利用Zookeeper作為對應。

上圖描述了HadoopEcoSystem中的各層系統,其中HBase位於結構化儲存層,Hadoop HDFS為HBase提供了高可靠性的底層儲存支援,Hadoop MapReduce為HBase提供了高效能的計算能力,Zookeeper為HBase提供了穩定服務和failover機制。

此外,Pig和Hive還為HBase提供了高層語言支援,使得在HBase上進行資料統計處理變的非常簡單。 Sqoop則為HBase提供了方便的RDBMS資料匯入功能,使得傳統資料庫資料向HBase中遷移變的非常方便。


HBase訪問介面

1.      Native Java API,最常規和高效的訪問方式,適合Hadoop MapReduce Job並行批處理HBase表資料

2.      HBase Shell,HBase的命令列工具,最簡單的介面,適合HBase管理使用

3.      Thrift Gateway,利用Thrift序列化技術,支援C++,PHP,Python等多種語言,適合其他異構系統線上訪問HBase表資料

4.      REST Gateway,支援REST 風格的Http API訪問HBase,解除了語言限制

5.      Pig,可以使用Pig Latin流式程式語言來操作HBase中的資料,和Hive類似,本質最終也是編譯成MapReduce Job來處理HBase表資料,適合做資料統計

6.      Hive,當前Hive的Release版本尚沒有加入對HBase的支援,但在下一個版本Hive 0.7.0中將會支援HBase,可以使用類似SQL語言來訪問HBase

HBase資料模型

Table & ColumnFamily

Row Key

Timestamp

Column Family

URI

Parser

r1

t3

url=http://www.taobao.com

title=天天特價

t2

host=taobao.com

t1

r2

t5

url=http://www.alibaba.com

content=每天…

t4

host=alibaba.com

Ø  Row Key: 行鍵,Table的主鍵,Table中的記錄按照Row Key排序

Ø  Timestamp: 時間戳,每次資料操作對應的時間戳,可以看作是資料的version number

Ø  Column Family:列簇,Table在水平方向有一個或者多個Column Family組成,一個Column Family中可以由任意多個Column組成,即Column Family支援動態擴充套件,無需預先定義Column的數量以及型別,所有Column均以二進位制格式儲存,使用者需要自行進行型別轉換。

Table & Region

當Table隨著記錄數不斷增加而變大後,會逐漸分裂成多份splits,成為regions,一個region由[startkey,endkey)表示,不同的region會被Master分配給相應的RegionServer進行管理:

-ROOT- &&.META. Table

HBase中有兩張特殊的Table,-ROOT-和.META.

Ø  .META.:記錄了使用者表的Region資訊,.META.可以有多個regoin

Ø  -ROOT-:記錄了.META.表的Region資訊,-ROOT-只有一個region

Ø  Zookeeper中記錄了-ROOT-表的location

Client訪問使用者資料之前需要首先訪問zookeeper,然後訪問-ROOT-表,接著訪問.META.表,最後才能找到使用者資料的位置去訪問,中間需要多次網路操作,不過client端會做cache快取。

MapReduce on HBase

在HBase系統上執行批處理運算,最方便和實用的模型依然是MapReduce,如下圖:

HBase Table和Region的關係,比較類似HDFS File和Block的關係,HBase提供了配套的TableInputFormat和TableOutputFormat API,可以方便的將HBase Table作為Hadoop MapReduce的Source和Sink,對於MapReduceJob應用開發人員來說,基本不需要關注HBase系統自身的細節。


HBase系統架構


Client

HBase Client使用HBase的RPC機制與HMaster和HRegionServer進行通訊,對於管理類操作,Client與HMaster進行RPC;對於資料讀寫類操作,Client與HRegionServer進行RPC

Zookeeper

Zookeeper Quorum中除了儲存了-ROOT-表的地址和HMaster的地址,HRegionServer也會把自己以Ephemeral方式註冊到 Zookeeper中,使得HMaster可以隨時感知到各個HRegionServer的健康狀態。此外,Zookeeper也避免了HMaster的 單點問題,見下文描述

HMaster

HMaster沒有單點問題,HBase中可以啟動多個HMaster,通過Zookeeper的MasterElection機制保證總有一個Master執行,HMaster在功能上主要負責Table和Region的管理工作:

1.      管理使用者對Table的增、刪、改、查操作

2.      管理HRegionServer的負載均衡,調整Region分佈

3.      在RegionSplit後,負責新Region的分配

4.      在HRegionServer停機後,負責失效HRegionServer 上的Regions遷移

HRegionServer


HRegionServer主要負責響應使用者I/O請求,向HDFS檔案系統中讀寫資料,是HBase中最核心的模組。

HRegionServer內部管理了一系列HRegion物件,每個HRegion對應了Table中的一個Region,HRegion中由多 個HStore組成。每個HStore對應了Table中的一個ColumnFamily的儲存,可以看出每個Column Family其實就是一個集中的儲存單元,因此最好將具備共同IO特性的column放在一個ColumnFamily中,這樣最高效。

HStore儲存是HBase儲存的核心了,其中由兩部分組成,一部分是MemStore,一部分是StoreFiles。MemStore是 Sorted Memory Buffer,使用者寫入的資料首先會放入MemStore,當MemStore滿了以後會Flush成一個StoreFile(底層實現是HFile), 當StoreFile檔案數量增長到一定閾值,會觸發Compact合併操作,將多個StoreFiles合併成一個StoreFile,合併過程中會進 行版本合併和資料刪除,因此可以看出HBase其實只有增加資料,所有的更新和刪除操作都是在後續的compact過程中進行的,這使得使用者的寫操作只要 進入記憶體中就可以立即返回,保證了HBaseI/O的高效能。當StoreFiles Compact後,會逐步形成越來越大的StoreFile,當單個StoreFile大小超過一定閾值後,會觸發Split操作,同時把當前 Region Split成2個Region,父Region會下線,新Split出的2個孩子Region會被HMaster分配到相應的HRegionServer 上,使得原先1個Region的壓力得以分流到2個Region上。下圖描述了Compaction和Split的過程:

在理解了上述HStore的基本原理後,還必須瞭解一下HLog的功能,因為上述的HStore在系統正常工作的前提下是沒有問題的,但是在分散式系統環境中,無法避免系統出錯或者宕機,因此一旦HRegionServer意外退出,MemStore中的記憶體資料將會丟失,這就需要引入HLog了。 每個HRegionServer中都有一個HLog物件,HLog是一個實現Write Ahead Log的類,在每次使用者操作寫入MemStore的同時,也會寫一份資料到HLog檔案中(HLog檔案格式見後續),HLog檔案定期會滾動出新的,並 刪除舊的檔案(已持久化到StoreFile中的資料)。當HRegionServer意外終止後,HMaster會通過Zookeeper感知 到,HMaster首先會處理遺留的 HLog檔案,將其中不同Region的Log資料進行拆分,分別放到相應region的目錄下,然後再將失效的region重新分配,領取 到這些region的HRegionServer在Load Region的過程中,會發現有歷史HLog需要處理,因此會Replay HLog中的資料到MemStore中,然後flush到StoreFiles,完成資料恢復。

HBase儲存格式

HBase中的所有資料檔案都儲存在HadoopHDFS檔案系統上,主要包括上述提出的兩種檔案型別:

1.      HFile, HBase中KeyValue資料的儲存格式,HFile是Hadoop的二進位制格式檔案,實際上StoreFile就是對HFile做了輕量級包裝,即StoreFile底層就是HFile

2.      HLog File,HBase中WAL(WriteAhead Log) 的儲存格式,物理上是Hadoop的SequenceFile

HFile

下圖是HFile的儲存格式:

首先HFile檔案是不定長的,長度固定的只有其中的兩塊:Trailer和FileInfo。正如圖中所示的,Trailer中有指標指向其他數 據塊的起始點。File Info中記錄了檔案的一些Meta資訊,例如:AVG_KEY_LEN, AVG_VALUE_LEN,LAST_KEY, COMPARATOR, MAX_SEQ_ID_KEY等。Data Index和Meta Index塊記錄了每個Data塊和Meta塊的起始點。

Data Block是HBase I/O的基本單元,為了提高效率,HRegionServer中有基於LRU的Block Cache機制。每個Data塊的大小可以在建立一個Table的時候通過引數指定,大號的Block有利於順序Scan,小號Block利於隨機查詢。 每個Data塊除了開頭的Magic以外就是一個個KeyValue對拼接而成, Magic內容就是一些隨機數字,目的是防止資料損壞。後面會詳細介紹每個KeyValue對的內部構造。

HFile裡面的每個KeyValue對就是一個簡單的byte陣列。但是這個byte數組裡麵包含了很多項,並且有固定的結構。我們來看看裡面的具體結構:

開始是兩個固定長度的數值,分別表示Key的長度和Value的長度。緊接著是Key,開始是固定長度的數值,表示RowKey的長度,緊接著是 RowKey,然後是固定長度的數值,表示Family的長度,然後是Family,接著是Qualifier,然後是兩個固定長度的數值,表示Time Stamp和Key Type(Put/Delete)。Value部分沒有這麼複雜的結構,就是純粹的二進位制資料了。

HLogFile

上圖中示意了HLog檔案的結構,其實HLog檔案就是一個普通的Hadoop Sequence File,Sequence File 的Key是HLogKey物件,HLogKey中記錄了寫入資料的歸屬資訊,除了table和region名字外,同時還包括 sequence number和timestamp,timestamp是“寫入時間”,sequence number的起始值為0,或者是最近一次存入檔案系統中sequence number。

HLog Sequece File的Value是HBase的KeyValue物件,即對應HFile中的KeyValue,可參見上文描述。

結束

本文對HBase技術在功能和設計上進行了大致的介紹,由於篇幅有限,本文沒有過多深入地描述HBase的一些細節技術。目前一淘的儲存系統就是基於HBase技術搭建的,後續將介紹“一淘分散式儲存系統”,通過實際案例來更多的介紹HBase應用。

1.7            雲平臺hadoop子專案ZOOKEEPER

zookeeper簡介

zookeeper是一個開源分散式的服務,它提供了分散式協作,分散式同步,配置管理等功能,是做為hadoop的分散式協調服務的. 其實現的功能與google的chubby基本一致.zookeeper的官方網站已經寫了一篇非常經典的概述性文章,請大家參閱:ZooKeeper: A DistributedCoordination Service for Distributed Applications

在此我僅花少量筆墨介紹下本文相關的內容。

在zookeeper的叢集中,各個節點共有下面3種角色和4種狀態:

  角色:leader,follower,observer

狀態:leading,following,observing,looking

除了observer和observing之外,其它的角色和狀態與下面將要介紹的Paxos演算法中的角色與狀態一一對應,我們將在下文中具體描述.

observer是zookeeper-3.3版本新新增的一個角色,在這裡有相關的介紹. 他們的引入是為了解決zookeeper叢集擴大後,由於網路可靠性下降可能導致的拜占庭將軍問題. observer的行為在大多數情況下與follower完全一致, 但是他們不參加選舉和投票, 而僅僅接受(observing)選舉和投票的結果.

zookeeper實現了一個層次名字空間(hierarchal name space)的資料模型, 它特別象一個檔案系統, 每個檔案被稱為znode, 一個znode除了自己包含一些資料外,還能擁有孩子節點.

存在下述的3種類型znode:

    Persistent Nodes: 永久有效地節點,除非client顯式的刪除,否則一直存在

    Ephemeral Nodes: 臨時節點,僅在建立該節點client保持連線期間有效,一旦連線丟失,zookeeper會自動刪除該節點

    Sequence Nodes: 順序節點,client申請建立該節點時,zk會自動在節點路徑末尾新增遞增序號,這種型別是實現分散式鎖,分散式queue等特殊功能的關鍵

Zookeeper Watch 定義如下:

    A watch event is one-time trigger, sent tothe client that set the watch, which occurs when the data for which the watchwas set changes.

在我看來,watch可以理解為一個分散式的回撥,當client關心的znodes發生變化時,zookeeper將會把訊息傳回到client,並導致client的訊息處理函式得到呼叫.zk的任何一個讀操作都能夠設定watch,例如:getData(), getChildren(),