hadoop一些相關知識

yu_lu發表於2024-06-19

大資料概念

  1. 什麼是大資料?

    大資料是指高速(velocity)湧現的大量(volume)多樣化(variety)具有一定價值(value)並且真實(veracity)的資料,其特性可簡單概括為5V。

  2. 原理流程

    1. 資料採集

    大資料首先需要將來自不同來源和應用的資料彙集在一起。需要匯入和處理資料、執行格式化操作,以符合業務分析所要求的形式。

    1. 資料儲存

    大資料對儲存要求較高。儲存解決方案可以部署在本地,也可以部署在雲端。可以採用任何形式儲存資料,根據需要為資料集設定處理要求,引入必要的處理引擎。

    1. 資料分析

    資料分析是根據資料內容及業務要求對資料進行處理的過程,在該過程中需要根據不同的資料量和業務形式選擇合適的處理引擎,大資料開發過程有時也會涉及到機器學習相關演算法

Hadoop簡介

Hadoop是一個適合海量資料的分散式儲存和分散式計算的平臺

hadoop的處理思想,分而治之

擴容能力(Scalable):能可靠(reliably)地儲存和處理PB級別的資料。如果資料量更大,儲存不下了,再增加節點就可以了。

成本低(Economical):可以透過普通機器組成的伺服器叢集來分發以及處理資料.這些伺服器叢集可達數千個節點。

高效率(Efficient):透過分發計算程式,hadoop可以在資料所在節點上(本地)並行地(parallel)處理他們,這使得處理非常的迅速

可靠性(Reliable):hadoop能夠自動地維護資料的多份副本,並且在任務失敗後能夠自動地重新部署(redeploy)計算任務.

hdfs shell 常用操作

  1. 上傳:hdfs dfs -put 本地路徑 HDFS路徑

  2. 下載:hdfs dfs -get HDFS路徑 本地路徑

  3. 建立目錄:hdfs dfs -mkdir HDFS路徑

  4. 檢視對應路徑中的內容:hdfs dfs -ls /

  5. 檢視檔案內容:

    • hdfs dfs -cat HDFS路徑
    • hdfs dfs -tail HDFS路徑
    • hdfs dfs -tail -f HDFS路徑 監聽HDFS中的檔案內容
    • hdfs dfs -text HDFS路徑 可以檢視被Hadoop壓縮的壓縮檔案
  6. 追加資訊到檔案中:hdfs dfs -appendToFile words.txt /input/words.txt

  7. 刪除檔案: hdfs dfs -rm -r -f /output

  8. 檢視指定目錄下對應空間佔用情況:hdfs dfs -du -h /

  9. 複製:hdfs dfs -cp 源路徑 目標路徑

  10. 重新命名:hdfs dfs -mv 源路徑 目標路徑

  11. 修改檔案許可權:hdfs dfs -chmod 735 目標路徑

  12. 檢視儲存空間:hdfs dfs -df 檢視整個HDFS中空間使用情況

  13. 檢視狀態:hdfs dfsadmin -report

