HDFS副本放置策略
客戶端:執行put命令所在的機器稱爲客戶端
- 第一副本
假如上傳節點爲dn節點,優先放置在本節點;否則會隨機找一個磁盤不太慢、CPU不太繁忙的節點 - 第二副本
放置於第一副本不同的機架上 - 第三副本
放置於第二副本的相同機架的不同節點上
CDH機架有一個默認的機架,虛擬的概念,CDH一般不調整這種默認機架
HDFS的讀寫流程
寫流程
- 1、client調用FileSystem.create(filePath)方法
client調用FileSystem.create(filePath)方法跟NN進行rpc通信,nn會檢查文件是否存在以及是否有權限進行創建,如果檢查失敗,返回錯誤信息,如果檢查通過,就創建一個新文件,不會關聯任何block塊,然後返回一個FSDataOutputStream對象 - 2、client端調用FSDataOutputStream對象的write()方法
將第一塊的第一個副本寫到第一個DN;第一個寫完,
就傳輸第二個副本到第二個DN上;第二個寫完,
就傳輸第三個副本到DN上;第三個副本寫完,
就返回一個ack packet確認包給第二個DN;
第二個DN接收到第三個的ack packet加上自身的ok後,就返回一個ack packet確認包給第一個DN,
第一個DN接收到第二個DN的ack packet 並加上自身的ok,就返回ack paket確認包給FSDataOutputStream對象,
標誌着第一塊 3副本已經寫入完畢,然後餘下的block依次這樣寫 - 3、當向文件寫入完數據後
client調用FSDataOutputStream對象的close()方法,關閉輸出流 - 4、最後調用FileSystem.complete()方法告訴NN數據寫入成功
讀流程
- 1、client調用FileSystem.open(filePath)方法,
與NN進行rpc通信,返回該文件的部分或者全部block列表,也就是FSDataInputStream對象 - 2、client調用FSDataInputStream.open()方法,
與第一塊最近的DN進行read,讀取完成後,會check,假如ok,就關閉與DN的通信;假如失敗,會記錄失敗塊+DN信息,下次將不會訪問該block塊,然後會去該塊的第二個DN地址進行讀取,check完成後,關閉通信;
假如block塊列表讀取完成後,文件還未結束,就再次調用FileSystem從NN獲取該文件的下一批次的block塊列表,然後繼續跟NN進行read - 3、client調用FSDataInputStream的close()方法,關閉輸入流
配置pid文件的生成路徑
啓動hdfs或yarn,如果不在配置文件配置的話,生成的pid文件會在/tmp目錄下,如果linux一個月自動清理pid文件,pid文件會造成集羣的啓動和停止(jps文件不會影響集羣),所以我們需要在hdfs和yarn的配置文件中配置讓,pid文件不要生成在/tmp目錄下
hdfs的配置
配置hadoop-env.sh
export HADOOP_PID_DIR=/home/hadoop/tmp
yarn配置
配置yarn-env.sh
export YARN_PID_DIR=/home/hadoop/tmp
重新啓動,查看pid文件路徑
[hadoop@JD tmp]$ pwd
/home/hadoop/tmp
生成在配置的路徑下
[hadoop@JD tmp]$ ll
total 20
-rw-rw-r-- 1 hadoop hadoop 5 Dec 1 18:28 hadoop-hadoop-datanode.pid
-rw-rw-r-- 1 hadoop hadoop 5 Dec 1 18:28 hadoop-hadoop-namenode.pid
-rw-rw-r-- 1 hadoop hadoop 5 Dec 1 18:29 hadoop-hadoop-secondarynamenode.pid
-rw-rw-r-- 1 hadoop hadoop 5 Dec 1 18:29 yarn-hadoop-nodemanager.pid
-rw-rw-r-- 1 hadoop hadoop 5 Dec 1 18:29 yarn-hadoop-resourcemanager.pid
HDFS DFS常用命令
hadoop fs 跟 hdfs dfs命令的區別
在linux輸入hdfs dfs命令還是會調用hadoop fs命令
[hadoop@JD ~]$ hdfs dfs
Usage: hadoop fs [generic options]
[-cat [-ignoreCrc] <src> ...]
[-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...]
[-chown [-R] [OWNER][:[GROUP]] PATH...]
[-ls [-C] [-d] [-h] [-q] [-R] [-t] [-S] [-r] [-u] [<path> ...]]
[-put [-f] [-p] [-l] <localsrc> ... <dst>]
[-get [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
[-copyFromLocal [-f] [-p] [-l] <localsrc> ... <dst>]
[-copyToLocal [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
[-rm [-f] [-r|-R] [-skipTrash] <src> ...]
hdfs的回收站
切記檢查生產上是否開啓了回收站,CDH默認是開啓的,哪怕開了回收站後,刪除文件的時候也要慎用-skipTrash(直接刪除)命令
- 配置開啓回收站(10080代表保留7天),在core-site.xml進行配置
key | value |
---|---|
fs.trash.interval | 10080 |
配置開啓回收站後,刪除文件,會將文件刪除到回收站中,七天過後會自動刪除;但是如果使用hdfs dfs -put -skipTrash /xxx命令,哪怕配置了回收站,也會直接把文件刪除
查看hdfs上的數據健康情況
[hadoop@JD ~]$ hdfs fsck /
19/12/05 20:40:09 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Connecting to namenode via http://JD:50070/fsck?ugi=hadoop&path=%2F
FSCK started by hadoop (auth:SIMPLE) from /192.168.0.3 for path / at Thu Dec 05 20:40:10 CST 2019
........Status: HEALTHY
Total size: 174944 B
Total dirs: 13
Total files: 8
Total symlinks: 0
Total blocks (validated): 7 (avg. block size 24992 B)
Minimally replicated blocks: 7 (100.0 %)
Over-replicated blocks: 0 (0.0 %)
Under-replicated blocks: 0 (0.0 %)
Mis-replicated blocks: 0 (0.0 %)
Default replication factor: 1
Average block replication: 1.0
這兩個指標最重要,正常情況下這倆都是0
Corrupt blocks: 0 #損壞的塊
Missing replicas: 0 (0.0 %)#丟失的副本
Number of data-nodes: 1
Number of racks: 1
FSCK ended at Thu Dec 05 20:40:10 CST 2019 in 7 milliseconds
The filesystem under path '/' is HEALTHY
HDFS的多節點(nn),單節點的磁盤均衡
各DN節點的數據均衡
爲了防止各個節點的磁盤使用率差距過大,我們可以執行start-balancer.sh腳本設置閾值,參數爲threshold = xxx,生產上一般設置閾值爲10即可。
-
設置閾值的目的是
90+60+80=230/3=76%
所有節點的磁盤used與集羣的平均used之差要小於這個閾值 -
同時也要設置執行平衡腳本時得帶寬,生產上設置30m即可,不能讓帶寬佔得太大,影響正常的寫入流程,在hdfs-site.xml設置
key | value |
---|---|
dfs.datanode.balance.bandwidthPerSec | 30m |
-
執行
[hadoop@JD sbin]$ pwd /home/hadoop/app/hadoop/sbin [hadoop@JD sbin]$ ./start-balancer.sh 設置閾值執行 [hadoop@JD sbin]$ ./start-balancer.sh -threshold 5
其實可以自己寫一個定時腳本,例如crontab,在每天晚上零點20的時候執行,從而達到每天調度,數據平衡,毛刺修正
一個DN節點的多個磁盤的數據均衡
操作使用文檔:https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HDFSDiskbalancer.html
-
爲什麼要放置多個物理的磁盤目錄
/data01 disk1 /data02 disk2 /data03 disk3 爲了高效率寫 高效率讀 提前規劃好2-3年存儲量 ,避免後期加磁盤維護的工作量
-
查看磁盤所佔空間大小
[hadoop@JD sbin]$ df -h /data01 90% /data02 60% /data03 80% /data04 0%
-
在hdfs-site.xml中開啓磁盤數據平衡(注意apache的某些低版本的hdfs沒有該配置項,cdh的版本都有)
key | value |
---|---|
dfs.disk.balancer.enabled | true |
-
在JD這臺機器上生成執行計劃,會生成JD.plan.json
hdfs diskbalancer -plan JD -
根據執行計劃去執行
hdfs diskbalancer -execute JD.plan.json -
查看狀態
hdfs diskbalancer -query JD -
什麼時候手動或調度執行?
a.新盤加入 b.監控服務器的磁盤剩餘空間 小於閾值 10%,發郵件預警 手動執行
怎麼在DataNode中掛載磁盤?
由hdfs-site.xml文件的dfs.datanode.data.dir屬性控制
key | value |
---|---|
dfs.datanode.data.dir | file://${hadoop.tmp.dir}/dfs/data |
假如我們現在有/data01,/data02,/data03,/data04四個目錄需要掛載在該DataNode節點中,修改hdfs-site.xml文件添加屬性
<property>
<name>dfs.datanode.data.dir</name>
<value>/data01,/data02,/data03,/data04</value>
</property>
HDFS的安全模式
進入安全模式
[hadoop@JD ~]$ hdfs dfsadmin -safemode enter
離開安全模式
[hadoop@JD ~]$ hdfs dfsadmin -safemode leave
安全模式影響
安全模式會影響寫數據,對讀數據沒有影響;如果NN的log顯示進入safe mode時,正常手動讓其離開安全模式
如果hdfs突然進入安全模式,從flume或者kafka讀數據到hdfs會拋大量的錯,這時候我們最好可以在數據上游設置一個開關,不讓數據到下游來