您好,登錄后才能下訂單哦!
這篇文章主要介紹“怎么處理HDFS問(wèn)題”,在日常操作中,相信很多人在怎么處理HDFS問(wèn)題問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”怎么處理HDFS問(wèn)題”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
hdfs有一個(gè)目錄掃描機(jī)制,默認(rèn)6小時(shí)會(huì)全盤掃描一次所有block,判斷與內(nèi)存里的那份blockMap是否一致。參考
https://blog.cloudera.com/hdfs-datanode-scanners-and-disk-checker-explained/
在小文件比較多的情況,掃描的時(shí)候特征很明顯——磁盤的iops很高,但吞吐量很低。當(dāng)然這不是引起datanode心跳超時(shí)的原因,真正的原因是處理掃描后的結(jié)果,比如比較完發(fā)現(xiàn)有20000個(gè)block不一致,在修復(fù)這些block時(shí)不斷的持有了 FsDatasetImpl 這個(gè)對(duì)象的一把鎖,在磁盤比較慢的情況下,可能需要5分鐘甚至10分鐘處理完,從而一直阻塞讀、寫、心跳的線程。
詳細(xì)的可以了解 HDFS-14476 lock too long when fix inconsistent blocks between disk and in-memory,包括一些特征、證據(jù),以及block修復(fù)邏輯,細(xì)節(jié)比較多。
解決辦法是,我們這邊加了個(gè)patch(已合入2.10和3.x),在處理異常block的時(shí)候,中間休息2秒,處理一下正常的請(qǐng)求,不至于datanode卡住甚至離線。
修復(fù)后的結(jié)果也是很明顯,datanode心跳平滑了許多
2. namenode遷移裁撤,遇到客戶端無(wú)法寫入
在文章 HDFS namenode節(jié)點(diǎn)裁撤不停服遷移實(shí)踐 里總結(jié)了在線遷移 namenode 的方法。遷移/裁撤的思路是保持 namenode hostname 不變,滾動(dòng)遷移 standby 的方式遷移。
但是在我們的遷移實(shí)踐中,發(fā)現(xiàn) hdfs namenode 完成遷移后,集群正常,但 hdfs 客戶端訪問(wèn)異常。在 yarn 這樣的長(zhǎng)任務(wù)場(chǎng)景下,會(huì)導(dǎo)致文件讀寫一直失敗,直到 yarn nodemanager 重啟。
具體問(wèn)題是這樣的:
client使用的是 ConfiguredFailoverProxyProvider ,client啟動(dòng)之后會(huì)根據(jù)當(dāng)時(shí)的inetsocket創(chuàng)建nn1,nn2兩個(gè)namenode proxy,這個(gè)在任何網(wǎng)絡(luò)異常的情況下都不會(huì)重新創(chuàng)建。
client 的 updateAddress 方法能檢測(cè)到namenode ip發(fā)生了變化,但由于那個(gè)異常沒(méi)有捕獲,本該在下次循環(huán)使用正確的 namenode ip 就能正常,但拋出異常后導(dǎo)致client重新連接namenode,然而上面的 namenode proxy 還是舊地址,SetupConnection 異常,又進(jìn)入updateAddress判斷邏輯,返回true又去建連接,陷入了死結(jié)。
復(fù)現(xiàn)步驟
打開(kāi)一個(gè)hdfsclient,長(zhǎng)時(shí)間寫一個(gè)文件 hdfs put
更新hdfs新namenode hostname-ip
stop old nn2, start new nn2
更新客戶端的namenode hostname-ip (client還在操作文件)
切換到新namenode hdfs haadmin -failover nn1 nn2
此時(shí)會(huì)發(fā)現(xiàn)client一直報(bào)錯(cuò)
在yarn客戶端啟動(dòng)的周期內(nèi),哪怕是新文件寫入,依舊會(huì)報(bào)錯(cuò)
對(duì) ConfiguredFailoverProxyProvider 打了個(gè)patch,就是在client failover之后,也進(jìn)行updateAddress判斷,如果有ip變動(dòng),就重新 createProxy。驗(yàn)證這個(gè)patch同樣有效。不過(guò)在client那邊統(tǒng)一捕獲會(huì)比較好,因?yàn)檫€有其他類型的HaProvider可能也有這個(gè)問(wèn)題。
這個(gè)問(wèn)題的 patch 已經(jīng)被合入 Apache Hadoop 3.4,見(jiàn) HADOOP-17068 client fails forever when namenode ipaddr changed。我們用的版本是 2.6.0-cdh6.4.11 ,也已合入。
除了從根源問(wèn)題上解決,也可以在 namenode 遷移操作時(shí),在老節(jié)點(diǎn)上啟用端口轉(zhuǎn)發(fā),再逐個(gè)重啟 yarn,避免引起大范圍故障。
現(xiàn)象:集群將滿時(shí),擴(kuò)容了批機(jī)器緩解空間。運(yùn)行了2個(gè)星期客戶端突然報(bào)文件寫入失敗
原因:hdfs在部分datanode空間滿的情況下,理論會(huì)自動(dòng)挑選其它可用的空閑節(jié)點(diǎn)。由于 dfs.datanode.du.reserved
配置不當(dāng),導(dǎo)致依然會(huì)選中滿節(jié)點(diǎn)。具體是dfs.datanode.du.reserved
如果小于分區(qū)block reserved,在磁盤用滿時(shí)就會(huì)出現(xiàn)
org.apache.hadoop.ipc.RemoteException(java.io.IOException): File
/kafka/xxxtmp.parquet could only be replicated to
0 nodes instead of minReplication
(=1). \
There are
14 datanode(s) running
and no node(s) are excluded
in this operation.
解決:
擴(kuò)容完,跑rebalance
修改磁盤分區(qū)的block reserved,使其小于 dfs.datanode.du.reserved
. 見(jiàn) hdfs datanode Non DFS Used與Remaining .
增加單個(gè)datanode容量告警
啟動(dòng) rebalance 命令./start-balancer.sh -threshold 10
,如果需要提高速度可以修改限流帶寬hdfs dfsadmin -setBalancerBandwidth 52428800
但是 datanode 上同時(shí)接收 blocks 并發(fā)數(shù),是不能在線調(diào)整的(或者說(shuō)只能調(diào)?。?,調(diào)整hdfs-site.xml
默認(rèn)的balance參數(shù),并重啟
dfs.balancer.moverThreads=1000
dfs.balancer.dispatcherThreads=200
dfs.datanode.balance.max.concurrent.moves=50
如果啟動(dòng)balance時(shí),嘗試以更高的并發(fā)執(zhí)行,datanode會(huì)判斷沒(méi)有足夠的線程接收 block: IOException: Got error, status message Not able to copy block … because threads quota is exceeded。
當(dāng) move 出現(xiàn)失敗時(shí),遷移速度是指數(shù)級(jí)下降的,因?yàn)閙ove block失敗默認(rèn)會(huì)sleep一段時(shí)間。
./start-balancer.sh
-threshold
5\
-Ddfs.datanode.balance.max.concurrent.moves=20 \
-Ddfs.datanode.balance.bandwidthPerSec=150000000 \
-Ddfs.balancer.moverThreads=500 \
-Ddfs.balancer.dispatcherThreads=100
騰訊云上的機(jī)器,可以直接在原有 datanode 上直接掛在新的磁盤,快速給hdfs擴(kuò)容。
增加磁盤,不需要重啟datanode。(前提是設(shè)置了 dfs.datanode.fsdataset.volume.choosing.policy
為AvailableSpaceVolumeChoosingPolicy
)
掛載后,先建立hadoop數(shù)據(jù)目錄并修正權(quán)限
在hdfs-site.xml
里加上新目錄配置 dfs.datanode.data.dir
可以使用 reconfig 命令使其生效: hdfs dfsadmin -reconfig datanode dn-x-x-x-x:50020 start
現(xiàn)象:active namenode 內(nèi)存故障,主備切換失敗
原因:dfs.ha.fencing.methods
設(shè)置為了ssh,但是并不能登錄其他namenode執(zhí)行fence
解決:生成ssh key,免密碼登錄?;蛘吒某?code>shell(/bin/true),強(qiáng)切。注意,修改fence方式后,需要重啟zkfc。
現(xiàn)象:執(zhí)行 hdfs
客戶端命令報(bào)錯(cuò) input/output error
,試著拷貝 hadoop / jdk 的介質(zhì)目錄,亦發(fā)現(xiàn)文件損壞。有時(shí)會(huì)發(fā)現(xiàn) jvm core
原因:磁盤存在壞塊,剛好hdfs或者jdk的 jar 庫(kù)損壞。通過(guò)觀察 messages 發(fā)現(xiàn)有 sda IO Input/Output Error
使用badblocks -s -v -o bb.log /dev/sda
可以看到磁盤損壞了哪些扇區(qū)
解決:從其他機(jī)器,拷貝一份正常的介質(zhì)
誤將系統(tǒng)盤作為了dfs.datanode.data.dir
,運(yùn)行一段時(shí)間后,這個(gè)分區(qū)很容易最先滿。
這個(gè)是配置上的問(wèn)題,理解datanode的工作方式,可以快速的將這個(gè)分區(qū)里的block挪到正確的磁盤分區(qū)。
處理方法就是停止datanode,拷貝/data
block到其它分區(qū),刪掉/data
的配置。因?yàn)閐atanode上block的位置是每次啟動(dòng)的時(shí)候,掃描上報(bào)給namenode,所以可以做物理拷貝。
可以使用拷貝命令cp -a /data/hadoopdata/current/BP-*-*/current/finalized/* /data1/hadoopdata/current/BP-*-*/current/finalized/
,不能拷貝整個(gè) hadoopdata 目錄,因?yàn)閂ERSION文件里面的storageID不同。
現(xiàn)象:將datanode加入 exclude ,正常 decomissing 的方式退役節(jié)點(diǎn),應(yīng)用層反饋 spark 任務(wù)部分異常,報(bào)錯(cuò) Unable to close file because the last block doest not have enough number of replicas ,但該集群一些其它的文件讀寫任務(wù)正常。
原因:spark任務(wù)會(huì)頻繁的創(chuàng)建、刪除application目錄。在decomissing時(shí),部分磁盤性能低的節(jié)點(diǎn),磁盤更加繁忙,導(dǎo)致出現(xiàn) last contact 心跳時(shí)間長(zhǎng)
解決:經(jīng)過(guò)驗(yàn)證,發(fā)現(xiàn)直接 kill datanode進(jìn)程的方式,不影響spark任務(wù)。但必須保證一個(gè)一個(gè)的kill,否則會(huì)出現(xiàn) missing block. (這不一定是解決問(wèn)題最好的辦法,但的確有效)
standby namenode的一個(gè)作用是,定期合并從journalnode上獲取的editlog,生成新的元數(shù)據(jù)fsimage,然后推送到active namenode。
當(dāng)standby namenode出現(xiàn)異常,如進(jìn)程退出、軟件bug(比如我們遇到過(guò) IOException: No image directories available!),導(dǎo)致長(zhǎng)時(shí)間未合并editlog。一旦需要發(fā)生切換或者重啟namenode,有可能導(dǎo)致啟動(dòng)時(shí)間過(guò)長(zhǎng),嚴(yán)重的editlog合并需要的內(nèi)存不足,無(wú)法啟動(dòng)namenode.
如果內(nèi)存不足,一種解決辦法是借一臺(tái)高內(nèi)存臨時(shí)機(jī)器合并editlog:
把standby停下來(lái),將hdfs的軟件介質(zhì)和配置文件,拷貝到高內(nèi)存機(jī)器
同時(shí)拷貝dfs.namenode.name.dir
目錄中最新能用的 fsimage_xxx 和它之后的所有 edits_xxx-xxx
在臨時(shí)機(jī)器上啟動(dòng) namenode 進(jìn)程,會(huì)自動(dòng)從對(duì)應(yīng)目錄加載 fsiamge 、合并editlog
預(yù)防比補(bǔ)救要重要,一定要監(jiān)控namenode上 TransactionsSinceLastCheckpoint
這個(gè)指標(biāo),我們的閾值是達(dá)到 5000000 就告警。
這個(gè)問(wèn)題 HDFS-15402 是在定期對(duì) datanode http://127.0.0.1:50075/jmx
jmx 進(jìn)行探測(cè)的時(shí)候產(chǎn)生的,我們有 5 個(gè) hadoop 3.1.3 的集群都存在該問(wèn)題。在 hadoop 2.x 中正常。
50075 端口上產(chǎn)生過(guò)多 close-wait 的影響是,正常的 webhdfs 會(huì)出現(xiàn) 504 Gateway-timeout
[root@dn-9-4-xxx-yy
/tmp]# ss -ant|grep :50075 |grep CLOSE-WAIT|wc -l
16464
[root@dn-9-4-xxx-yy
/tmp]# ss -ant|grep :50075 |grep CLOSE-WAIT|head -3
CLOSE-WAIT
123 0 9.4.xxx.yy:50075
9.4.xxx.yy:39706
CLOSE-WAIT
123 0 9.4.xxx.yy:50075
9.4.xxx.yy:51710
CLOSE-WAIT
123 0 9.4.xxx.yy:50075
9.4.xxx.yy:47475
lsof
-i:39706
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 134304 hdfs
*307u IPv4 429yy7315 0t0 TCP dn-9-4-xxx-yy:50075->dn-9-4-xxx-yy:39706 (CLOSE_WAIT)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 123 0 9.4.xxx.yy:50075 9.4.xxx.yy:39706 CLOSE_WAIT 134304/java
CLOSE-WAIT 狀態(tài)是客戶端(curl)發(fā)起關(guān)閉tcp連接時(shí),服務(wù)端(datanode)收到了FIN-ACK,但在關(guān)閉socket時(shí)一直沒(méi)有完成。正常流程是關(guān)閉socket完成,然后向客戶端發(fā)送FIN
所以問(wèn)題出在datanode server上,與knox還是haproxy客戶端沒(méi)有關(guān)系。并且這個(gè)問(wèn)題調(diào)整os內(nèi)核參數(shù)是沒(méi)有用的,除非kill datanode,否則close-wait狀態(tài)會(huì)永久存在。使用網(wǎng)上的kill_close_wait_connections.pl
能夠清理這些 close-wait,之后 webhdfs 請(qǐng)求變得好轉(zhuǎn)。
目前避開(kāi)的方法就是,不再請(qǐng)求 datanode jmx 做監(jiān)控,只獲取 namenode 上的指標(biāo)。datanode 上采集 os 級(jí)別的指標(biāo)。
在官方 jira 里我們提了這個(gè)問(wèn)題 KNOX-2139,當(dāng)我們使用 webhdfs with knox 上傳 8589934592 bytes 大小的文件,會(huì)出現(xiàn) (55) Send failure: Broken pipe,在 hdfs 只能看到一個(gè)空文件。而且在版本 knox 1.1, 1.2 中是必現(xiàn),在 0.8 版本正常。
簡(jiǎn)單 debug 了一下代碼,knox 拿到的請(qǐng)求 contentLength 為 0,8G 以外的情況 contentLength 為-1。
我們后來(lái)使用 haproxy 代替 knox 解決 knox 自身上傳速度慢和這個(gè) 8G 文件的問(wèn)題。在 備份系統(tǒng)上傳優(yōu)化:從knox到haproxy 有介紹我們的實(shí)現(xiàn)
不過(guò)在最新的 1.4 版本,8G問(wèn)題又消失了。根據(jù)官方的恢復(fù),可能跟 jetty 的升級(jí)有關(guān)。
Unable to load native-hadoop library for your platform… using builtin-java classes
經(jīng)常在執(zhí)行 hdfs
客戶端命令時(shí)會(huì)有這樣的提示,其實(shí)是個(gè)老生常談的問(wèn)題。
簡(jiǎn)單說(shuō)就是系統(tǒng)里沒(méi)有找到原生的 hadoop 庫(kù) libhdfs.so
,這個(gè)庫(kù)是 C 寫的,性能比較好。缺少但不影響使用,因?yàn)?hadoop 里有 java 實(shí)現(xiàn)的客戶端庫(kù)。
出現(xiàn)這個(gè)我總結(jié)原因有 3 個(gè):
hadoop 安裝包里沒(méi)有自帶 libhdfs.so
這個(gè)情況占很大一部分。去到目錄${HADOOP_HOME}/lib/native/
,看下是否有l(wèi)ibhdfs.so,libhdfs.a,libhadoop.so,libhadoop.a。如果沒(méi)有的話,可以重新下一個(gè)完整的二進(jìn)制包,把lib/native
拷出來(lái)用
這種看到才是正常的
./bin/hadoop checknative
20/05/14 20:13:39 INFO bzip2.Bzip2Factory: Successfully loaded
& initialized native-bzip2 library system-native
20/05/14 20:13:39 INFO zlib.ZlibFactory: Successfully loaded
& initialized native-zlib library
Native library checking:
hadoop: true
/data1/hadoop-hdfs/hadoop-dist/target/hadoop-2.6.0-cdh6.4.11-tendata/lib/native/libhadoop.so.1.0.0
zlib: true
/lib64/libz.so.1
snappy: true
/data1/hadoop-hdfs/hadoop-dist/target/hadoop-2.6.0-cdh6.4.11-tendata/lib/native/libsnappy.so.1
lz4: true revision:10301
bzip2: true
/lib64/libbz2.so.1
openssl: true
/usr/lib64/libcrypto.so
實(shí)在不行就在自己的 os 上編譯一個(gè)。
mvn clean package
-Pdist,native
-DskipTests
-Dtar
-Dbundle.snappy
-Dsnappy.lib=/usr/local/lib
so 文件存在,但路徑不對(duì)
現(xiàn)在的版本,默認(rèn)路徑都能找得到 so 庫(kù)。這個(gè) Hadoop “Unable to load native-hadoop library for your platform” warning 里面介紹的大部分方法,都是在教怎么設(shè)置路徑。真實(shí)原因很少會(huì)因?yàn)槁窂讲粚?duì),不過(guò)這個(gè)答案靠譜 https://stackoverflow.com/a/30927689 ,也就是我們的情況 3
編譯的版本,在我們的 os 上依賴庫(kù)不全
遇到過(guò)這種,glibc 庫(kù)版本不夠:
$ ldd lib/native/libhadoop.so
lib/native/libhadoop.so: /lib64/libc.so.6: version `GLIBC_2.14'
not found
(required by lib/native/libhadoop.so)
linux-vdso.so.1 => (0x00007ffd1db6d000)
/$LIB/libonion.so
=> /lib64/libonion.so
(0x00007f5bfd37d000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f5bfce40000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f5bfcc23000)
libc.so.6 => /lib64/libc.so.6 (0x00007f5bfc88f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5bfd266000)
$ strings
/lib64/libc.so.6 |grep GLIBC_
可以看當(dāng)前系統(tǒng)支持哪些版本的 glibc
但是 glibc 安裝升級(jí)有風(fēng)險(xiǎn),如果要安裝 2.14 版本務(wù)必先做好測(cè)試。
hdfs 集群出現(xiàn) missing block,無(wú)非就是 namenode 里還記錄的 block 元數(shù)據(jù)信息,但是所有副本都丟失了。如果是同時(shí)掛了多個(gè)機(jī)器,或者損壞了多個(gè)機(jī)器上的磁盤,是有可能會(huì)出現(xiàn)。
遇到過(guò) 2 次人為產(chǎn)生 missing blocks:
kill 一個(gè) datanode 進(jìn)程,就出現(xiàn) missing block
先設(shè)置所有文件的 replication 為 1,一小段時(shí)間后,再設(shè)置為 2
這兩種情況都算是 bug,對(duì)應(yīng)的文件確實(shí)無(wú)法 get 下來(lái)了。但第 1 中情況還好,經(jīng)過(guò)排除日志,發(fā)現(xiàn)實(shí)際這些丟失的 blocks 本就接收到了刪除命令,過(guò)一段時(shí)間后,missing block 一般會(huì)自動(dòng)消失。第 2 中情況,是真的意外丟 block 了,比較嚴(yán)重。不要輕易把 replication 設(shè)置為 1,再改回去可能丟 block。
如果確認(rèn)這些 missing block 可以消除,可以通過(guò) fsck 命令手動(dòng)處理:
// 如果missing blocks數(shù)不是很多,可以直接逐個(gè)delete
hdfs fsck file_name
-delete
// 如果missing blocks較多,可以從namenode上拿到corrupt塊
hdfs fsck
/ -list-corruptfileblocks
-openforwrite
| egrep
-v
'^\.+$' | egrep
"MISSING|OPENFORWRITE" | grep
-o
"/[^ ]*" | sed
-e
"s/:$//" > missing_blocks.txt
實(shí)際還有些許多問(wèn)題,比如用戶supergroup 權(quán)限問(wèn)題、rack-aware.sh
文件缺失的問(wèn)題,限于篇幅就不列舉了。
問(wèn)題是不斷會(huì)出現(xiàn)的,但及時(shí)對(duì)大部分場(chǎng)景做到監(jiān)控工具,能夠提前發(fā)現(xiàn)問(wèn)題。下面是整理并上線的關(guān)鍵告警指標(biāo):
datanode lastcontact
datanode 與 namenode 心跳監(jiān)控。心跳時(shí)間長(zhǎng)意味這這個(gè) dn 沒(méi)響應(yīng)了,默認(rèn)超過(guò)10m30s 沒(méi)響應(yīng),dn會(huì)脫離集群。
namenode and datanode web probe
namenode 50070 與 datanode 50075 從外部探測(cè),并且 datanode 會(huì)根據(jù) include里面的地址自動(dòng)增減。我們使用修改過(guò)了 telegraf http_response 插件,支持動(dòng)態(tài)讀取url,比如 exec bash get_datanode_urls.sh
dirctory max files
單目錄下的文件數(shù)告警。hdfs默認(rèn)限制單目錄下最大的文件數(shù)100萬(wàn),由配置項(xiàng)dfs.namenode.fs-limits.max-directory-items
決定。
這個(gè)指標(biāo)數(shù)據(jù)來(lái)源于 fsimage 目錄畫像分析。
transactions not merged
standby 未滾動(dòng)的editlog數(shù)。長(zhǎng)期未checkpoint會(huì)導(dǎo)致下次namenode啟動(dòng)消耗過(guò)多內(nèi)存,甚至啟動(dòng)失敗。
missing blocks
異常blocks數(shù)
test write file
在2個(gè)namenode節(jié)點(diǎn)上,定期使用 hdfs put/get 寫入文件。如果失敗會(huì)告警
non-active namenode
hdfs集群namenode有且只有一個(gè)active,一個(gè)standby。其它情況告警
cluster capacity
集群總體容量監(jiān)控
node usage, ioutil
單個(gè) datanode 磁盤空間使用率預(yù)警,ioutil持續(xù)5分鐘大于95%預(yù)警。
failover occurs
hdfs namenode發(fā)生failover
namenode heap size
namenode heap size使用比率。blocks數(shù)量多,內(nèi)存使用越多。
到此,關(guān)于“怎么處理HDFS問(wèn)題”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。