如何有效恢復誤刪的HDFS檔案

大資料學習與分享發表於2020-12-01

HDFS是大資料領域比較知名的分散式儲存系統,作為大資料相關從業人員,每天處理HDFS上的檔案資料是常規操作。這就容易帶來一個問題,實際操作中對重要資料檔案的誤刪,那麼如何恢復這些檔案,就顯得尤為重要。

本文針對誤刪HDFS檔案的問題,通過利用HDFS的內部機制,提供了以下幾種方法:

1. 回收站機制恢復

HDFS提供了回收站功能,當我們執行hdfs dfs -rm -r some_file命令後,檔案不會被立即刪除。而是先將要刪除的資料移動到當前使用者的.Trash目錄下,待超過一定時間(可通過引數配置)後才會真正執行刪除的操作。

首先看個例子:

[root@bigdatalearnshare-3 ~]# hdfs dfs -rm -r /bigdatalearnshare/test/stats.json 
20/07/24 16:42:35 INFO fs.TrashPolicyDefault: Namenode trash configuration: Deletion interval = 360 minutes, Emptier interval = 0 minutes.
20/07/24 16:42:35 INFO fs.TrashPolicyDefault: Moved: 'hdfs://bigdatalearnshare-1:9000/bigdatalearnshare/test/stats.json' to trash at: hdfs://bigdatalearnshare-1:9000/user/root/.Trash/Current/bigdatalearnshare/test/stats.json
Moved: 'hdfs://bigdatalearnshare-1:9000/bigdatalearnshare/test/stats.json' to trash at: hdfs://bigdatalearnshare-1:9000/user/root/.Trash/Current

 

從上面的例子可以看出,我們在刪除檔案stats.json時,stats.json會被移到/user/root/.Trash/Current目錄下:

[root@bigdatalearnshare-3 ~]# hdfs dfs -ls /user/root/.Trash/Current/bigdatalearnshare/test
Found 1 items
-rw-r--r--   1 root supergroup        147 2020-07-24 16:42 /user/root/.Trash/Current/bigdatalearnshare/test/stats.json

 

如果我們刪除該檔案的操作為誤操作,此時HDFS的回收站機制就發揮重大作用了。我們只需到回收站中找到誤刪的檔案,然後移動(mv)到原來的目錄,即可恢復誤刪的資料。

注意:HDFS的回收站機制預設是關閉的,需要我們在配置檔案core-site.xml中配置一些引數,具體如下:

<property>
     <name>fs.trash.interval</name>
     <value>360</value>
     <description>檢查點被刪除後的分鐘數。如果為零,垃圾桶功能將被禁用。
     該選項可以在伺服器和客戶端上配置。如果垃圾箱被禁用伺服器端,則檢查客戶端配置。
     如果在伺服器端啟用垃圾箱,則會使用伺服器上配置的值,並忽略客戶端配置值。
     </description>
</property>

<property>
     <name>fs.trash.checkpoint.interval</name>
     <value>0</value>
     <description>垃圾檢查點之間的分鐘數。應該小於或等於fs.trash.interval。
     如果為零,則將該值設定為fs.trash.interval的值。每次檢查指標執行時,
     它都會從當前建立一個新的檢查點,並刪除比fs.trash.interval更早建立的檢查點。
     </description>
</property>

 

注意:通過回收站恢復誤刪的資料,要求時間不能超過fs.trash.interval配置的時間。

生產中為了防止誤刪資料,建議開啟HDFS的回收站機制


 

 

2. 快照機制恢復

HDFS快照是檔案系統的只讀時間點副本。可以在檔案系統的子樹或整個檔案系統上建立快照。

一個快照是一個全部檔案系統、或者某個目錄在某一時刻的映象。快照的一些常見用例是資料備份,利用快照可以對重要資料進行恢復,防止使用者錯誤性的操作,管理員可以通過以滾動的方式週期性設定一個只讀的快照,這樣就可以在檔案系統上有若干份只讀快照。如果使用者意外地刪除了一個檔案,就可以使用包含該檔案的最新只讀快照來進行恢復。

HDFS的快照的特徵如下:

  1. 快照的建立是瞬間的,代價為O(1),取決於子節點掃描檔案目錄的時間

  2. 當且僅當做快照的檔案目錄下有檔案更新時才會佔用小部分記憶體,佔用記憶體的大小為O(M),其中M為更改檔案或者目錄的數量

  3. 新建快照的時候,Datanode中的block不會被複制,快照中只是記錄了檔案塊的列表和大小資訊快照不會影響正常的HDFS的操作

  4. 對做快照之後的資料進行的更改將會按照時間順序逆序的記錄下來,使用者訪問的還是當前最新的資料,快照裡的內容為快照建立的時間點時檔案的內容減去當前檔案的內容

下面我們來實操說明如何利用快照恢復誤刪除的檔案:

建立快照

為目錄/bigdatalearnshare/snapshot建立名為snapshot-test的快照:

