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文件
-
vi hadoop-env.sh / yarn-env.sh / mapred-env.sh 在這三個文件中添加JAVA_HOME路徑
-
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 root@hadoop04:/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 root@hadoop04:/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生態圈中的一個很厲害的組件,它是一個分佈式文件存儲系統,可以使用很多廉價的機器組成一個強大的分佈
式集羣,爲我們的以後處理的數據提供了一個存儲數據的平臺,就目前來說,主流的spark並沒有自身的文件存儲功能,還是需要
依靠HDFS來提供,在之後所學到的HIVE、HBase、sqoop、flume等,都有面向HDFS的接口,它是Hadoop生態圈中不可缺少的一
部分。
它是有多臺廉價機器組成的集羣,所以它能夠提供給我們海量的存儲空間。它的容錯機制爲我們存儲數據提供了保障,防止某臺
機器發生故障導致數據丟失。但是它的缺點也很明顯,不能像我們存儲在本地那樣可以隨意修改,只支持一個線程去修改,而且不適
合去存儲很多小文件。因爲在每次namenode啓動時,會將fsimage加載到內存中,小文件元數據信息太多會浪費namenode的內
存,但正因爲namenode記錄着元數據信息,我們讀取或寫數據的時候,我們並不需要知道文件存儲在哪臺datanode,我們只需要
對文件進行拉取或者寫入操作就行,方便了我們的操作。
但對於剛學習Hadoop的人們,沒必要配置HA,配置全分佈就行。因爲HA確實很耗費資源,會導致以後hive之類以MR爲底層的
計算過程耗時比較長。
summed up by JiaMingcan
轉載請署名:JiaMingcan