什麼是Hadoop
Hadoop項目主要包括以下四個模塊:
Hadoop Common 爲其他Hadoop模塊提供基礎設施
Hadoop HDFS 一個高可靠,高吞吐量的分佈式文件系統
Hadoop MapReduce 一個分佈式離線並行計算框架
Hadoop Yarn 一個新的MapReduce 框架,任務調度與資源處理
Hadoop體系結構
HDFS和MapReduce是Hadoop的核心,Hadoop就是靠HDFS來實現分佈式存儲的支持,通過MapReduce來進行並行計算處理。
HDFS體系結構
HDFS採用了主從結構模型即採用Master-Slaver模式,HDFS集羣是有一個NameNode和多個DataNode組成的。 NameNode中心服務器(Master):維護文件系統樹、以及整棵樹內的文件目錄、負責整個數據集羣的管理。
DataNode分佈在不同的機架上(Slaver):在客戶端或者NameNode的調度下,存儲並檢索數據塊,並且定期向NameNode發送所存儲的數據塊的列表。
機架:HDFS集羣,由分佈在多個機架上的大量DataNode組成,不同機架之間節點通過交換機通信,HDFS通過機架感知策略,使NameNode能夠確定每個DataNode所屬的機架ID,使用副本存放策略,來改進數據的可靠性、可用性和網絡帶寬的利用率。
數據塊(block):HDFS最基本的存儲單元,默認爲64M,用戶可以自行設置大小。
元數據:指HDFS文件系統中,文件和目錄的屬性信息。HDFS實現時,採用了 鏡像文件(Fsimage) + 日誌文件(EditLog)的備份機制。文件的鏡像文件中內容包括:修改時間、訪問時間、數據塊大小、組成文件的數據塊的存儲位置信息。目錄的鏡像文件內容包括:修改時間、訪問控制權限等信息。日誌文件記錄的是:HDFS的更新操作。
NameNode啓動的時候,會將鏡像文件和日誌文件的內容在內存中合併。把內存中的元數據更新到最新狀態。
用戶數據:HDFS存儲的大部分都是用戶數據,以數據塊的形式存放在DataNode上。
在HDFS中,NameNode 和 DataNode之間使用TCP協議進行通信。DataNode每3s向NameNode發送一個心跳。每10次心跳後,向NameNode發送一個數據塊報告自己的信息,通過這些信息,NameNode能夠重建元數據,並確保每個數據塊有足夠的副本。
Reduce的體系結構
分佈式編程架構
以數據爲中心,更看重吞吐率
分而治之(把對大規模數據集的操作,分發給一個主節點管理下的各個分節點共同完成,然後整合各個節點的中間結果得到最終的輸出)
Map把一個任務分解成多個子任務
Reduce將分解後的多任務分別處理,並將結果彙總爲最終的結果
也採用了Master-Slaver結構。
4個實體:
Client
JobTraker
TaskTraker(任務節點)
HDFS(輸入、輸出數據、配置信息等) 作業(Job):在Hadoop內部,用Job來表示運行的MapReduce程序所需要用到的所有jar文件和類的集合,這些文件最終都被整合到一個jar文件中,將此jar文件提交給JobTraker,MapReduce程序就會執行。
任務(Task):MapTask和ReduceTask
鍵值對(key/value pair)
Map()、Reduce()函數的輸入、輸出都是
HDFS存儲的輸入數據經過解析後,以鍵值對的形式,輸入到MapReduce()函數中進行處理,輸出一系列鍵值對作爲中間結果,在Reduce階段,對擁有同樣Key值的中間數據進行合併形成最後結果。 生命週期: 1.提交作業
-在作業提交之前,需要對作業進行配置;
-程序代碼,主要是自己編寫的MapReduce程序;
-配置輸入輸出路徑、輸出是否壓縮;
-配置完成後,通過JobClient來提交;
作業調度算法:
FIFO調度器(默認)、公平調度器、容量調度器
2.任務分配
-TaskTracker和JobTracker之間的通信與任務的分配是通過心跳機制完成的;
-TaskTracker會主動向JobTracker詢問是否有作業要做,如果自己可以做,那麼就會申請到作業任務,這個任務 可以使Map也可能是Reduce任務;
3.任務執行
-TaskTraker將代碼和配置信息到本地;
-分別爲每一個Task啓動JVM運行任務
4.狀態更新
-任務在運行過程中,首先會將自己的狀態彙報給TaskTracker,然後由TaskTracker彙總告之JobTracker;
-任務進度是通過計數器來實現的;
-JobTracker是在接受到最後一個任務運行完成後,纔會將作業標誌爲成功。
借鑑https://blog.csdn.net/u013063153/article/details/53114989
MapReduce數據流圖
用戶自定義map函數接收一個輸入的key/value,然後產生一個集合,MapReduce把所有相同的key的值的value組成一個集合。reduce合併這些value值。通常我們通過一個迭代器把value值提供給reduce,這樣就可以處理無法全部放入內存的大量數據。
HDFS服務功能
NameNode是主節點,存儲文件的元數據,包括文件名,文件目錄結構,文件屬性(生成時間,文件屬性,文件權限)以及每個文件的塊列表和塊所在的DataNode
DataNode 在本地文件系統存儲文件塊數據,以及塊數據的校驗和。
Secondary NameNode 用來監控HDFS狀態的輔助後臺程序,每隔一段時間獲取HDFS元數據的快照。
YARN 服務功能
ResourceManager
處理客戶端請求
啓動和監控ApplicationMaster
監控NodeManager
資源分配與調度
ApplicationMaster
數據切分
爲程序申請資源並且分配給內部任務
任務監控與容錯
NodeManager
單個節點上的資源管理
處理來自ResourceManager 的命令
處理來自ApplicationMaster的命令
Container
對任務運行環境的抽象,封裝了CPU,內存等多維資源以及環境變量,啓動命令等任務運行相關的星系
離線計算框架MapReduce
將計算分爲兩個階段,Map和Reduce階段
Map階段並行處理輸入數據
Reduce階段對Map結果進行處理
Shuffle連接Map和Reduce兩個階段
Map Task將數據寫入到磁盤
Reduce Task從每個Map Task讀取一部分數據
僅僅適合離線批處理
1.具有很好的容錯性和擴展性 2.適合簡單的批處理任務
缺點
1.啓動開銷大 2.過多使用磁盤導致磁盤效率低下
卸載linux系統自帶的環境安裝包
rpm -qa|grep java #查詢安裝的java環境
rpm -e --nodeps + 包名 #卸載相應的安裝包,多個包名以空格隔開
安裝java的jdk
chmod u+x ./* #爲安裝文件夾設置可執行權限
tar -zxvf jdk-7u67-linux-x64.tar.gz -C /opt/modules/
#-C 指定解壓的位置,默認是當前文件夾
cd /opt/modules/jdk1.7.0_67/
vi /etc/profile #編輯環境變量
export JAVA_HOME=/opt/modules/jdk1.7.0_67/
export PATH=$PATH:$JAVA_HOME/bin
source /etc/profile #使環境變量生效
#退出後重新登錄
java -version
#bash: /opt/modules/jdk1.7.0_67/bin/java: cannot execute binary file
#賦值了權限以後還出現這樣的問題就是linux版本出現了出現了問題> > 這裏輸入引用文本
安裝hadoop
tar -zxvf hadoop-2.5.0.tar.gz -C /opt/modules/
cd /opt/modules/hadoop-2.5.0/etc/hadoop
echo $JAVA_HOME #輸出java環境變量
vi hadoop-env.sh
#查找 JAVA_HOME的位置
export JAVA_HOME=${JAVA_HOME}替換爲JAVA_HOME=/opt/modules/jdk1.7.0_67
cd /opt/modules/hadoop-2.5.0
mkdir input
cp etc/hadoop/*.xml input/
#-rw-r--r--. 1 root root 3589 Mar 17 21:57 capacity-scheduler.xml
#-rw-r--r--. 1 root root 774 Mar 17 21:57 core-site.xml
#-rw-r--r--. 1 root root 9201 Mar 17 21:57 hadoop-policy.xml
#-rw-r--r--. 1 root root 775 Mar 17 21:57 hdfs-site.xml
#-rw-r--r--. 1 root root 620 Mar 17 21:57 httpfs-site.xml
#-rw-r--r--. 1 root root 690 Mar 17 21:57 yarn-site.xml
hadoop 環境變量設置
參考地址:hadoop官方網址,目前使用的版本爲2.5.0
Standalone Operation 進入到hadoop的安裝目錄 我的安裝環境 /opt/modules/hadoop-2.5.0
mkdir input
cp etc/hadoop/*.xml input
vi etc/hadoop/hadoop-env.sh
<!-- 找到java_home 設置java環境變量 -->
export JAVA_HOME=/opt/modules/jdk1.7.0_67
vi etc/hadoop/core-site.xml
<configuration>
<!-- NameNode -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop.lilang.com:9000</value>
</property>
<!-- 臨時文件夾 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/modules/hadoop-2.5.0/data/tmp</value>
</property>
<!--垃圾處理時間一週 -->
<property>
<name>fs.trash.interval</name>
<value>604800</value>
</property>
</configuration>
vi etc/hadoop/hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<!-- SecondaryNameNode-->
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>hadoop.jianxin.com:50090</value>
</property>
</configuration>
vi etc/hadoop/mapred-env.xml
export JAVA_HOME=/opt/modules/jdk1.7.0_67
vi etc/hadoop/mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.jobhistory.address</name>
<value>hadoop.jianxin.com:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>hadoop.jianxin.com:19888</value>
</property>
</configuration>
#配置yarn的環境變量
vi etc/hadoop/yarn-env.sh
export JAVA_HOME=/opt/modules/jdk1.7.0_67/
vi etc/hadoop/yarn-site.xml
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hadoop.jianxin.com</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- NodeManager Resouce -->
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>4096</value>
<description>Amount of physical memory, in MB, that can be allocated
for containers.</description>
</property>
<property>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>4</value>
<description>Number of CPU cores that can be allocated
for containers.</description>
</property>
<!-- 日誌聚集功能配置 -->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>640800</value>
</property>
vi etc/hadoop/slaves
啓動方式
jps查看啓動了哪些服務
bin/hdfs namenode -format #格式化文件系統,如果啓動失敗Cannot remove currentdirectory一般是沒有用管理員權限登錄
全部啓動
需要配置ssh免密登錄,因爲鏈接節點的時候用的是ssh協議
cd ~
cd .ssh
ssh-keygen -t rsa #指定加密算法
ssh-copy-id hadoop.jianxin.com #拷貝公鑰到authorized_keys
sbin/start-all.sh #/opt/modules/hadoop-2.5.0
#默認情況下歷史服務器是沒有啓動的
[root@hadoop hadoop-2.5.0]# jps
5993 Jps
5676 NodeManager
5180 NameNode
5583 ResourceManager
5440 SecondaryNameNode
#單獨啓動歷史服務器
sbin/mr-jobhistory-daemon.sh start historyserver
[root@hadoop hadoop-2.5.0]# jps
6038 JobHistoryServer
5676 NodeManager
5180 NameNode
6137 Jps
5583 ResourceManager
5440 SecondaryNameNode
這是失敗的,因爲datanode沒有啓動起來
java.io.IOException: Incompatible clusterIDs in /opt/modules/hadoop-2.5.0/data/tmp/dfs/data: namenode clusterID = CID-e0ceb89a-d6ce-4c97-888c-32f68887d925; datanode clusterID = CID-a1ab5bc9-d4fc-4e4e-a4f6-e53da68f905a
at org.apache.hadoop.hdfs.server.datanode.DataStorage.doTransition(DataStorage.java:477)
at org.apache.hadoop.hdfs.server.datanode.DataStorage.recoverTransitionRead(DataStorage.java:226)
at org.apache.hadoop.hdfs.server.datanode.DataStorage.recoverTransitionRead(DataStorage.java:254)
at org.apache.hadoop.hdfs.server.datanode.DataNode.initStorage(DataNode.java:975)
at org.apache.hadoop.hdfs.server.datanode.DataNode.initBlockPool(DataNode.java:946)
at org.apache.hadoop.hdfs.server.datanode.BPOfferService.verifyAndSetNamespaceInfo(BPOfferService.java:278)
at org.apache.hadoop.hdfs.server.datanode.BPServiceActor.connectToNNAndHandshake(BPServiceActor.java:220)
at org.apache.hadoop.hdfs.server.datanode.BPServiceActor.run(BPServiceActor.java:812)
at java.lang.Thread.run(Thread.java:745)
每次namenode format會重新創建一個namenodeId,而data目錄包含了上次format時的id,namenode format清空了namenode下的數據,但是沒有清空datanode下的數據,導致啓動時失敗,所要做的就是每次fotmat前,清空data下的所有目錄。 或者是先停掉集羣,然後將datanode節點目錄/dfs/data/current/VERSION中的clusterID修改爲與dfs/name/current/VERSION中的clusterID 一致即可。 /opt/modules/hadoop-2.5.0/data/tmp/dfs
分模塊啓動
sbin/start-dfs.sh
sbin/start-yarn.sh
sbin/mr-jobhistory-daemon.sh start historyserver
關閉服務的時候都有相應的關閉模塊,即start變爲stop
各個服務組件逐一啓動
# 各個服務組件逐一啓動
# hdfs
sbin/hadoop-daemon.sh start|stop namenode|datanode|secondarynamenode
# yarn
sbin/yarn-daemon.sh start|stop resourcemanager|nodemanager
# mapreduce
sbin/mr-historyserver-daemon.sh start|stop historyserver
HDFS架構(分佈式文件系統)
易於擴展的分佈式文件系統
運行在大量的普通廉價機器上 提供容錯機制
爲大量用戶提供性能不錯的文件存取服務
NameNode
NameNode是一箇中心服務器,單一節點,負責管理文件系統的名字空間,以及客戶端對文件的訪問。
文件操作 NameNode負責文件元數據的操作,DataNode負責處理文件的內容讀寫請求,跟文件相關的東西不會經過NameNode,只會詢問它和哪個DataNode有聯繫。
副本存放在哪些DataNode上由NameNode決定,讀取文件的時候NameNode儘量讓用戶先讀取最近的副本,降低塊的消耗和讀取延遲。
NameNode全權管理數據塊的複製,週期性的接收從集羣的每個DataNode傳遞過來的心跳信號和塊狀態報告。塊狀態報告包含了改DataNode上的所有的數據塊的列表。
DataNode
一個數據塊在DataNode以文件的存儲在磁盤上 ,包括兩個文件,一個是數據本身,一個是元數據包括數據塊的長度,塊數據的校驗和以及時間戳。
DataNode啓動後向NameNode註冊,通過後週期性的向NameNode上報所有的塊信息。
DataNode是每三秒心跳一次,心跳結果帶有NameNode給DataNode的命令,如果超過十分鐘NameNode沒有收到DataNode的心跳,則認爲該節點不可用。
集羣運行中可以安全的加入或者退出一些機器。
文件大小
文件被切分爲塊,默認大小爲128M,以塊爲單位,每個塊有多個副本存儲在不同的機器上,副本數可在文件生成時指定。
可以創建,刪除,移動或者重命名文件,當文件的創建,寫入,關閉之後不能修改文件中的內容了。
數據損壞處理
當DataNode讀取block的時候,會計算checksum,如果計算後的checksum和創建block的時候不一樣,說明該block已經損壞。客戶端就會讀取其他塊上的數據,NameNode標記該塊已經損壞,刪除壞的塊,然後複製其他好的block達到預期設置的文件的備份數,DataNode在其文件創建三週以後驗證其checknum。
NameNode啓動方式
NameNode
內存
本地磁盤
fsimage
edits 格式化HDFS,目的就是生成fsimage
0-> format
1-> fsimage
2-> Start NameNoderead fsimage
3-> Start DataNode註冊
block report 4-> create dir /user/beifeng/tmp -> write [edits]
5-> put files /user/beifeg/tmp(*-site.xml) -> write [edits]
6-> delete file /user/beifeng/tmp/core-site.xml -> write [edits]
Namenode保存文件系統元數據鏡像,namenode在內存及磁盤(fsimage和editslog)上分別存在一份元數據鏡像文件,內存中元數據鏡像保證了hdfs文件系統文件訪問效率,磁盤上的元數據鏡像保證了hdfs文件系統的安全性。
namenode在磁盤上的兩類文件組成:
fsimage文件:保存文件系統至上次checkpoint爲止目錄和文件元數據。
edits文件:保存文件系統從上次checkpoint起對hdfs的所有操作記錄日誌信息。
首此啓動hdfs過程:
首次安裝格式化(format)主要作用是在本地文件系統生成fsimage文件 啓動namenode:
讀取fsimage生成內存中元數據鏡像。
啓動datanode:
向namenode註冊;
向namenode發送blockreport。
啓動成功後,client可以對HDFS進行目錄創建、文件上傳、下載、查看、重命名等操作,更改namespace的操作將被記錄在edits文件中。
之後啓動HDFS文件系統過程 啓動namenode:
讀取fsimage元數據鏡像文件,加載到內存中。
讀取editlog日誌文件,加載到內存中,使當前內存中元數據信息與上次關閉系統時保持一致。然後在磁盤上生成一份同內存中元數據鏡像相同的fsimage文件,同時生成一個新的的editlog文件用於記錄以後的hdfs文件系統的更改。
啓動datanode:
向namenode註冊;
向namenode發送blockreport。
啓動成功後,client可以對HDFS進行目錄創建、文件上傳、下載、查看、重命名等操作,更改namespace的操作將被記錄在editlog文件中。
SecondaryNameNode
SecondaryNameNode的主要作用是用於合併fsimage和editlog文件。在沒有SecondaryNameNode守護進程的情況下,從namenode啓動開始至namenode關閉期間所有的HDFS更改操作都將記錄到editlog文件,這樣會造成巨大的editlog文件,所帶來的直接危害就是下次啓動namenode過程會非常漫長。
在啓動SecondaryNameNode守護進程後,每當滿足一定的觸發條件(每3600s、文件數量增加100w等),SecondaryNameNode都會拷貝namenode的fsimage和editlog文件到自己的目錄下,首先將fsimage加載到內存中,然後加載editlog文件到內存中合併fsimage和editlog文件爲一個新的fsimage文件,然後將新的fsimage文件拷貝回namenode目錄下。並且生成新的editlog文件用於記錄DFS的更改。
工作流程 Secondary namenode工作流程:
1)secondary通知namenode切換edits文件
2)secondary通過http請求從namenode獲得fsimage和edits文件
3)secondary將fsimage載入內存,然後開始合併edits
4)secondary將新的fsimage發回給namenode
5)namenode用新的fsimage替換舊的fsimage
安全模式
在啓動namenode至所有datanode啓動完成前的階段成爲安全模式。在安全模式下,client只能讀取部分HDFS文件信息,不允許client對HDFS的任何更改操作,比如創建目錄、上傳文件、刪除文件、重命名文件等。
bin/hdfs dfsadmin -safemode
本文分享自微信公衆號 - 我愛問讀書(wawds_)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。