hadoop 學習筆記

weixin_34023863發表於2016-05-31

MR的優勢

MapReduce與SETI(Search fo Extra—Terrestrial Intelligence)搜尋外星智慧 的計劃不同之處是,SETI的確招募了全球大量的志願計算機,不過它所發散出去的task是CPU高密度計算任務,廣大志願者貢獻的是CPU週期,而不是網路頻寬。例如需要處理儲存在HDFS上的log,海量的log統計需要切分任務,第一步要把各個任務所需資源傳輸到所在的計算節點,這裡依賴大量的網路頻寬。各個計算節點在maptask階段完全並行,計算結果輸出到HDFS上再進行分桶排序,進入到reduce階段。

  • 有大量資料在計算節點和儲存節點直接傳送,叢集需要大量頻寬支撐
  • 能夠依賴HDFS對大規模資料進行處理
  • MR程式設計簡單,邏輯清晰,不用考慮資料分流問題

MR過程

  • 一個MR(Job)是客戶端需要執行的一個工作單元,包括輸入資料,MR程式和配置資訊,Hadoop將job分成若干個task執行(map or reduce )task。
  • 兩個節點控制Job之心過程:
    Jobtracker以及一些列tasktracker。Jobtracker負責排程tasktracker上的任務以及收集tasktracker的執行狀態資訊,如果jobfail,jobtracker負責在其它tasktracker上重啟任務。
  • 輸入分片:
    Hadoop將MR輸入資料劃分成小資料塊,稱為輸入分片,一個大的輸入分成了N個分片,如果分片規模越小,那麼所有計算節點的負載會趨向均衡(叢集中各個計算節點的硬體配置不同,當前所承擔計算量也不同)。不過分片過小,分片過程就會佔用很高的時間,對於大多數作業,一個合理的分片趨向於HDFS的一個塊的大小,預設為64M,這樣儲存節點進行計算很有好處(不用對HDFS塊進行切分,也不會佔用叢集頻寬資源)。
  • map將結果寫入本地磁碟,reduce結果才會寫入HDFS.
  • shuffle:後面標題shuffle有詳細介紹


    1551474-8db07f50091cef26.JPG
    官方定義的shuffle
  • 啟動mr任務:
    Streaming 使用Unix標準輸入流作為Hadoop和應用程式之間的介面,也就是說可以用任何語言通過標準輸入輸出編寫MR程式。
    目前我用的是streaming,很方便配置各項引數。
  • 一個沒有用過的東西 Hadoop Pipes
    Hadoop Pipes 是Hadoop MR的C++介面名稱,並沒使用標準輸入輸出實現MR之間Streaming,Hadoop Pipes 使用socket作為tasktracker與C++版本map函式過著reduce函式的程式間的通道

HDFS

HDFS的設計
  • 流式資料訪問:一次寫入,多次讀取。
  • 商用硬體: Hadoop並不需要執行在高可靠的硬體上,事實上hadoop節點故障率不低,只不過被設計成可以繼續執行,使用者不易察覺。
  • 資料訪問延遲高,對於低延遲要求的訪問,不適合儲存在HDFS上。
  • 一個Hadoop叢集上所能儲存的檔案數量是受制於namenode節點記憶體的,所以不要儲存大量小檔案到HDFS上。
  • 不修改已經儲存的檔案
HDFS資料塊
  • 無力磁碟的資料塊大小一般為512B,作為讀寫資料的最小單位,類似的,HDFS也採取(block)的策略,一般預設儲存塊大小為64M,HDFS上的檔案也被劃分為塊級大小的分塊(chunk),作為獨立儲存單元,但是與其他檔案系統不同的是,HDFS中小於塊大小的檔案不會佔據整個塊空間。
  • 大資料塊的目的:減少定址開銷。
  • 分塊儲存的優勢:1、某檔案所需儲存空間可以大於叢集中任意磁碟的容量。2、使用塊而不是檔案作為儲存單元,簡化儲存子系統設計,例如許可權資訊,並不需要與塊一同儲存。3、Hadoop的儲存容錯系統也得益於HDFS的塊級儲存,備份時只針對塊進行穩定儲存,即使有檔案損壞也只是塊級損壞,只需要恢復塊級資料。

