大資料概念
-
什麼是大資料?
大資料是指高速(velocity)湧現的大量(volume)多樣化(variety)具有一定價值(value)並且真實(veracity)的資料,其特性可簡單概括為5V。
-
原理流程
- 資料採集
大資料首先需要將來自不同來源和應用的資料彙集在一起。需要匯入和處理資料、執行格式化操作,以符合業務分析所要求的形式。
- 資料儲存
大資料對儲存要求較高。儲存解決方案可以部署在本地,也可以部署在雲端。可以採用任何形式儲存資料,根據需要為資料集設定處理要求,引入必要的處理引擎。
- 資料分析
資料分析是根據資料內容及業務要求對資料進行處理的過程,在該過程中需要根據不同的資料量和業務形式選擇合適的處理引擎,大資料開發過程有時也會涉及到機器學習相關演算法
Hadoop簡介
Hadoop是一個適合海量資料的分散式儲存和分散式計算的平臺
hadoop的處理思想,分而治之
擴容能力(Scalable):能可靠(reliably)地儲存和處理PB級別的資料。如果資料量更大,儲存不下了,再增加節點就可以了。
成本低(Economical):可以透過普通機器組成的伺服器叢集來分發以及處理資料.這些伺服器叢集可達數千個節點。
高效率(Efficient):透過分發計算程式,hadoop可以在資料所在節點上(本地)並行地(parallel)處理他們,這使得處理非常的迅速
可靠性(Reliable):hadoop能夠自動地維護資料的多份副本,並且在任務失敗後能夠自動地重新部署(redeploy)計算任務.
hdfs shell 常用操作
上傳:hdfs dfs -put 本地路徑 HDFS路徑
下載:hdfs dfs -get HDFS路徑 本地路徑
建立目錄:hdfs dfs -mkdir HDFS路徑
檢視對應路徑中的內容:hdfs dfs -ls /
檢視檔案內容:
- hdfs dfs -cat HDFS路徑
- hdfs dfs -tail HDFS路徑
- hdfs dfs -tail -f HDFS路徑 監聽HDFS中的檔案內容
- hdfs dfs -text HDFS路徑 可以檢視被Hadoop壓縮的壓縮檔案
追加資訊到檔案中:hdfs dfs -appendToFile words.txt /input/words.txt
刪除檔案: hdfs dfs -rm -r -f /output
檢視指定目錄下對應空間佔用情況:hdfs dfs -du -h /
複製:hdfs dfs -cp 源路徑 目標路徑
重新命名:hdfs dfs -mv 源路徑 目標路徑
修改檔案許可權:hdfs dfs -chmod 735 目標路徑
檢視儲存空間:hdfs dfs -df 檢視整個HDFS中空間使用情況
檢視狀態:hdfs dfsadmin -report
儲存時遇到的問題
-
資料需要切成多少塊,每塊的大小是多少?
HDFS中的檔案會被分割成若干個塊(Block)進行儲存。預設情況下,每個塊的大小為128MB(在早期版本中預設是64MB)。你可以根據具體需求在HDFS配置中調整塊的大小。
-
資料是以什麼樣的形式儲存,是否可以進行壓縮?
資料在HDFS中以塊的形式儲存,每個塊在磁碟上都是一個檔案。HDFS支援多種資料壓縮格式,如Gzip等。壓縮資料可以減少儲存空間並提高I/O效能。壓縮與解壓縮操作通常在資料讀寫時由MapReduce等計算框架處理。
-
資料的儲存位置,提供一個標準?
HDFS使用主從架構,由一個NameNode和多個DataNode組成。NameNode負責管理檔案系統的名稱空間和後設資料,DataNode負責實際儲存資料塊。每個資料塊在叢集中的多個DataNode上有多個副本(預設是3個),以保證資料的高可用性和可靠性。
-
需要將資料的儲存位置記錄在某個地方,對應的順序?
NameNode記錄所有資料塊的位置及其對應的DataNode。它維護檔案系統的後設資料,包括檔案到塊的對映、塊到DataNode的對映、檔案的訪問許可權等。客戶端訪問檔案時,NameNode提供所需的後設資料資訊。
-
對於檔案的描述資訊需要進行儲存(對資料的描述資訊以及儲存位置等稱後設資料)?
NameNode儲存了所有的後設資料,包括:
- 檔案到塊的對映
- 塊到DataNode的對映
- 檔案的目錄結構
- 檔案和目錄的許可權、所有者和時間戳資訊
這些後設資料儲存在NameNode的記憶體中,並定期寫入磁碟中的FsImage檔案和編輯日誌(Edits log)以保證資料的永續性
-
對於儲存的資料如果丟失了一部分,那麼該怎麼處理?
HDFS透過副本機制來處理資料丟失問題。每個資料塊有多個副本,分佈在不同的DataNode上。具體處理機制如下:
- 資料塊丟失監測:NameNode會週期性地與DataNode通訊,檢查每個塊的健康狀態。如果某個塊的副本少於指定數量(通常是3個),就認為資料塊丟失。
- 資料塊重複制:NameNode會選擇新的DataNode來建立丟失副本的副本,從剩餘的健康副本複製資料塊。這一過程自動進行,保證了資料的高可用性。
透過這些機制,HDFS保證了資料的可靠性和高可用性,即使部分DataNode失效或資料塊丟失,也能快速恢復資料。
-
資料持久化
記憶體中會存在這樣的問題:記憶體當斷電時,會導致記憶體資料丟失,為了保證資料的安全性,於是需要將資料進行持久化操作,持久化是將資料儲存在磁碟當中,如果對記憶體中的資料,直接將資料以快照的形式儲存在磁碟中,會導致部分的資料可能會存在丟失,那麼如果以客戶端操作命令將其追加到磁碟檔案中,那麼會導致最終的持久化檔案會非常大
針對上述的問題,又如下策略:
- 將客戶端中的操作記錄不斷的儲存到一個檔案中成為edits檔案
- 於是需要定期的將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分散式叢集中計算存在的問題
-
如果要對巨大量的單個檔案資料進行計算,那麼單臺計算機不能完成工作,需要使用多臺伺服器,每臺伺服器處理多少的資料量?
在Hadoop中,檔案被分成多個塊(block),每個塊的大小可以配置(預設128MB)。當對一個巨大的單個檔案進行計算時,這些塊會被分配到不同的DataNode(資料節點)上進行並行處理。Hadoop透過MapReduce來實現這種分散式計算。
- Map階段:
- 輸入檔案被切分成多個塊。
- 每個塊被分配給一個Mapper任務,Mapper會讀取該塊並進行相應的處理。
- 多個Mapper任務並行執行,處理不同的塊。
- 處理的資料量:
- 每個Mapper任務處理一個塊的資料。由於塊的大小是固定的(比如128MB),所以每臺伺服器(執行Mapper任務的DataNode)處理的資料量就是塊大小乘以該伺服器上執行的Mapper任務數量。
- 伺服器的數量和每個伺服器上Mapper任務的數量取決叢集的規模和配置。
- Map階段:
-
如果每個伺服器處理自身儲存的資料,那麼最終的結果如何進行彙集到一個或多個計算機中進行求和計算?
- Shuffle和Sort階段:
- Map任務輸出的結果(中間資料)會經過Shuffle階段,將具有相同鍵的記錄傳送到同一個Reduce任務。
- Shuffle階段包括資料的分組和排序,為Reduce任務做準備。
- Reduce階段:
- Reduce任務接收到由Shuffle階段整理好的資料進行彙總處理。
- Reduce任務可以計算區域性彙總,例如求和操作。
- 最終結果的彙集:
- 多個Reduce任務的輸出結果可以寫到HDFS中,形成最終結果檔案。
- 結果可以在單個Reduce任務中完成,也可以透過後處理。
- Shuffle和Sort階段:
MapReduce
常用的writable實現類
- 布林型(boolean) BooleanWritable
- 位元組型(byte) ByteWritable
- 整型(int)IntWritable / VIntWritable
- 浮點型(float) FloatWritable
- 雙精度浮點型(double) DoubleWritable
- 長整型(long) LongWritable / VLongWritable
- 字串 String Text
mapreduce中的方法
-
小檔案合併
當MapReduce的資料來源中小檔案過多,那麼根據FileInputFormat類中GetSplit函式載入資料,會產生大量的切片從而啟動過多的MapTask任務,MapTask啟動過多那麼會導致申請過多資源,並且MapTask啟動較慢,執行過程較長,效率較低
如何解決?
可以使用MR中的CombineTextInputFormat類,在形成資料切片時,可以對小檔案進行合併。
-
輸出類
對於文字檔案輸出MapReduce中使用FileOutputFormat類作為預設輸出類,但是如果要對輸出的結果檔案進行修改,那麼需要對輸出過程進行自定義。
而自定義輸出類需要繼承FileOutputFormat 並在RecordWriter中根據輸出邏輯將對應函式進行重寫 -
關聯分析
map階段的主要任務是對不同檔案中的資料打標籤
reduce階段進行實際的連線操作
-
過濾
在MapReduce過程中可以根據判斷邏輯選擇適當的資料進行寫出,同時MapReduce過程中允許只存在有Map過程
-
序列化
序列化 (Serialization)是將物件的狀態資訊轉換為可以儲存或傳輸的形式的過程。在序列化期間,物件將其當前狀態寫入到臨時或永續性儲存區。以後,可以透過從儲存區中讀取或反序列化物件的狀態,重新建立該物件。
當兩個程序在進行遠端通訊時,彼此可以傳送各種型別的資料。無論是何種型別的資料,都會以二進位制序列的形式在網路上傳送。傳送方需要把這個物件轉換為位元組序列,才能在網路上傳送;接收方則需要把位元組序列再恢復為物件。把物件轉換為位元組序列的過程稱為物件的序列化。把位元組序列恢復為物件的過程稱為物件的反序列化。
在Hadoop中可以自定義序列化類。
透過實現WritableComparable介面,寫出write(序列化操作)和readFields(去序列化操作)方法。
MapReduce最佳化
-
IO階段:
問題:大量的網路傳輸,會降低MR執行效率
解決方案:
- 採用資料壓縮的方式,減少網路IO的時間
- 透過Combine或者提前過濾資料減少資料傳輸量
- 適當備份,因為備份多可以本地化生成map任務
-
Reduce階段
執行效率慢
解決方案:
- 合理設定Reduce數量
- 使用MapJoin規避使用Reduce,減少shuffle
- 使Key分配均勻,避免資料傾斜的產生
-
資料輸入
問題:合併小檔案:因為大量小檔案會產生大量的Map任務,而任務的裝載比較耗時,從而導致MR執行較慢
解決方案:
- 在讀取計算前,對小檔案進行合併
-
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的核心概念
- ResourceManager(RM):
- 負責叢集的資源管理和分配
- 包括兩個主要元件:排程器(Scheduler)和應用程式管理器(ApplicationManager)。
- NodeManager(NM):
- 負責叢集的資源管理和分配。
- 包括兩個主要元件:排程器(Scheduler)和應用程式管理器(ApplicationManager)。
- ApplicationMaster(AM):
- 每個應用程式(如MapReduce作業)都有一個專門的ApplicationMaster,負責申請資源並與NodeManger協調以執行任務。
- 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 排程器
- FIFO Scheduler也叫先進先出排程器,根據業務提交的順序,排成一個佇列,先提交的先執行,並且執行時可以申請整個叢集中的資源。邏輯簡單,使用方便,但是容易導致其他應用獲取資源被阻塞,所以生產過程中很少使用該排程器
- Capacity Scheduler 也稱為容量排程器,是Apache預設的排程策略,對於多個部門同時使用一個叢集獲取計算資源時,可以為每個部門分配一個佇列,而每個佇列中可以獲取到一部分資源,並且在佇列內部符合FIFO Scheduler排程規則
- Fair Scheduler 也稱為公平排程器,現在是CDH預設的排程策略,公平排程在也可以在多個佇列間工作,並且該策略會動態調整每個作業的資源使用情況