儲存時遇到的問題

  1. 資料需要切成多少塊,每塊的大小是多少?

    HDFS中的檔案會被分割成若干個塊(Block)進行儲存。預設情況下,每個塊的大小為128MB(在早期版本中預設是64MB)。你可以根據具體需求在HDFS配置中調整塊的大小。

  2. 資料是以什麼樣的形式儲存,是否可以進行壓縮?

    資料在HDFS中以塊的形式儲存,每個塊在磁碟上都是一個檔案。HDFS支援多種資料壓縮格式,如Gzip等。壓縮資料可以減少儲存空間並提高I/O效能。壓縮與解壓縮操作通常在資料讀寫時由MapReduce等計算框架處理。

  3. 資料的儲存位置,提供一個標準?

    HDFS使用主從架構,由一個NameNode和多個DataNode組成。NameNode負責管理檔案系統的名稱空間和後設資料,DataNode負責實際儲存資料塊。每個資料塊在叢集中的多個DataNode上有多個副本(預設是3個),以保證資料的高可用性和可靠性。

  4. 需要將資料的儲存位置記錄在某個地方,對應的順序?

    NameNode記錄所有資料塊的位置及其對應的DataNode。它維護檔案系統的後設資料,包括檔案到塊的對映、塊到DataNode的對映、檔案的訪問許可權等。客戶端訪問檔案時,NameNode提供所需的後設資料資訊。

  5. 對於檔案的描述資訊需要進行儲存(對資料的描述資訊以及儲存位置等稱後設資料)?

    NameNode儲存了所有的後設資料,包括:

    • 檔案到塊的對映
    • 塊到DataNode的對映
    • 檔案的目錄結構
    • 檔案和目錄的許可權、所有者和時間戳資訊

    這些後設資料儲存在NameNode的記憶體中,並定期寫入磁碟中的FsImage檔案和編輯日誌(Edits log)以保證資料的永續性

  6. 對於儲存的資料如果丟失了一部分,那麼該怎麼處理?

    HDFS透過副本機制來處理資料丟失問題。每個資料塊有多個副本,分佈在不同的DataNode上。具體處理機制如下:

    • 資料塊丟失監測:NameNode會週期性地與DataNode通訊,檢查每個塊的健康狀態。如果某個塊的副本少於指定數量(通常是3個),就認為資料塊丟失。
    • 資料塊重複制:NameNode會選擇新的DataNode來建立丟失副本的副本,從剩餘的健康副本複製資料塊。這一過程自動進行,保證了資料的高可用性。

    透過這些機制,HDFS保證了資料的可靠性和高可用性,即使部分DataNode失效或資料塊丟失,也能快速恢復資料。

  7. 資料持久化

    記憶體中會存在這樣的問題:記憶體當斷電時,會導致記憶體資料丟失,為了保證資料的安全性,於是需要將資料進行持久化操作,持久化是將資料儲存在磁碟當中,如果對記憶體中的資料,直接將資料以快照的形式儲存在磁碟中,會導致部分的資料可能會存在丟失,那麼如果以客戶端操作命令將其追加到磁碟檔案中,那麼會導致最終的持久化檔案會非常大

    針對上述的問題,又如下策略:

    1. 將客戶端中的操作記錄不斷的儲存到一個檔案中成為edits檔案
    2. 於是需要定期的將edits檔案和記憶體中的資料進行合併,生成對應的fsimage檔案

    edits檔案儲存了部分使用者的所有操作記錄

    fsimage檔案時儲存了部分後設資料資訊的

    1、當Hadoop第一次安裝啟動後,會先在Data目錄下生成空的edits檔案和空的fsimage檔案,edits檔案用於追加使用者的寫和修改操作記錄
    2、當程式在不斷的執行過程中,由於客戶端會不斷上傳修改檔案,導致edits檔案很大,於是當SecondaryNameNode發起Checkpoint請求之後,所有客戶端的寫操作追加到一個新的edits檔案
    3、對於Secondary NameNode 會將Fsimage檔案和edits檔案合併生成一個新的Fsimage檔案
    4、當Hadoop要重啟之後,原先記憶體中的資料都消失了,之後透過NameNode載入新的edits檔案和新的Fslmage檔案到記憶體中進行合併就生成完成的後設資料資訊了

    Secondary NameNode的checkpoins請求觸發的機制:

    1.CheckPoint發起時機:1.fs.checkpoint.period指定兩次checkpiont的最大時間間隔,預設3600秒。

    2.fs.checkpoint.size 規定edits檔案的最大值,一旦超過這個值則強制checkpoint,不管是否到達最大時間間隔預設大小是64M

Hadoop分散式叢集中計算存在的問題

  1. 如果要對巨大量的單個檔案資料進行計算,那麼單臺計算機不能完成工作,需要使用多臺伺服器,每臺伺服器處理多少的資料量?

    在Hadoop中,檔案被分成多個塊(block),每個塊的大小可以配置(預設128MB)。當對一個巨大的單個檔案進行計算時,這些塊會被分配到不同的DataNode(資料節點)上進行並行處理。Hadoop透過MapReduce來實現這種分散式計算。

    • Map階段
      • 輸入檔案被切分成多個塊。
      • 每個塊被分配給一個Mapper任務,Mapper會讀取該塊並進行相應的處理。
      • 多個Mapper任務並行執行,處理不同的塊。
    • 處理的資料量
      • 每個Mapper任務處理一個塊的資料。由於塊的大小是固定的(比如128MB),所以每臺伺服器(執行Mapper任務的DataNode)處理的資料量就是塊大小乘以該伺服器上執行的Mapper任務數量。
      • 伺服器的數量和每個伺服器上Mapper任務的數量取決叢集的規模和配置。
  2. 如果每個伺服器處理自身儲存的資料,那麼最終的結果如何進行彙集到一個或多個計算機中進行求和計算?

    • Shuffle和Sort階段
      • Map任務輸出的結果(中間資料)會經過Shuffle階段,將具有相同鍵的記錄傳送到同一個Reduce任務。
      • Shuffle階段包括資料的分組和排序,為Reduce任務做準備。
    • Reduce階段
      • Reduce任務接收到由Shuffle階段整理好的資料進行彙總處理。
      • Reduce任務可以計算區域性彙總,例如求和操作。
    • 最終結果的彙集
      • 多個Reduce任務的輸出結果可以寫到HDFS中,形成最終結果檔案。
      • 結果可以在單個Reduce任務中完成,也可以透過後處理。