NAMENODE AND DATANODE

  • NameNode 管理檔案系統的名稱空間,維護整個檔案系統樹及整棵樹的檔案和目錄,這些資訊以檔案形式永久儲存在本地磁碟上:名稱空間映象檔案和編輯日誌檔案。
    如果NameNode節點壞掉,那麼整個檔案系統也隨之壞掉,因為我們丟失了所有檔案組織資訊,所以NameNode的容錯非常重要.
    1、第一種機制是備份組成檔案系統後設資料持久狀態的檔案,這些操作為實時同步的原子操作,一般是講持久狀態寫入本地磁碟的同時,寫入一個遠端掛在的網路檔案系統(NFS)
    2、另一種機制是執行一個輔助的NameNode,定期編輯日誌,合併空間映象。輔助節點儲存資料必然落後於NameNode,主節點失效必然丟失資料,一般把儲存在NFS上的後設資料回覆到輔助節點上作為新的NameNode。
  • DataNode同樣維護每個檔案中各個塊所在的資料節點資訊,但是並不永久儲存,這些資訊在系統reboot時有資料節點重建。它是檔案系統的工作節點,需要檢索並且儲存資料塊,定期向NameNode所儲存的傳送資料塊列表。
  • client代表使用者與NameNode 和DataNode互動訪問整個檔案系統。

client 與HDFS、NameNode、DataNode之間的資料流:

  • client通過呼叫open方法開啟希望讀取的檔案,HDFS通過RPC呼叫namenode ,namenode返回檔案每個塊的序列+datanode地址。
  • client通過create方法建立新檔案,HDFS通過RPC呼叫namenode,在檔案系統名稱空間中新建一個檔案,namenode檢查檔案不存在且使用者許可權符合標準,建立檔案並新增記錄,否則跑出IOException異常。資料通過DFSoutputstream組織成一個個資料包,組成資料佇列,在一組(一般是三個)datanode中通過管道線傳送,第一份副本優先選擇client所在的datanode,如果client不在本地,那麼隨機挑選一個儲存不太滿,不繁忙的datanode。第二份副本會切換機架選取一個datanode,第三份副本與第二副本同機架不同節點。
  • distcp應用場景
    典型應用場景是在兩個HDFS叢集之間傳送資料

Hadoop的IO操作

  • 資料完整性:
    資料第一次引入HDFS前計算校驗和,在通過不可靠的通道進行傳輸之後再次計算校驗和。其中寫資料的client將資料及其校驗和傳送到一系列datanode組成的管道線,管道線中的最後一個datanode負責驗證校驗和。
    不僅如此,每個datanode也會在後臺執行緒執行一個datablockscanner,定期驗證儲存在這個datanode上的所有資料塊。
  • 壓縮:
    為了節省儲存空間,節約頻寬,有時會需要對檔案進行壓縮處理。


    1551474-130ad06e5907832a.JPG
    壓縮格式總結.JPG

    可切分的壓縮格式包括bzip2 ,預處理過程中被索引過的LZO。

  • codec


    1551474-436a29f3ef67a6bd.JPG
    e3afd245-0fe3-4d5c-b643-8558fc87c175.JPG

    1551474-2b46e68263e45405.JPG
    某例項
  • 可切分:
    可切分就是說可以從壓縮劉資料的任意位置讀取資料。
    假如一個壓縮檔案為1G,在64M一塊的格式下分為16塊。如果是可切分的壓縮格式,這16塊可以作為16個MAP的輸入,反之,雖然儲存了16個資料塊,這16塊有隻能以一定順序進入一個MAP。

序列化

  • 序列化定義:序列化(serialization)是指將結構化物件轉化為位元組流一般在網路上傳輸或者寫入磁碟永久儲存的過程。反序列化(deserialization)是指將位元組流轉回結構化物件的逆過程。
  • 應用場景:程式間通訊和永久儲存 。 Hadoop節點程式間通訊就是通過RPC(remote procedure call)實現的。
    *Hadoop序列化格式:使用自己的序列化格式writable,它夠緊湊,速度快(可謂Hadoop的核心),但是不易被java意外的語言進行擴充或者使用。
    很明顯,writable介面有兩個方法,一個DataOutput 將結構化資料寫到二進位制流,一個DataInput方法讀取二進位制流資料。

HIVE VS HBASE

  • HIVE 資料倉儲儲存,一次儲存,多次訪問。可用partition分桶儲存,一般適用於全盤掃描的需求,例如分桶統計資料需要訪問某桶內全部資料,如果想要查詢某跳資料,顯然不是Hive擅長的工作,因為其沒有索引。
  • HBASE Key,Value形式按列儲存
    HBase作為面向列的資料庫執行在HDFS之上,HDFS缺乏隨即讀寫操作,HBase正是為此而出現。HBase以Google BigTable為藍本,以鍵值對的形式儲存。專案的目標就是快速在主機內數十億行資料中定位所需的資料並訪問它。
    HBase是一個資料庫,一個NoSql的資料庫,像其他資料庫一樣提供隨即讀寫功能,Hadoop不能滿足實時需要,HBase正可以滿足。如果你需要實時訪問一些資料,就把它存入HBase。
    你可以用Hadoop作為靜態資料倉儲,HBase作為資料儲存,放那些進行一些操作會改變的資料。