[root@bigdatalearnshare-3 ~]# hdfs dfsadmin -allowSnapshot /bigdatalearnshare/snapshotAllowing snaphot on /bigdatalearnshare/snapshot succeeded[root@bigdatalearnshare-3 ~]# hdfs dfs -createSnapshot /bigdatalearnshare/snapshot snapshot-testCreated snapshot /bigdatalearnshare/snapshot/.snapshot/snapshot-test

誤刪除操作

因為我們為/bigdatalearnshare/snapshot建立了快照,此時我們無法刪除該目錄:

[root@bigdatalearnshare-3 ~]#  hdfs dfsadmin -allowSnapshot /bigdatalearnshare/snapshot
Allowing snaphot on /bigdatalearnshare/snapshot succeeded
[root@bigdatalearnshare-3 ~]# hdfs dfs -createSnapshot /bigdatalearnshare/snapshot snapshot-test
Created snapshot /bigdatalearnshare/snapshot/.snapshot/snapshot-test

 

但是我們可以hdfs dfs -rm -r命令該目錄下檔案。

如果此時,我們誤刪了該目錄下的重要檔案,我們就可以通過快照機制進行檔案的恢復。具體如下:

[root@bigdatalearnshare-3 ~]# hdfs dfs -rm -r /bigdatalearnshare/snapshot
20/07/24 17:06:52 INFO fs.TrashPolicyDefault: Namenode trash configuration: Deletion interval = 360 minutes, Emptier interval = 0 minutes.
rm: Failed to move to trash: hdfs://bigdatalearnshare-1:9000/bigdatalearnshare/snapshot: The directory /bigdatalearnshare/snapshot cannot be deleted since /bigdatalearnshare/snapshot is snapshottable and already has snapshots

 

注意:快照機制進行檔案的恢復,我們要用cp命令,不能用mv,因為快照在這裡是只讀的。

[root@bigdatalearnshare-3 ~]# hdfs dfs -mv /bigdatalearnshare/snapshot/.snapshot/snapshot-test/stats.json /bigdatalearnshare/snapshot
mv: Modification on a read-only snapshot is disallowed

 


 

3. 編輯日誌(edits)恢復

通過編輯日誌恢復HDFS檔案,適用於Hadoop叢集沒有開啟回收站機制,也沒有對重要資料進行快照處理的場景。

但是這種方式存在很大弊端,檔案的恢復存在以下幾種情況: 
1)全部恢復
2)部分恢復
3)完全沒有回覆

這個主要和叢集的繁忙狀態有很大關係。而且通過這種方式恢復誤刪檔案的代價很高,具體看以下介紹:

刪除檔案:

因為剛才開啟了HDFS回收站機制,為了模擬檔案被立刻刪除的情況,此處通過指定-skipTrash引數跳過回收站回收:

hdfs dfs -rm -r -skipTrash /bigdatalearnshare/testlog/stats.json

 

恢復資料

NameNode在收到刪除命令時,會先將這個命令寫到edits中,然後會告訴DataNode執行真正的檔案刪除操作。

所以我們在誤刪檔案後,需要做的是立刻停止NameNode和DataNode節點,阻止刪除命令的執行。然後找到執行刪除操作發生時間對應的edits日誌。

本次測試時,edits檔案為edits_inprogress_0000000000000003454,該檔案是二進位制的形式,我們可以通過HDFS命令將這個檔案轉換成可讀的xml形式,如下:

hdfs oev -i edits_inprogress_0000000000000003454 -o edits_inprogress_0000000000000003454.xml

 

在edits_inprogress_0000000000000003454.xml中查詢刪除/bigdatalearnshare/testlog下檔案stats.json的命令記錄:

<EDITS>
  <RECORD>
    <OPCODE>OP_DELETE</OPCODE>
    <DATA>
      <TXID>3462</TXID>
          <LENGTH>0</LENGTH>
          <PATH>/bigdatalearnshare/testlog/stats.json</PATH>
          <TIMESTAMP>1595582828526</TIMESTAMP>
          <RPC_CLIENTID>dd918895-1482-4b0a-ab8e-d3b2b87c430d</RPC_CLIENTID>
          <RPC_CALLID>1</RPC_CALLID>
      </DATA>
  </RECORD>
</EDITS>

 

OP_DELETE代表刪除操作,我們可以將這個標記修改為安全的操作(如OP_SET_PERMISSIONS),如果這個命令在最後,可以直接刪除,然後儲存。再將修改後的編輯日誌轉換成計算機能夠識別的格式:

hdfs oev -i edits_inprogress_0000000000000003454.xml -o edits_inprogress_0000000000000003454 -p binary

 

最後再啟動NameNode和DataNode節點,檢視誤刪檔案的恢復情況。

 

關聯文章:

必須掌握的分散式檔案儲存系統—HDFS

HDFS重要知識點

Hadoop調優


 

關注微信公眾號:大資料學習與分享,獲取更對技術乾貨

相關文章