MapReduce

常用的writable實現類

  • 布林型(boolean) BooleanWritable
  • 位元組型(byte) ByteWritable
  • 整型(int)IntWritable / VIntWritable
  • 浮點型(float) FloatWritable
  • 雙精度浮點型(double) DoubleWritable
  • 長整型(long) LongWritable / VLongWritable
  • 字串 String Text

mapreduce中的方法

  1. 小檔案合併

    當MapReduce的資料來源中小檔案過多,那麼根據FileInputFormat類中GetSplit函式載入資料,會產生大量的切片從而啟動過多的MapTask任務,MapTask啟動過多那麼會導致申請過多資源,並且MapTask啟動較慢,執行過程較長,效率較低

    如何解決?

    ​ 可以使用MR中的CombineTextInputFormat類,在形成資料切片時,可以對小檔案進行合併。

  2. 輸出類

    對於文字檔案輸出MapReduce中使用FileOutputFormat類作為預設輸出類,但是如果要對輸出的結果檔案進行修改,那麼需要對輸出過程進行自定義。
    而自定義輸出類需要繼承FileOutputFormat 並在RecordWriter中根據輸出邏輯將對應函式進行重寫

  3. 關聯分析

    map階段的主要任務是對不同檔案中的資料打標籤

    reduce階段進行實際的連線操作

  4. 過濾

    在MapReduce過程中可以根據判斷邏輯選擇適當的資料進行寫出,同時MapReduce過程中允許只存在有Map過程

  5. 序列化

    序列化 (Serialization)是將物件的狀態資訊轉換為可以儲存或傳輸的形式的過程。在序列化期間,物件將其當前狀態寫入到臨時或永續性儲存區。以後,可以透過從儲存區中讀取或反序列化物件的狀態,重新建立該物件。

    當兩個程序在進行遠端通訊時,彼此可以傳送各種型別的資料。無論是何種型別的資料,都會以二進位制序列的形式在網路上傳送。傳送方需要把這個物件轉換為位元組序列,才能在網路上傳送;接收方則需要把位元組序列再恢復為物件。把物件轉換為位元組序列的過程稱為物件的序列化。把位元組序列恢復為物件的過程稱為物件的反序列化。

    在Hadoop中可以自定義序列化類。

    透過實現WritableComparable介面,寫出write(序列化操作)和readFields(去序列化操作)方法。

MapReduce最佳化

  1. IO階段:

    問題:大量的網路傳輸,會降低MR執行效率

    解決方案:

    • 採用資料壓縮的方式,減少網路IO的時間
    • 透過Combine或者提前過濾資料減少資料傳輸量
    • 適當備份,因為備份多可以本地化生成map任務
  2. Reduce階段

    執行效率慢

    解決方案:

    • 合理設定Reduce數量
    • 使用MapJoin規避使用Reduce,減少shuffle
    • 使Key分配均勻,避免資料傾斜的產生
  3. 資料輸入

    問題:合併小檔案:因為大量小檔案會產生大量的Map任務,而任務的裝載比較耗時,從而導致MR執行較慢

    解決方案:

    • 在讀取計算前,對小檔案進行合併
  4. Map階段

    多次溢寫會產生多個溢寫檔案,並且最終需要合併成一個結果檔案

    解決方案:

    • 增大觸發spill的記憶體上限,減少spill次數,從而減少磁碟IO

      ​ io.sort.mb:環形緩衝區大小

      ​ sort.spill.percent:預設溢位率為(80%)

    • 不影響業務邏輯前提下,先進行Combine處理,減少I/O

MapReduce進階

mapreduce預設輸入處理類

InputFormat:抽象類,只是定義了兩個方法

FileInputFormat:

  • FileInputFormat是所有以檔案作為資料來源的InputFormat實現的基類,FileInputFormat儲存作為job輸入的所有檔案,並實現了對輸入檔案計算splits的方法。至於獲得記錄的方法是有不同的子類——TextInputFormat進行實現的。