排程框架背景

在目前版本以及0。20版本系列中,mapred.job.tracker決定了執行MR程式的方式,如果被設定為local,則在單個JVM上執行整個作業,小資料集單機測試,如果被設定成主機+埠號,執行器將作業交給該地址的jobtracker。hadoop2.0引入了一種新的執行機制,稱為MR2,建立在一個名為YARN的系統上。目前執行框架通過mapreduce.framework.name屬性進行設定,local表示本地作業執行器,classic表示經典MR框架MR1,使用一個jobtracker和多個tasktracker,yarn表示新的框架。

經典MR框架組成

  • 客戶端:
    1、提交MR作業,檢查輸出目錄是否存在,計算作業的輸入分片(因為輸入路徑已經給定,根據檔案大小計算分片個數)
    2、將作業所需資源(作業JAR檔案,配置檔案和計算所得的輸入分片)複製到一個以作業ID明明的目錄下jobtracker的檔案系統中,告知jobtracker作業準備執行(通過呼叫Jobtracker的submitJob()圖中步驟4)
  • Jobtracker:
    協調作業執行。jobtracker是一個java應用程式,主類是JobTracker。
    1、接到submitjob後,將呼叫放入內部佇列,交由job scheduler排程,並對其封裝初始化
    2、為了建立任務執行列表,job scheduler首先從HDFS中獲取已經計算好的輸入分片,為每個分片建立任務
  • tasktracker:
    執行作業劃分後的任務,是一個java應用程式,主類是tasktracker。
    1、執行一個簡單的訊黃來定期傳送heartbeat給jobtracker,一為了表明tracker仍然存活,二充當訊息通道。
    2、對於map任務和reduce任務,tasktracker有固定的數量和任務槽,二者獨立設定,準確數量有tasktracker核心數和記憶體大小決定。預設排程器在處理reduce任務槽之前會填滿map任務槽。
    3、為了選擇reduce任務,jobtracker並不考慮資料本地化,直接從reduce任務列表中選取下一個,而對於map任務,則優先考慮tasktracker的網路位置,選取一個最近的輸入分片檔案,理想情況任務是資料本地化的(不過也可能是機架本地化)。
    4、現在tasktracker已經被分配了一個任務,第一步,從HDFS中把作業JAR檔案與應用程式所需的全部檔案複製到tasktracker所在的檔案系統,實現檔案本地化。第二步,為任務新建一個本地工作目錄,解壓JAR檔案。第三部,建立taskrunner例項執行該任務
    5、 taskrunner啟動一個新的JVM來執行每個任務,以便使用者定義的mr函式的任何軟體問題都不會影響到tasktracker(例如導致崩潰或者掛起),單殺不同任務之間重用JVM還是可能的。
    6、Streaming任務使用標準輸入輸出流與程式進行通訊
    ![Uploading 7ccf8386-6c9d-4bf6-bf5d-624f8419ae94_830239.JPG . . .]
1551474-52f923e6910dd4a4.JPG
Streaming與tasktracker機器子程式之間的關係
  • HDFS


    1551474-c3d2b13f29c406fd.JPG
    經典MR1作業啟動過程

YARN(MR2)

