Hadoop個人心得筆記之MapReduce

                                             MapReduce

目錄

                                             MapReduce

一、概述

二、序列化機制

三、分區

四、排序

五、合併

六、數據本地化策略

七、job的執行流程

八、Shuffle過程

1.Map端的Shuffle

注意:

2.Reduce端的Shuffle

注意:

3.Shuffle調優

九、小文件處理



一、概述

  1. 是Hadoop中的一套分佈式的計算框架
  2. 將整個計算過程拆分爲2個階段:Map階段和Reduce階段
  3. Map階段負責數據的整理,Reduce階段負責數據的彙總
  4. Reducer中的迭代器採用的是地址複用機制
  5. Reducer中的迭代器只能遍歷一次
  6. 如果Mapper和Reducer的結果類型一致,可以只設置一個
  7. 如果輸入路徑是一個文件,則MapReduce只處理這個文件;如果輸入的是一個目錄,則處理這個目錄下的所有的文件 --- 注意:如果文件以_開頭,則該文件會被跳過。在MapReduce中,_開頭的文件被認爲是隱藏文件不需要處理
  8. 在MapReduce中,如果不指定,默認鍵值之間用\t分隔
  9. 如果Reducer沒有業務邏輯,可以省略Reducer

二、序列化機制

  1. 在MapReduce中,要求被傳輸的數據必須能夠被序列化
  2. Hadoop中,序列化機制默認使用AVRO,但是Hadoop對AVRO的序列化機制進行了進一步的封裝,提供了更簡單的序列化機制
  3. 在Hadoop要想實現序列化,需要實現Writable,重寫其中的方法
  4. 在Hadoop中,序列化的時候,要求屬性不能爲null
  5. 案例:按人統計每一個的總流量 - cn.tedu.flow
  6. 練習:score.txt - 計算每一個人的總成績 - cn.tedu.serialscore

 

三、分區

  1. 分區在MapReduce中用於進行數據的分類
  2. 在MapReduce中,如果不指定,則默認只有1個分區
  3. 每一個分區都必須對應一個ReduceTask,每一個ReduceTask都會產生一個結果文件
  4. 在MapReduce對分區進行了編號,編號默認從0開始遞增
  5. 分區的頂級父類是Partitioner
  6. 在MapReduce中,默認使用的HashPartitioner
  7. 案例:分地區統計不同的人花費的總流量 - cn.tedu.partflow

 

四、排序

  1. 在MapReduce中,會對鍵做自動的排序 - 自然排序
  2. 如果自定義一個類產生的對象要想作爲鍵,那麼這個對象必須要允許被排序 - WritableComparable
  3. 多屬性排序的場景稱之爲二次排序
  4. 練習:profit2.txt - 先按照月份進行升序,如果月份一樣,則按照業績降序 - cn.tedu.sortprofit

 

五、合併

  1. 在MapReduce中,因爲默認只有1個Reduce,所以所有的計算壓力都會落在Reduce上,導致Reduce的計算性能成了整個MapReduce的瓶頸,所以爲了提高計算效率,可以在數據傳輸到Reduce之前先對數據進行一次整合,這個過程稱之爲合併 - Combine
  2. 合並不會影響最終的計算結果
  3. 一般而言,Combine和Reduce的邏輯是一致的,只需要在Driver中添加job.setCombinerClass(class);

 

六、數據本地化策略

  1. 當JobTracker接收到應用之後,會去訪問NameNode獲取要處理的文件信息
  2. NameNode將文件信息返回給JobTracker
  3. JobTracker收到文件信息之後會將文件進行切片(只包含切片信息不包含實際數據),一般習慣上,會將切片和切塊設置的一樣大。每一個切片會分給一個MapTask
  4. JobTracker會MapTask分發到TaskTracker來執行。在分發的時候,哪一個DataNode上有對應的Block,那麼MapTask就會分發這個節點上 - 數據本地化
  5. 數據本地化的目的:減少對網絡資源的消耗

 

                                

七、job的執行流程

  1. 客戶端提交一個job任務到JobTracker: hadoop jar xxx.jar
  2. JobTracker收集環境信息:
    1. 檢測類型是否匹配
    2. 檢測輸入/輸出路徑是否合法
  3. JobTracker給job分配一個全局遞增的jobid,然後將jobid返回給客戶端
  4. 客戶端收到jobid之後,將jar包提交到HDFS上
  5. 準備執行job任務
  6. JobTracker會將job任務進行劃分,劃分爲MapTask和ReduceTask,其中MapTask的數量由切片數量決定,ReduceTask的數量由Partitioner/numReduceTask決定
  7. JobTracker等待TaskTracker的心跳。一般TaskTracker和DataNode會設置爲同一個節點。當TaskTracker發送心跳信息的時候,這個時候JobTracker就會給TaskTracker分配任務。注意:在分配的時候,MapTask符合數據本地化策略(當TaskTracker上有這個數據的時候纔會將MapTask分給它),ReduceTask分配到相對空閒的節點上
  8. TaskTracker領取到任務之後,到對應的節點下載jar包 - 體現的思想:邏輯移動而數據固定
  9. TaskTracker會在本節點內啓動JVM子進程執行MapTask或者是ReduceTask - 注意:每一個MapTask或者ReduceTask都會啓動一次JVM子進程

 

