HDFS在機器斷電或意外崩潰的狀況下,有可能出現正在寫的數據(例如保存在DataNode內存的數據等)丟失的問題。再次重啓HDFS後,發現hdfs沒法啓動,查看日誌後發現,一直處於安全模式。node
出現前面提到的問題主要緣由是客戶端寫入的數據沒有及時保存到磁盤中,從而致使數據丟失;又由於數據塊丟失達到必定的比率,致使hdfs啓動進入安全模式。apache
爲了弄清楚致使安全模式的緣由,下面主要對hdfs安全模式和如何退出安全模式進行分析。安全
當 hdfs的NameNode節點啓動時,會進入安全模式階段。安全模式主要是爲了系統啓動的時候檢查各個DataNode上數據塊的有效性,同時根據策略必要的複製或者刪除部分數據塊。工具
在此階段,NameNode加載fsimage(Filesystem image:文件meta信息的持久化的檢查點)文件到內存中,而後在editlog中執行相應的操做。加載fsimage文件包含文件metadata信息,可是不包含文件塊位置的信息。oop
DataNode啓動的時候掃描本地磁盤,保存的block信息,而後將這些信息彙報給NameNode,讓 NameNode獲得塊的位置信息,並對每一個文件對應的數據塊副本進行統計。spa
若是hdfs數據量很大時,進入至退出安全模式時間較長。日誌
當最小副本條件知足時,即必定比例(dfs.safemode.threshold.pct缺省值0.999f)的數據塊都達到最小副本數,系統就會退出安全模式。當最小副本條件未達到要求時,就會對副本數不足的數據塊安排DataNode進行復制,直至達到最小副本數。若是datanode丟失的block達到必定的比例(1-dfs.safemode.threshold.pct),則系統會一直處於安全模式狀態即只讀狀態。而在安全模式下,系統會處於只讀狀態,NameNode不會處理任何塊的複製和刪除命令。server
dfs.safemode.threshold.pct(缺省值0.999f)表示HDFS啓動的時候,若是DataNode上報的block個數達到了元 數據 記錄的block個數的0.999倍才能夠離開安全模式,不然一直是這種只讀模式。若是設爲1則HDFS永遠是處於SafeMode。內存
下面這行摘錄自NameNode啓動時的日誌:hadoop
異常狀況: |
The ratio of reported blocks 0.8544 has not reached the threshold0.9990. Safe mode will be turned off automatically. org.apache.hadoop.hdfs.server.namenode.SafeModeException: Checkpoint not created. Name node is in safe mode. |
正常狀況: |
The ratio of reported blocks 1.0000 has reached the threshold0.9990. Safe mode will be turned off automatically in 18 seconds. |
機器斷電或意外崩潰是客觀存在的事實,爲了減小其帶來的問題,從丟數據和不丟數據兩個方面討論解決方法。
由於機器斷電或意外崩潰,在內存中未寫入的數據塊已經丟失或損壞,沒法復原,只有讓hdfs離開安全模式,纔可讓hdfs啓動成功,這樣無可避免的會致使數據丟失。
經過第2.2節緣由分析可知,有兩個方法離開這種安全模式:
1. 修改dfs.safemode.threshold.pct爲一個比較小的值,缺省是0.999;
該方法雖然能夠是HDFS正常啓動,可是threshold.pct的值很差把握,設置低了會致使集羣可靠性降低,不推薦使用。
2. 退出安全模式後,刪除損壞的塊文件,而後重啓hdfs服務。
注: 不論hdfs是否採用journal ha模式。hdfs進入安全模式後,hbase沒法啓動,會一直打印等待dfs退出安全模式(「Waiting for dfs to exit safe mode...」),此時也不可使用hbck工具修復hbase,不然會打印獲取不到Master錯誤(
client.HConnectionManager$HConnectionImplementation: getMaster attempt 8 of 35 failed)。
退出安全模式具體方法以下:
1. 首先啓動hdfs全部服務,包括NameNode | DataNode | JournalNode | DFSZKFailoverController等;
[hadoop@172-25-8-121 hadoop]$ ./sbin/start-dfs.sh
2. 判斷hdfs是否處於安全模式
[hadoop@172-25-8-121 bin]$ hdfs dfsadmin -safemode get
Safe mode is ON |
注:兩種模式,ON / OFF
3. 使用fsck命令查看是否有損壞的塊
[hadoop@172-25-8-121 hadoop]$ ./bin/hdfs fsck /
(如下紅色標記的爲缺失或損壞的塊)
[hadoop@172-25-8-121 sbin]$ hadoop fsck / …………… /hbase/data/default/DSA_RESULT_SUMMARY/3432986e5109695221484de73f26cecd/attribute/08fa05898ff34fe9b0cdfef5dc30e9e6:CORRUPT blockpool BP-2061322962-172.25.8.121-1440560168099 block blk_1073742016
/hbase/data/default/DSA_RESULT_SUMMARY/3432986e5109695221484de73f26cecd/attribute/08fa05898ff34fe9b0cdfef5dc30e9e6:MISSING 1 blocks of total size 78969 B.. /hbase/data/default/DSA_RESULT_SUMMARY/3432986e5109695221484de73f26cecd/image/1ca82fc944a14a05aebac92b8de46d11:CORRUPT blockpool BP-2061322962-172.25.8.121-1440560168099 block blk_1073742018
/hbase/data/default/DSA_RESULT_SUMMARY/3432986e5109695221484de73f26cecd/image/1ca82fc944a14a05aebac92b8de46d11:MISSING 1 blocks of total size 72545 B... /hbase/data/default/DSA_RESULT_SUMMARY/3432986e5109695221484de73f26cecd/sequence/9ddd08a485164eabbdd16d66d96b19b3:CORRUPT blockpool BP-2061322962-172.25.8.121-1440560168099 block blk_1073742020
/hbase/data/default/DSA_RESULT_SUMMARY/3432986e5109695221484de73f26cecd/sequence/9ddd08a485164eabbdd16d66d96b19b3:MISSING 1 blocks of total size 77363 B......... /hbase/data/default/DSA_RESULT_SUMMARY/939bafb7709b004c8a81796b6af05733/attribute/a50e9e114db548508328bee892139800:CORRUPT blockpool BP-2061322962-172.25.8.121-1440560168099 block blk_1073742015
/hbase/data/default/DSA_RESULT_SUMMARY/939bafb7709b004c8a81796b6af05733/attribute/a50e9e114db548508328bee892139800:MISSING 1 blocks of total size 138179 B.. /hbase/data/default/DSA_RESULT_SUMMARY/939bafb7709b004c8a81796b6af05733/image/9965fb45404b46278d2d4738bbff8051:CORRUPT blockpool BP-2061322962-172.25.8.121-1440560168099 block blk_1073742017
/hbase/data/default/DSA_RESULT_SUMMARY/939bafb7709b004c8a81796b6af05733/image/9965fb45404b46278d2d4738bbff8051:MISSING 1 blocks of total size 126927 B.... /hbase/data/default/DSA_RESULT_SUMMARY/939bafb7709b004c8a81796b6af05733/sequence/441a9d027c944d78931d0d18a39454bd:CORRUPT blockpool BP-2061322962-172.25.8.121-1440560168099 block blk_1073742019
/hbase/data/default/DSA_RESULT_SUMMARY/939bafb7709b004c8a81796b6af05733/sequence/441a9d027c944d78931d0d18a39454bd: MISSING 1 blocks of total size 135366 B........................Status: CORRUPT Total size: 1624639056 B (Total open files size: 45 B) Total dirs: 85 Total files: 75 Total symlinks: 0 (Files currently being written: 5) Total blocks (validated): 83 (avg. block size 19573964 B) (Total open file blocks (not validated): 5) ******************************** CORRUPT FILES: 6 MISSING BLOCKS: 6 MISSING SIZE: 629349 B CORRUPT BLOCKS: 6 ******************************** Minimally replicated blocks: 77 (92.77109 %) Over-replicated blocks: 0 (0.0 %) Under-replicated blocks: 0 (0.0 %) Mis-replicated blocks: 0 (0.0 %) Default replication factor: 2 Average block replication: 1.8554217 Corrupt blocks: 6 Missing replicas: 0 (0.0 %) Number of data-nodes: 4 Number of racks: 1 FSCK ended at Wed Aug 26 17:17:22 CST 2015 in 44 milliseconds
The filesystem under path '/' is CORRUPT |
4. 在NameNode節點上使用dfsadmin命令離開安全模式
[hadoop@172-25-8-121 hadoop]$ ./bin/hdfs dfsadmin -safemode leave
Instead use the hdfs command for it.
Safe mode is OFF |
5. 使用fsck命令將丟失的塊刪除
[hadoop@172-25-8-121 hadoop]$ ./bin/hdfs fsck -delete
6. 重啓hdfs相關服務
[hadoop@172-23-9-20 hadoop]# ./sbin/dfs-start.sh
7. 重啓hbase
[hadoop@172-23-9-20 hbase]# ./bin/start-hbase.sh
8. 若是hbase啓動失敗,則使用hbck命令修復
[hadoop @172-23-9-20 hbase]# ./bin/hbase hbck -repair
HBase提供了hbck命令來檢查各類不一致問題,包括meta數據不一致。檢查數據在Master及RegionServer的內存中狀態與數據在HDFS中的狀態之間的一致性。
HBase的hbck不只可以檢查不一致問題,並且還可以修復不一致問題。
在生產環境中,應當常常運行hbck,以便及早發現不一致問題並更容易地解決問題。
使用hsync()方法實現意外斷電狀況下HDFS數據的完整性。hdfs在Client端提供了hsync()的方法調用,從而保證在機器崩潰或意外斷電的狀況下,數據不會丟失。
在hdfs中,調用hflush()會將Client端buffer中的存放數據更新到Datanode端,直到收到全部Datanode的ack響應時結束調用。這樣可保證在hflush()調用結束時,全部的Client端均可以讀到一致的數據。hdfs中的sync()本質也是調用hflush()。
hsync()則是除了確保會將Client端buffer中的存放數據更新到Datanode端外,還會確保Datanode端的數據更新到物理磁盤上,這樣在hsync()調用結束後,即便Datanode所在的機器意外斷電,數據並不會所以丟失。而hflush()在機器意外斷電的狀況下卻有可能丟失數據,由於Client端傳給Datanode的數據可能存在於Datanode的cache中,並未持久化到磁盤上。
hdfs雖然提供了hsync()方法,可是若咱們對每次寫操做都執行hsync(),會嚴重加重磁盤的寫延遲。經過一些策略,比方說按期執行hsync()或當存在於Cache中的數據達到必定數目時,執行hsync()會是更可行的方案,從而儘可能減小機器意外斷電所帶來的影響。