對於節點數量超出4000的大型叢集,MR1系統開始面臨擴充性的瓶頸,因此YARN(Yet Another Resource Nefotiator)

  • YARN將jobtracker只能劃分為多個獨立的實體,改善classicMR面臨擴充瓶頸的問題。Jobtracker負責作業排程和任務進度見識,追蹤任務、重啟失敗或者國漫的任務和進行任務等級等等。
    Yarn將這樑總角色劃分為兩個獨立的守護程式:管理叢集上資源使用的資源管理器(RM)和管理叢集上執行任務生命週期的應用管理器(AM)。
    基本思路是: AM與RM協商叢集上的計算資源:容器(每個容器都有特定的記憶體上限),在這些容器上執行特定的應用程式程式。
    容器由叢集節點上執行的節點管理器(NodeManager)監視,確保應用程式使用的資源不會超過分配給它的資源。
  • 每個例項(這裡指MR Job)有一個專用的應用master


    1551474-d745629b76ff9dce.JPG
    ![Uploading aa5479ab-1ee4-4eec-899c-f685eb09335e_962818.JPG . . .]
  • 一次任務的執行過程:
    作業提交:MR2中作業提交使用與MR1相同的API,MR2實現了ClientProtocol,當mapreduce.framework.name=yarn 啟動時,從RM而不是JOBTRACKER獲得Job_Id,然後計算輸入分片,在叢集上產生分片,並將作業資源(作業JAR,配置資訊,分片資訊輔助到HDFS),最後通過呼叫RM上的submitApplication()方法提交作業
    作業初始化:RM接收到submitApplication(),將訊息傳遞給排程器(scheduler),排程器分配一個容器,RM在節點管理器的管理下在容器中啟動應用程式的master程式。
    MR作業的AppMaster是一個java應用程式,它對作業進行初始化,通過建立多個簿記物件以保持對作業進度的跟蹤,因為它接受來自任務的進度和完成報告(步驟6)。接下來,他接受來自共享檔案系統的已經被計算好的輸入分片(步驟7)然後AM決定如何執行構成MR作業的各個任務,如果作業很小,就選擇在與它同一個JVM上執行任務。判定在一個節點上順序執行它們的開銷小於在新容器中分配執行的開銷的大,就會發生這種情況,稱為uberized,或者作為uber任務執行。MR1中不會在單tasktracker上執行小作業(例如10個mapper+1 reducer)。
    任務分配
    如果任務不適合作為uber任務執行,那麼AM為所有Map Reduce任務向RM請求容器(步驟8),並且指定記憶體需求,預設1G,通過mapreduce.map.memory.mb 和mapreduce.reduce.memory.mb設定。
    在記憶體分配方面,MR2對比與MR1,可以自行申請1G的整數倍的記憶體,而MR1只能是每個MR任務佔用固定的MR槽,導致小任務記憶體利用率低。
    任務執行
    一旦RM為任務分配了容器,AM就通過節點管理器通訊來啟動容器(步驟9ab),在它執行之前,首先將任務所需的資源本地化(包括作業配置JAR檔案和所有DFS上的檔案),最後執行Map or Reduce任務。
    進度和狀態更新
    Yarn執行時,任務每3s通過umbilical API想AM回報進度和狀態(包括計數器),相比之下MR1 通過TT 到JT實現進度更新。客戶端每秒查詢一次AM接受進度更新,通常向使用者顯示
    在MR1中,作業跟蹤器的WEB UI展示執行作業列表及其進度,在YARN中,RM的Web UI 展示了正在執行的APP以及連線到對應的AM,每個AM展示MR作業進度等進一步細節。
    1551474-546f44a34a4c73f7.JPG
    MR2系統中狀態更新的傳播

    作業完成
    出了向AM 查詢進度之外,客戶端每5s通過Job的waitForCompletion()檢查作業是否完成。
    作業完成後AM和任務容器清理其工作狀態,OutPutCommitter的作業清理方法會被呼叫,作業歷史伺服器儲存作業資訊以便需要時查詢。
    1551474-656dcfa48a3bbcb5.JPG

失敗

作業的失敗處理目前還不是很能影響到自身,所以優先將時間用在其它地方,此處留空

shuffle

  • 在Map階段 MAP的輸出首先存放在記憶體中一般預設有環狀100M的緩衝區,當緩衝區內資料使用量達到80%,那麼開始寫入tasknode本地磁碟。寫入磁碟過程:1、首先將資料最終要傳入的reducer分桶(partition),然後在每個分割槽中,按照鍵值進行排序(sort排序,combiner如果有的話,對map輸出進一步處理,減少向磁碟寫入的資料量)
  • Reduce階段,假如有M 個MAP任務, N個reduce任務, 每當有一個MAP任務報告完成, reduce任務就會立即訪問MAP產生的資料,並且按Key值拉取對應的partition 資料,所以說,reduce任務在最初階段就是在不斷的拉取所有Map任務的輸出。 reduce task node在不斷拉取Map輸出的同時,不斷的merge本地的map資料以達到有序(如果檔案大,那麼將存在磁碟山個,否則可以儲存在reduce node 的本地記憶體中),當最後一個Map任務結束之時,所有的reduce任務將完成最後一次本地資料merge,將所有資料排序後生成一個檔案,然後開始執行使用者自定義的reducer程式。

UDF

相關文章