TextInputFormat:

  • 是預設的處理類,處理普通文字檔案
  • 檔案中每一行作為一個記錄,他將每一行在檔案中的起始偏移量作為key,每一行的內容作為value
  • 預設以\n或Enter鍵作為一行記錄

RecordReader

每一個InputSplit都有一個RecordReader,作用是把InputSplit中的資料解析成Record,即<k1,v1>。

在TextInputFormat中的RecordReader是LineRecordReader,每一行解析成一個<k1,v1>。其中,k1表示偏移量,v1表示行文字內容

shuffle

廣義的Shuffle過程是指,在Map函式輸出資料之後並且在Reduce函式執行之前的過程。在Shuffle過程中,包含了對資料的分割槽、溢寫、排序、合併等操作

Shuffle原始碼主要的內容包含在 MapOutputCollector 的子實現類中,而該類物件表示的就是緩衝區的物件,該類中的函式有如下:

public void init(Context context
             ) throws IOException, ClassNotFoundException;
public void collect(K key, V value, int partition
                ) throws IOException, InterruptedException;
public void close() throws IOException, InterruptedException;

public void flush() throws IOException, InterruptedException, 
                        ClassNotFoundException;

自定義分割槽

預設分割槽下,如果Reduce的數量大於1,那麼會使用HashPartitioner對Key進行做Hash計算,之後再對計算得到的結果使用reduce數量進行取餘得到分割槽編號,每個reduce獲取固定編號中的資料進行處理

自定義分割槽需要重寫分割槽方法,根據不同的資料計算得到不同的分割槽編號

// 新增自定義分割槽類
job.setPartitionerClass(Partitioner.class);
// 按照需求給出分割槽個數
job.setNumReduceTasks();

Combine

combiner發生在map端的reduce操作。

  • 作用是減少map端的輸出,減少shuffle過程中網路傳輸的資料量,提高作業的執行效率。
  • combiner僅僅是單個map task的reduce,沒有對全部map的輸出做reduce。

如果不用combiner,那麼,所有的結果都是reduce完成,效率會相對低下。使用combiner,先完成的map會在本地聚合,提升速度。

注意:Combiner的輸出是Reducer的輸入,Combiner絕不能改變最終的計算結果。所以,Combine適合於等冪操作,比如累加,最大值等。求平均數不適合

YARN

YARN的核心概念

  1. ResourceManager(RM)
    • 負責叢集的資源管理和分配
    • 包括兩個主要元件:排程器(Scheduler)和應用程式管理器(ApplicationManager)。
  2. NodeManager(NM)
    • 負責叢集的資源管理和分配。
    • 包括兩個主要元件:排程器(Scheduler)和應用程式管理器(ApplicationManager)。
  3. ApplicationMaster(AM):
    • 每個應用程式(如MapReduce作業)都有一個專門的ApplicationMaster,負責申請資源並與NodeManger協調以執行任務。
  4. Container:
    • 資源的抽象表示,包含特定數量的CPU、記憶體等資源。任務在容器中執行。

yarn工作流程

yarn是如何執行一個mapreduce job的?

首先,Resource Manager會為每一個application(比如一個使用者提交的MapReduce Job) 在NodeManager裡面申請一個container,然後在該container裡面啟動一個Application Master。 container在Yarn中是分配資源的容器(記憶體、cpu、硬碟等),它啟動時便會相應啟動一個JVM。然後,Application Master便陸續為application包含的每一個task(一個Map task或Reduce task)向Resource Manager申請一個container。等每得到一個container後,便要求該container所屬的NodeManager將此container啟動,然後就在這個container裡面執行相應的task
等這個task執行完後,這個container便會被NodeManager收回,而container所擁有的JVM也相應地被退出。

yarn 排程器

  1. FIFO Scheduler也叫先進先出排程器,根據業務提交的順序,排成一個佇列,先提交的先執行,並且執行時可以申請整個叢集中的資源。邏輯簡單,使用方便,但是容易導致其他應用獲取資源被阻塞,所以生產過程中很少使用該排程器
  2. Capacity Scheduler 也稱為容量排程器,是Apache預設的排程策略,對於多個部門同時使用一個叢集獲取計算資源時,可以為每個部門分配一個佇列,而每個佇列中可以獲取到一部分資源,並且在佇列內部符合FIFO Scheduler排程規則
  3. Fair Scheduler 也稱為公平排程器,現在是CDH預設的排程策略,公平排程在也可以在多個佇列間工作,並且該策略會動態調整每個作業的資源使用情況