hadoop學習總結:
1.hadoop簡介:
(1)分佈式存儲系統。HDFS(Hadoop Distirbuted File System)
#分佈式存儲系統。
#提供了高可靠/高拓展/高吞吐率的數據存儲服務。
(2)分佈式計算框架MapReduce。
#分佈式計算框架
#具有易於編程/高容錯率/高拓展性等有點。
2.HDFS優點:
(1)高容錯性
#數據自動保存多個副本。
#副本丟失後,自動恢復。
(2)適合批處理。
#移動計算而非數據。
#數據位置暴露給計算框架
(3)適合大數據處理
#GB/TB/甚至PB級數據。
#百萬規模以上的文件數量
#10k+節點
(4)可構建在廉價的機器上
#通過多副本提高可靠性。
#提供了容錯和恢復機制。
3.HDFS缺點:
(1)低延遲數據訪問
#比如毫秒級
#低延遲與高吞吐率
(2)小文件存取
#佔用NameNode大量內存
#尋道時間超過讀取時間
(3)併發寫入/文件隨機修改
#一個文件只能有一個寫者
#僅支持append
4.HDFS 數據存儲單元(block)
(1)文件被切分成固定大小的數據塊:默認數據塊大小爲64MB(hadoop1.x),可配置。若文件大小不到64MB,則單獨存成一個block。
(2)一個文件存儲方式:按大小被切分成若干個block,存儲到不同節點上,默認情況下每個block都有三個副本。
(3)Block大小和副本數通過Client端上傳文件時設置,文件上傳成功後副本數可以變更,Block Size不可變更。
5. NameNode(NN)
(1)NameNode主要功能:接受客戶端的讀寫服務
(2)NameNode保存metadate信息包括
#文件owership和permissions
#文件包含哪些塊
#Block保存在哪個DataNode(由DataNode啓動時上報)
(3)NameNode的metadate信息在啓動後會加載到內存
#metadata存儲到磁盤文件名爲”fsimage”
#Block的位置信息不會保存到fsimage
#edits記錄對metadata的操作日誌
6.SecondaryNameNode(SNN)
(1)它不是NN的備份(但可以做備份),它的主要工作是幫助NN合併edits log,減少NN啓動時間。
(2)SNN執行合併時機
#根據配置文件設置的時間間隔fs.checkpoint.period 默認3600秒。
#根據配置文件設置edits log大小 fs.checkpoint.size 規定edits文件的最大值默 認是64MB。
7.DataNode(DN)
(1)存儲數據(Block)
(2)啓動DN線程的時候會向NN彙報block信息
(3)通過向NN發送心跳保持與其聯繫(3秒一次),如果NN10分鐘沒有收到DN的心跳,則認爲其已經lost,並copy其上的block到其它DN。
8. Block的副本放置策略
(1)第一個副本:放置在上傳文件的DN; 如果是集羣外提交,則隨機挑選一臺 磁盤不太滿,CPU不太忙的節點。
(2)第二個副本:放置在於第一個副本不 同的 機架的節點上。
(3)第三個副本:與第二個副本相同機架 的節點。
(4)更多副本:隨機節點.
9.HDFS文件權限
(1)與Linux文件權限類似,r: read; w:write; x:execute,權限x對於文件忽略,對於文件夾表示是否允許訪問其內容。
(2)如果Linux系統用戶zhangsan使用hadoop命令創建一個文件,那麼這個文件在HDFS中owner就是zhangsan。
(3)HDFS的權限目的:阻止好人錯錯事,而不是阻止壞人做壞事。HDFS相信,你告訴我你是誰,我就認爲你是誰。
10.安全模式
(1)namenode啓動的時候,首先將映像文件(fsimage)載入內存,並執行編輯日誌(edits)中的各項操作。
(2)一旦在內存中成功建立文件系統元數據的映射,則創建一個新的fsimage文件(這個操作不需要SecondaryNameNode)和一個空的編輯日誌。
(3)此刻namenode運行在安全模式。即namenode的文件系統對於客服端來說是隻讀的。(顯示 目錄,顯示文件內容等。寫、刪除、重命名都會失敗)。
(4)在此階段Namenode收集各個datanode的報告,當數據塊達到最小副本數以上時,會被認爲是“安全”的,在一定比例(可設置)的數據塊被確定爲“安全”後,再過若干時間,安全模式結束。
(5)當檢測到副本數不足的數據塊時,該塊會被複制直到達到最小副本數,系統中數據塊的位 置並不是由namenode維護的,而是以塊列表形式存儲在datanode中。
11. 安裝HDFS和hadoop。(集羣)
使用四個real server做測試。realserver1,2,3,4.
(1)檢查集羣的機器時間基本一致(在30秒以內)
(2)安裝java和ssh。
#安裝SSH :基本CentOS已經安裝好了。可以自己測試一下,如果需要安裝自己在網上找教程。
#安裝java:
- 首先下載java安裝包到系統中,然後解壓,配置環境變量。
CentOS7中 vi /etc/profile
export JAVA_HOME=/usr/java/jdk1.7.0_79
export PATH=
source /etc/profile
- 測試:
$JAVA_HOME/bin/java -version和java -version輸出的版本信息一致。
(3)免登錄的配置。
#使用命令加密:ssh-keygen -t dsa -P ” -f ~/.ssh/id_dsa
- 在~/.ssh中有三個文件,id_dsa是私鑰文件,自己使用,id_dsa.pub公鑰文件,給別人使用,免密碼登陸系統的時候使用。
#把公鑰放到本機的認證文件中, cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys。這樣登陸本機就不需要密碼了。
#讓本機登陸其他datenode不需要密碼。
- 把本機的公鑰複製給其他機器,scp ~/.ssh/id_dsa.pub [email protected]:/opt
- 把本機公鑰添加到其他機器的認證文件中,cat /opt/id_dsa.pub >> ~/.ssh/authorized_keys
(4)拷貝hadoop2.5.1安裝包到系統中,解壓。配置文件。
#配置JAVA_HOME:hadoop-2.5.1/etc/hadoop/hadoop-env.sh.在文本內容中,修改JAVA_HOME的環境變量。
#vi core-site.xml:
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://192.168.0.4:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/hadoop-2.5</value>
</property>
</configuration>
#vi hdfs-site.xml:
<configuration>
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>192.168.0.5:50090</value>
</property>
<property>
<name>dfs.namenode.secondary.https-address</name>
<value>192.168.0.5:50091</value>
</property>
</configuration>
#vi slaves:配置datenote的屬性。
192.168.0.5
192.168.0.8
192.168.0.9
#vi masters:配置secondary namenode
192.168.0.5
(5)把安裝在本機上的hadoop複製到各個節點中。
# scp -r hadoop-2.5.1/ [email protected]:/root
(6)配置hadoop的環境變量:在每個機器都配置。
#export HADOOP_HOME=/usr/yiyele/hadoop-2.5.1
export PATH=
(7)格式化namenode,生成fsimage文件。
#hdfs namenode -format
#start-dfs.sh
#stop-dfs.sh
(8)如果以上配置完成後,還不能顯示datanode,可以試着添加或修改主機名。hostname /etc/hosts /etc/hostname
12. HDFS 2.x
(1)解決HDFS1.0中的單點故障和內存受限問題。
#解決單點故障:
- HDFS HA:通過主備NameNode解決。除了edit文件不一致,其他文件基本一致。例如初始元數據,fsimage文件等,目的是爲了實現瞬間接管。
如果在每次更新fsimage數據時,會同時更新備用NameNode的fsimage信息。datanode在發送block信息時,也會同時向備用NameNode發送。
- 如果主NameNode發生故障,則切換到備NameNode上。
#解決內存受限問題
- HDFS Federation
- 每個NameNode分管一部分目錄
- 所有NameNode共享所有的DataNode存儲資源
(2)2.x僅是架構上發生了變化,使用方式不變
#對HDFS使用者透明
#HDFS1.x中的命令和API仍可以使用。
13. 搭建HDFS HA集羣:(實在hadoop集羣搭建好的基礎上進行修改)
(1)搭建zookeeper:server1 server2 server3
#安裝zookeeper,解壓。配置文件。
- 進入到zookeeper目錄下的conf,創建文件zoo.cfg。 vi zoo.cfg
tickTime=2000
dataDir=/opt/zookeeper
clientPort=2181
initLimit=5
syncLimit=2
server.1=nginx1:2888:3888
server.2=nginx2:2888:3888
server.3=lvs:2888:3888
#在/opt/zookeeper/目錄下創建myid文件。 vi myid
- 分別寫入對應的id,1,2,3
#配置環境變量vi profile,把zookeeper目錄下的bin加入PATH中。/usr/yiyele/zookeeper-3.4.6/bin
#啓動zookeeper,在bin目錄下,命令:zkServer.sh start
#連接內存數據庫:zkCli.sh
(2)配置zookeeper和hadoop(保證zookeeper處於啓動狀態不變)
#刪除hadoop配置文件中的masters(配置secondaryNameNode),刪除hadoop的緩存文件。/opt/hadoop-2.5.
#編輯hdfs-site.xml:
- nameservices配置:
<property>
<name>dfs.nameservices</name>
<value>mycluster</value> //nameservice ID
</property>
- namenode配置:
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value> //兩個namenode的名稱
</property>
- nameNode的rpc協議具體配置:(修改兩個namenode的value值)
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name> //注意nameservice ID要一致
<value>machine1.example.com:8020</value> //第一個namenode的配置
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>machine2.example.com:8020</value> //第二個namenode的配置
</property>
- namenode的http協議的具體配置:(修改兩個namenode的value值)
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>machine1.example.com:50070</value> //第一個namenode的配置
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>machine2.example.com:50070</value> //第二個namenode的配置
</property>
- edits文件的共享目錄:
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://node1.example.com:8485;node2.example.com:8485;node3.example.com:8485/mycluster</value>
</property>
- java連接NameNode的配置:基本不用修改
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
- <property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/exampleuser/.ssh/id_rsa</value> //私鑰目錄
</property>
- 配置journalnode的數據存放目錄:
-
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/path/to/journal/node/local/data</value>
</property>
#編輯 core-site.xml文件
- <property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value> //nameservice ID
</property>
- <property>
<name>hadoop.tmp.dir</name>
<value>/opt/hadoop-2.5</value>
</property>
# 以上是手動切換的配置,如果需要自動切換則需:
- 編輯hdfs-site.xml:
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
- 編輯core-site.xml:配置zoodeeper的三臺服務器。(server1 server2 server3)
<property>
<name>ha.zookeeper.quorum</name>
<value>zk1.example.com:2181,zk2.example.com:2181,zk3.example.com:2181</value>
</property>
(3)首先啓動journaynode。(確保配置文件在各個服務器上都配置好)確保journalnode啓動成功,才進行下面的步驟。
# 命令:hadoop-daemon.sh start journalnode
# 查看journalnode的日誌,看看是否有錯。
(4)同步兩臺namenode中的元數據。
# 首先任意格式化一個namenode,命令:hdfs namenode -format
# 然後把格式化後的namenode中的目錄數據拷貝到另一臺namenode中。/opt/hadoop-2.5
(5)初始化zookeeper。(在任意一個namenode中)
# 命令:hdfs zkfc -formatZK
(6)在免密碼登陸的服務上,啓動服務。
# 命令: start-dfs.sh
- 分別啓動兩個namenode 三個datanode 三個journalnnode 兩個zookeeper。檢查啓動的信息。
# 單獨啓動節點的命令:
hadoop-daemon start datanode
zkServer.sh start
(7)檢查:
# 分別用瀏覽器登錄namenode的50070端口查看。
# 查看standby的namenode能否接管,強制關掉actived的namenode。
(8)注意:
# 注意讓namenode的兩個機器都能互相免密碼登陸。
# 出錯看日誌。
14.熟悉hdfs hadoop-daemon start-dfs.sh等命令。
15.MapReduce:離線的分佈式計算框架。
(1)設計概念:移動計算,不是移動數據。
(2)步驟:
# input 輸入數據
# splitting 分割block數據。
# Mapping 輸出key-value的值,負責把複雜的任務分解爲若干個簡單的任務執行。(數據規模小,就近計算,小任務並行計算)
# shuffling 複製/排序/合併等
# reducing 操作,對mapping數據進行彙總(默認是一個)
# output 輸出。
(3)shuffler:
# input->map->buffer in memory->partitioin,sort,spill to disk->merge on disk->fetch->sort/group->reduce->output
- buffer in memory:把數據讀到內存,當達到閾值後,就存在磁盤中。
- partitioin:計算分區號,默認是做key的hash值做取模運算。
- sort:排序。對maptask輸出數據進行排序。默認排序算法是key值的字典(ASCII)排序。
- spill to disk:溢出到磁盤,內存中數據達到閾值,就存到磁盤中。
- merge on disk:在磁盤中合併
- fetch:把第一階段合併的數據抓到(根據分區號)reduce的前處理中。可以被抓到各個reduce的task中去。
- sort/group:排序,使用默認算法。然後分組(根據鍵是否相等)。
- reduce:每組(排序後)數據都會傳到reduce中進行計算。
- output:輸出結果。
# conbiner:默認不執行,作用是把鍵相同的值累加,有分組的效果。所以執行這個操作會導致分組操作執行兩次。
(4)split的大小:
# 公式:max(min.split,min(max.split,block))
- min.split:10M
- max.split:100M
- block: 64M
# 以上值爲默認值。
(5)運行環境:YARN。
# 簡介:hadoop2.x的運行環境,包括Resource Manager/Node Manager(container,App Mstr)
# 詳細過程見官方文檔。
16.YARN配置:
# 編輯yarn-site.xml.
- <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> //配置兩個resource manager
<value>rm1,rm2</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm1</name> //配置第一個resource manager
<value>master1</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name> //配置第二個resource manager
<value>master2</value>
</property>
<property>
<name>yarn.resourcemanager.zk-address</name> //配置zookeeper
<value>zk1:2181,zk2:2181,zk3:2181</value>
</property>
# 編輯mapred-site.xml
- <property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
# 編輯yarn-site.xml
- <property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
# 啓動:
- 命令:start-yarn.sh
- 啓動備用resource manager:yarn-daemon.sh start resourcemanager
# 檢測:
- 訪問主節點8088端口。查看信息
- 訪問備用的主節點8088端口。查看信息,會重定向到主節點的頁面。
17.執行。
# 第一種方式:服務器環境:(需要src下放置hadoop的配置文件)
- 1.hadoop jar 包名 執行類名(加上打包的名)
- 2.服務器環境第二種方式:(企業使用)
* 把jar包直接放在本地上
* 修改hadoop的源碼,注意:確保項目的lib需要真實安裝的jdk的lib
* 增加一個屬性:
config.set("mapred.jar","jar包所在的路徑");
* 本地執行main方法,servlet調用MR
# 第二種方式:本地測試環境:
- 在hadoop目錄下的bin目錄中添加winutils.exe
- 在window下配置hadoop的環境變量
- 修改hadoop的源碼,注意:確保項目的lib需要真實安裝的jdk的lib
- MR調用的代碼需要改變:
* src不能有服務器的hadoop配置文件
* 在調用時使用:
Configuration config = new Configuration();
config.set("fs.defaultFS",“hdfs://node7:8020”); //指定namenode的主機名和端口號
config.set("yarn.resourcemanager.hostname",node7); //指定resourcemanager的主機名和端口號