來源:CSDNcss
做者:Syn良子 html
原文:https://blog.csdn.net/cssdongl/article/details/77750495 node
一.問題背景網絡
問題產生的緣由多是因爲前幾日Hadoop集羣維護的時候,基礎運維組操做不當,先關閉的Hadoop集羣,而後才關閉的Flume agent致使的hdfs文件寫入後狀態不一致。排查和解決過程以下.運維
二.解決過程oop
1.既然是hdfs文件出問題,用fsck檢查一下吧測試
hdfs fsck /spa
固然你能夠具體到指定的hdfs路徑,檢查完打印結果沒有發現任何異常,沒有發現損壞或者Corrupt的block,繼續排查.net
2.那麼加上其餘參數細查debug
hdfs fsck / –openforwrite
ok,此次檢查出來很多文件打印顯示都是 openforwrite狀態,並且我測試相應文件確實不能讀取,這很不正常不是嗎?Flume已經寫過的hdfs文件竟然還處於openforwrite狀態,並且沒法cat和get
因此這裏的」Cannot obtain block length for LocatedBlock」結合字面意思講應該是當前有文件處於寫入狀態還沒有關閉,沒法與對應的datanode通訊來成功標識其block長度.
那麼分析其產生的可能性,舉栗子以下
1>Flume客戶端寫入hdfs文件時的網絡鏈接被不正常的關閉了
或者
2>Flume客戶端寫入hdfs失敗了,並且其replication副本也丟失了
我這裏應該屬於第一種,總結一下就是Flume寫入的hdfs文件因爲什麼緣由沒有被正常close,狀態不一致隨後沒法正常訪問.繼續排查
3.推斷:HDFS文件租約未釋放
能夠參考這篇文章來了解HDFS租約機制 http://www.cnblogs.com/cssdongl/p/6699919.html
瞭解過HDFS租約後咱們知道,客戶端在每次讀寫HDFS文件的時候獲取租約對文件進行讀寫,文件讀取完畢了,而後再釋放此租約.文件狀態就是關閉的了。
可是結合當前場景因爲先關閉的hadoop集羣,後關閉的Flume sink hdfs,那麼hadoop集羣都關了,Flume還在對hdfs文件寫入,那麼租約最後釋放了嗎?答案是確定沒釋放.
4.恢復租約
對於這些狀態損壞的文件來說,rm掉的話是很暴力的作法,萬一上游對應日期的數據已經沒有rention呢?因此,既然沒有釋放租約,那麼恢復租約close掉文件就是了,以下命令
hdfs debug recoverLease -path <path-of-the-file> -retries <retry times>
請將<path-of-the-file>修改爲你須要恢復的租約狀態不一致的hdfs文件的具體路徑,若是要恢復的不少,能夠寫個自動化腳原本找出須要恢復的全部文件而後統一恢復租約.
ok,執行完命令後再次cat對應hdfs文件已無異常,順利顯示內容,問題解決.