Hadoop簡介及HDFS
1.Hadoop簡介
Hadoop是Apache基金會開發的分散式系統基礎架構。開創者是Lucene–Doug Cutting,而Google是hadoop的思想之源(GFS–>HDFS,Map-Reduce–>MR,BigTable–>HBase)。 目前主流的是2.0x版本的Hadoop,它由HDFS、Mapreduce、Yarn、Core四個部分組成。
Hadoop 的優勢
1)高可靠性:因為 Hadoop 假設計算元素和儲存會出現故障,因為它維護多個工作資料副 本,在出現故障時可以對失敗的節點重新分佈處理。 2)高擴充套件性:在叢集間分配任務資料,可方便的擴充套件數以千計的節點。 3)高效性:在 MapReduce 的思想下,Hadoop 是並行工作的,以加快任務處理速度。 4)高容錯性:自動儲存多份副本資料,並且能夠自動將失敗的任務重新分配。
Hadoop 組成
1)Hadoop HDFS:一個高可靠、高吞吐量的分散式檔案系統。 2)Hadoop MapReduce:一個分散式的離線平行計算框架。 3)Hadoop YARN:作業排程與叢集資源管理的框架。 4)Hadoop Common:支援其他模組的工具模組(Configuration、RPC、序列化機制、日誌操作)。
2.HDFS
HDFS架構
這種架構主要由四個部分組成,分別為 HDFS Client、NameNode、DataNode 和 Secondary NameNode。下面我們分別介紹這四個組成部分。 1)Client:就是客戶端。 (1)檔案切分。檔案上傳 HDFS 的時候,Client 將檔案切分成一個一個的 Block,然後進行儲存。 (2)與 NameNode 互動,獲取檔案的位置資訊。 (3)與 DataNode 互動,讀取或者寫入資料。 (4)Client 提供一些命令來管理 HDFS,比如啟動或者關閉HDFS。 (5)Client 可以通過一些命令來訪問 HDFS。 2)NameNode:就是 master,它是一個主管、管理者。 (1)管理 HDFS 的名稱空間。 (2)管理資料塊(Block)對映資訊 (3)配置副本策略 (4)處理客戶端讀寫請求。 3)DataNode:就是 Slave。NameNode 下達命令,DataNode 執行實際的操作。 (1)儲存實際的資料塊。 (2)執行資料塊的讀/寫操作。 4)Secondary NameNode:並非 NameNode 的熱備。當 NameNode 掛掉的時候,它並不能馬上替換 NameNode 並提供服務。 (1)輔助 NameNode,分擔其工作量。 (2)定期合併 Fsimage 和 Edits,並推送給 NameNode。 (3)在緊急情況下,可輔助恢復 NameNode。
HDFS讀/寫操作
客戶端在讀取資料時,會有一個就近原則,挑選最近的datenode來讀取資料。
在寫資料時,因為副本數預設為3,所以第一個副本在client所在的節點,第二個副本在第一個副本所在的機架的隨機節點上,第三個副本在不同機架的隨機節點。這裡體現了HDFS的高容錯性。
DataNode的工作機制
這裡需要注意的是datanode向namenode註冊之後,每3s返回一次心跳;若10分鐘namenode沒有收到來自datanode的心跳訊息,則判定datanode死亡;datanode每小時上報所有的塊訊息給namenode。還有datanode的block中的資料有校驗和,它會在讀取資料時,通過orc奇偶校驗判斷資料是否損壞,保證了資料的完整性。
HDFS的高可用
可以通過兩個NameNode實現避免單點故障導致的服務中斷。
若要實現高可用,元資料的管理方式需要改變,在之前是儲存在namenode,可以通過secondrynamenode來幫助namenode恢復資料、整合資料。需要改變為,兩個namenode都儲存有元資料,但是隻有active狀態的namenode來實現寫edits,共享的edits可以放在jounalnode中。
但是上面說的這種方式,如果一臺namenode宕機了,另一臺機器還需要我們手動來從standby狀態轉為active狀態。所以要通過zookeeper這個提供協調服務的軟體,namenode會在zookeeper中維護一個持久會話,如果這個會話中斷了,zookeeper就知道該namenode發生了故障,立即通知另一臺namenode轉換為active提供服務。每臺執行namenode的機器也運行了zkfc的程序,該程序對namenode進行監控,並可以獲得znode鎖,保證了只有一個namenode為active。
3.HDFS配置
前提條件
- 準備幾臺虛擬機器,最少三臺
- 將機器的網路配置好,如果後面幾臺機器的是克隆的話,需要進行下面3、4、5、6步,若不是克隆的就跳過。
- 需要修改/etc/udev/rules.d/70-persistent-net.rules 將eth0網絡卡刪除,再將eth1改為eth0,複製mac地址
- vi /etc/sysconfig/network 中的hostname
- vi /etc/sysconfig/network-scripts/ifcfg-eth0 將HWADDR改為剛才複製的mac地址,IPADDR修改ip地址。
- vi /etc/hosts 對主機名進行ip對映。
- 裝好JDK和Hadoop,在/etc/profile下配置/jdk/bin和/hadoop/bin以及/hadoop/sbin
- 關閉防火牆,service iptables stop
- 開啟免密登入。通過ssh-keygen 生成私鑰和公鑰,再用ssh-copy-id將公鑰拷給需要免密登入的機器。
單機版
只需要將jdk配置好,hadoop解壓後,在hadoop/etc/hadoop/hadoop-env.sh中配置下jdk的路徑,這樣就實現了單機版的配置。
偽分散式
修改core-site.xml
<!-- 指定HDFS 中 NameNode 的地址 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop101:9000</value>
</property>
<!-- 指定 hadoop 執行時產生檔案的儲存目錄 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/module/hadoop-2.7.2/data/tmp</value>
</property>
修改hdfs-site.xml
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
全分散式
-
cd /usr/local/hadoop/etc/hadoop/ 進入該路徑中配置hadoop檔案
-
mv mapred-site.xml.template mapred-site.xml 將檔案改名
-
vi core-site.xml (以下紅色的均為看實際情況可變的)
<property> <name>fs.defaultFS</name> <value>hdfs://hadoop01:9000</value> </property> <!-- 指定 hadoop 執行時產生檔案的儲存目錄 --> <property> <name>hadoop.tmp.dir</name> <value>/usr/local/hadoop-2.7.2/data/tmp</value> </property>
-
vi hdfs-site.xml
<!--文字副本數為3--> <property> <name>dfs.replication</name> <value>3</value> </property> <!--SecondaryNameNode地址--> <property> <name>dfs.namenode.secondary.http-address</name> <value>hadoop03:50090</value> </property>
-
vi yarn-site.xml
<property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <!-- 指定 YARN 的 ResourceManager 的地址 --> <property> <name>yarn.resourcemanager.hostname</name> <value>hadoop02</value> </property> <!-- 日誌聚集功能使能 --> <property> <name>yarn.log-aggregation-enable</name> <value>true</value> </property> <!-- 日誌保留時間設定 7 天 --> <property> <name>yarn.log-aggregation.retain-seconds</name> <value>604800</value> </property>
-
vi mapred-site.xml
<property> <name>mapreduce.jobhistory.address</name> <value>hadoop02:10020</value> </property> <property> <name>mapreduce.jobhistory.webapp.address</name> <value>hadoop02:19888</value> </property> <!-- 指定 mr 執行在 yarn 上 --> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property>
高可用HA
-
配置hdfs-site.xml
<name>dfs.replication</name> <value>3</value> </property> <!--配置nameservice--> <property> <name>dfs.nameservices</name> <value>mycluster</value> </property> <!--myucluster下的名稱節點兩個id --> <property> <name>dfs.ha.namenodes.mycluster</name> <value>nn1,nn2</value> </property> <!--配置每個nn的rpc地址--> <property> <name>dfs.namenode.rpc-address.mycluster.nn1</name> <value>hadoop01:8020</value> </property> <property> <name>dfs.namenode.rpc-address.mycluster.nn2</name> <value>hadoop02:8020</value> </property> <!--配置webui埠--> <property> <name>dfs.namenode.http-address.mycluster.nn1</name> <value>hadoop01:50070</value> </property> <property> <name>dfs.namenode.http-address.mycluster.nn2</name> <value>hadoop02:50070</value> </property> <!--名稱節點共享編輯目錄--> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://hadoop01:8485;hadoop02:8485;hadoop03:8485/mycluster</value> </property> <!--java類,client使用它判斷哪個節點是啟用態--> <property> <name>dfs.client.failover.proxy.provider.mycluster</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> </property> <!--指令碼列表或者java類,在容災保護啟用態的nn--> <property> <name>dfs.ha.fencing.methods</name> <value> sshfence shell(/bin/true) </value> </property> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/root/.ssh/id_rsa</value> </property> <!--配置JN存放edit的本地路徑--> <property> <name>dfs.journalnode.edits.dir</name> <value>/usr/local/hadoop-2.7.2/data/jn</value> </property> <!-- 訪問代理類:client,mycluster,active 配置失敗自動切換實現方式--> <property> <name>dfs.client.failover.proxy.provider.mycluster</name> <value> org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider </value> </property> <!-- 關閉許可權檢查--> <property> <name>dfs.permissions.enable</name> <value>false</value> </property>
-
配置core-site.xml
<property> <name>fs.defaultFS</name> <value>hdfs://mycluster</value> </property> <!-- 指定 hadoop 執行時產生檔案的儲存目錄 --> <property> <name>hadoop.tmp.dir</name> <value>/usr/local/hadoop-2.7.2/data/tmp</value> </property>
-
同步core-site.xml和hdfs-site.xml
-
檢測
1)在jn節點分別啟動jn程序 hadoop-daemon.sh start journalnode 2)啟動jn之後,在兩個NN之間進行disk元資料同步 a)如果是全新叢集,先format檔案系統,只需要在一個nn上執行。 $>hadoop namenode -format b)如果將非HA叢集轉換成HA叢集,複製原NN的metadata到另一個nn. 1.步驟一 在hadoop01中 $>scp -r /usr/local/hadoop-2.7.2/data/tmp/dfs/name hadoop02:/usr/local/hadoop-2.7.2/data/tmp/dfs/ 2.步驟二 在新的nn(未格式化的nn)上執行一下命令,實現待命狀態引導。 在[nn2]上,同步 nn1 的元資料資訊: $>hdfs namenode -bootstrapStandby //需要hadoop01的namenode為啟動狀態,提示是否格式化,選擇N. 3)在一個NN上執行以下命令,完成edit日誌到jn節點的傳輸。 $>hdfs namenode -initializeSharedEdits 4)啟動所有節點. 在hadoop02中 $>hadoop-daemon.sh start namenode //啟動名稱節點 $>hadoop-daemons.sh start datanode //啟動所有資料節點 在hadoop02中 $>hadoop-daemon.sh start namenode //啟動名稱節點
hdfs haadmin -transitionToActive nn1 //切成啟用態 hdfs haadmin -transitionToStandby nn1 //切成待命態 hdfs haadmin -transitionToActive --forceactive nn2//強行啟用 hdfs haadmin -failover nn1 nn2 //模擬容災演示,從nn1切換到nn2 hdfs haadmin -getServiceState nn1 //檢視狀態
配置 HDFS-HA 自動故障轉移
-
在hdfs-site.xml中
<property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property> 在core-site.xml中 <property> <name>ha.zookeeper.quorum</name> <value>hadoop01:2181,hadoop02:2181,hadoop03:2181</value> </property>
-
同步!!!
-
啟動 (1) 關閉所有 HDFS 服務: sbin/stop-dfs.sh (2) 啟動 Zookeeper 叢集: bin/zkServer.sh start (3) 初始化HA 在 Zookeeper 中狀態: bin/hdfs zkfc -formatZK 成都 (4) 啟動HDFS 服務: sbin/start-dfs.sh (5) 在各個 NameNode 節點上啟動 DFSZK Failover Controller,先在哪臺機器啟動,哪個機器的NameNode 就是 Active NameNode sbin/hadoop-daemon.sh start zkfc (6) 驗證 (1) 將 Active NameNode 程序 kill kill -9 namenode 的程序 id (2) 將 Active NameNode 機器斷開網路 service network stop
YARN的高可用
-
在yarn-site.xml中
<property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <!-- 指定 YARN 的 ResourceManager 的地址 <property> <name>yarn.resourcemanager.hostname</name> <value>hadoop02</value> </property>--> <property> <name>yarn.resourcemanager.ha.enabled</name> <value>true</value> </property> <property> <name>yarn.resourcemanager.cluster-id</name> <value>cluster1</value> </property> <property> <name>yarn.resourcemanager.ha.rm-ids</name> <value>rm1,rm2</value> </property> <property> <name>yarn.resourcemanager.hostname.rm1</name> <value>hadoop01</value> </property> <property> <name>yarn.resourcemanager.hostname.rm2</name> <value>hadoop03</value> </property> <property> <name>yarn.resourcemanager.webapp.address.rm1</name> <value>hadoop01:8088</value> </property> <property> <name>yarn.resourcemanager.webapp.address.rm2</name> <value>hadoop03:8088</value> </property> <property> <name>yarn.resourcemanager.zk-address</name> <value>hadoop01:2181,hadoop02:2181,hadoop03:2181</value> </property> <!--啟用自動恢復--> <property> <name>yarn.resourcemanager.recovery.enabled</name> <value>true</value> </property> <!--指定 resourcemanager 的狀態資訊儲存在zookeeper 叢集--> <property> <name>yarn.resourcemanager.store.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value> </property> <!-- 日誌聚集功能使能 --> <property> <name>yarn.log-aggregation-enable</name> <value>true</value> </property> <!-- 日誌保留時間設定 7 天 --> <property> <name>yarn.log-aggregation.retain-seconds</name> <value>604800</value> </property>
-
同步yarn-site.xml
-
先啟動hdfs
-
啟動 yarn (1) 在 hadoop102 中執行: sbin/start-yarn.sh (2) 在 hadoop103 中執行: sbin/yarn-daemon.sh start resourcemanager (3) 檢視服務狀態 bin/yarn rmadmin -getServiceState rm1
補充:如果沒有配置高可用的話,namenode出現故障了怎麼辦???
在主namenode發生故障時 ( 假設 沒 有 及 時 備 份 數 據 ) ,可以 從SecondaryNameNode 恢復資料。
方法一:將 SecondaryNameNode 中資料拷貝到 namenode 儲存資料的目錄; 方法 二: 使用 -importCheckpoint 選項 啟動 namenode 守 護 進 程 ,從而將SecondaryNameNode 中資料拷貝到 namenode 目錄中。
一、手動拷貝 SecondaryNameNode 資料: 模擬 namenode 故障,並採用方法一,恢復 namenode 資料 1) kill -9 namenode 程序
jps檢視一下
2) 刪除 namenode 儲存的資料(data/tmp/dfs/name)
rm -rf name
3) 拷貝 SecondaryNameNode 中資料到原 namenode 儲存資料目錄
scp -r [email protected]:/usr/local/hadoop-2.7.2/data/tmp/dfs/namesecondary/* 拷貝到原來name地方
namesecondary 改名name 並把current in_use.lock刪除掉。
4) 重新啟動 namenode
sbin/hadoop-daemon.sh start namenode
二、採用 importCheckpoint 命令拷貝 SecondaryNameNode 資料 模擬 namenode 故障,並採用方法二,恢復 namenode 資料
修改 hdfs-site.xml 中的
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>120</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>/usr/local/hadoop-2.7.2/data/tmp/dfs/name</value>
</property>
1) kill -9 namenode 程序 2) 刪除 namenode 儲存的資料(data/tmp/dfs/name) 一般上namenode都是name下的
rm -rf /etc/local/hadoop-2.7.2/data/tmp/dfs/name/*
3 )如果 SecondaryNameNode 不和 Namenode 在 一個 主機 節點上,需要將 SecondaryNameNode 儲存資料的目錄拷貝到 Namenode 儲存資料的平級目錄, 並刪除 in_use.lock 檔案。
scp -r [email protected]:/usr/local/had../data/tmp/dfs/namesecondary ./
rm -rf in_use.lock
4)匯入檢查點資料(等待一會 ctrl+c 結束掉)
bin/hdfs namenode -importCheckpoint
5)啟動 namenode
sbin/hadoop-daemon.sh start namenode
總結
通過以上對於Hadoop的簡介可以看出來,Hadoop其實就是一個分散式的大資料處理架構平臺,如今Hadoop已經成為一個生
態圈,它的生態圈中有許多元件,可以幫我們儲存海量的資料,也可以幫助我們對海量的資料進行處理分析。
而HDFS是Hadoop生態圈中的一個很厲害的元件,它是一個分散式檔案儲存系統,為我們的以後處理的資料提供了一個儲存數
據的平臺。而且它的容錯機制為我們儲存資料提供了保障,防止某臺機器發生故障導致資料丟失。但是它的缺點也很明顯,不能像
我們儲存在本地那樣可以隨意修改,只支援一個執行緒去修改,而且不適合去儲存很多小檔案。因為在每次namenode啟動時,會將
fsimage載入到記憶體中,小檔案元資料資訊太多會浪費namenode的記憶體,但正因為namenode記錄著元資料資訊,我們讀取或寫
資料的時候,我們並不需要知道檔案儲存在哪臺datanode,我們只需要對檔案進行拉取或者寫入操作就行,方便了我們的操作。
但對於剛學習Hadoop的人們,沒必要配置HA,配置全分佈就行。因為HA確實很耗費資源,會導致以後hive之類以MR為底層的
計算過程耗時比較長。
summed up by JiaMingcan
轉載請署名:JiaMingcan