八、Shuffle過程

1.Map端的Shuffle

  1. 每一個Split會分給一個MapTask來處理
  2. MapTask默認是對數據進行按行讀取,每讀取一行調用一次map方法
  3. map方法在處理完一行數據的時候會將數據寫出到緩衝區中
  4. 每一個MapTask都自帶了一個緩衝區,緩衝區維繫在內存中
  5. 緩衝區默認大小是100M
  6. 當緩衝區達到條件的時候,將緩衝區中的數據寫到本地磁盤上,這個過程稱之爲溢寫(Spill),產生的文件稱之爲溢寫文件
  7. 溢寫之後,後續產生的數據會繼續寫到緩衝區中
  8. 溢寫過程可能發生不止一次
  9. 當map將結果放到緩衝區中之後,結果在緩衝區中會進行分區和排序過程;如果指定了Combiner,那麼數據在緩衝區中還會進行合併
  10. 如果所有數據處理完成,但是有一部分數據在緩衝區中,那麼將緩衝區中的數據沖刷到上一次的溢寫文件中
  11. 因爲可能會產生多次溢寫,那麼會產生多個溢寫文件,在結果發往Reduce之前,會將多個溢寫文件進行合併(merge),將多個溢寫文件合併成一個結果文件

注意:

  1. 溢寫過程不一定會發生。如果沒有發生溢寫過程,則將緩衝區中的數據直接沖刷到最後的結果文件中;如果只有一次溢寫,那麼這個溢寫文件就是最後的結果文件
  2. merge過程也不一定發生
  3. 如果溢寫文件個數>=3個,那麼在merge過程中,自動進行一次combine(指定了Combiner)
  4. 在merge過程中,結果會進行整體的分區和排序
  5. 初始數據量並不能決定溢寫次數
  6. 閾值默認是0.8 - 即緩衝區的使用達到這個大小的80%的時候,就開始溢寫
  7. 緩衝區本質上是一個字節數組,而且是一個環形的緩衝區,目的是爲了重複利用緩衝區

2.Reduce端的Shuffle

  1. ReduceTask啓動fetch線程去MapTask上抓取數據,只抓取當前要處理的分區的數據,將抓取的數據放到文件中,每從一個MapTask中抓取到數據就會產生一個數據文件
  2. 抓取完數據之後,將這個數據文件再次進行merge
  3. 在merge過程中,對數據再次進行排序
  4. merge完成之後,將相同的鍵所對應的值放入一個List集合,然後利用List集合去產生迭代器,這個過程稱之爲分組(group)
  5. 每一組會調用一次reduce方法
  6. 每一個ReduceTask會產生一個結果文件

注意:

  1. 默認fetch線程的數量爲5,表示每一個ReduceTask會啓動5個線程去抓取數據
  2. fetch線程通過http請求去抓數據
  3. merge因子默認爲10,表示每10個數據文件進行一次合併,最後合成1個數據文件
  4. reduce閾值默認爲0.05,表示當有5%的MapTask結束,那麼啓動ReduceTask開始抓取數據

3.Shuffle調優

  1. 調大緩衝區,實際開發中,一般會將緩衝區設置爲250~400M左右
  2. 儘量添加Combiner,不是所有場景下都可以添加Combiner
  3. 調大緩衝區的閾值 - 這種方式不推薦
  4. 將MapTask的結果進行壓縮 - 這種方式能夠有效的減少網絡的傳輸時間 - 這種方式不算優化,只是在節點資源和網絡資源之間進行取捨
  5. 增加fetch線程的數量 - 考慮服務器的線程承載量
  6. 增大merge因子 - 不推薦
  7. 降低Reduce的閾值 - 不推薦

 

九、小文件處理

  1. 危害:
    1. 存儲:每一個小文件在存儲的時候都會產生一條元數據,如果存儲大量的小文件,會產生大量的元數據,導致NameNode的效率變低;如果小文件數量過多,可能會導致NameNode的內存崩潰
    1. 計算:每一個小文件都會作爲一個切片來處理,每一個切片要對應一個MapTask,意味着如果產生了大量的小文件,會對應大量的切片,則需要大量的MapTask來處理。導致整個集羣的併發量要增加,如果超過集羣的承載能力導致服務器宕機
  1. 處理手段:合併(將多個小文件合併成一個大文件、利用一個任務處理多個小文件)、壓縮
  2. 合併:
    1. 手動合併:手動編碼、合併工具
    2. har包 - Hadoop Archive
    3. CompositeInputFormat - 多源輸入
  3. har:將多個小文件合併成一個文件,並且達成一個har包
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章