瞭解HDFS恢復過程(第2部分)Best Practices for Hive Authorization Using Apache Ranger in HDP 2.2

轉載https://clouderatemp.wpengine.com/blog/2015/03/understanding-hdfs-recovery-processes-part-2/

很好的文章,但是要翻牆轉載給國內的夥伴,作者有問題請聯繫刪除

在運行或轉向可用於生產環境的Apache Hadoop時,掌握HDFS恢復過程非常重要。在由兩部分組成的結論中,解釋了管道恢復。

HDFS的一項重要設計要求是確保連續且正確的操作支持生產部署。因此,對於操作員而言,瞭解HDFS恢復過程的工作方式非常重要。在這篇文章的第1部分中,我們研究了租賃回收和大塊回收。現在,在第2部分中,我們將探討管道恢復。

這三個恢復過程對於HDFS容錯至關重要。它們共同幫助確保即使在存在網絡和節點故障的情況下,HDFS中的寫入也持久且一致。

概括

在HDFS中,文件分爲多個塊,並且文件訪問遵循多讀取器,單寫入器的語義。爲了滿足容錯要求,一個塊的多個副本存儲在不同的DataNode上。副本數稱爲複製因子。創建新文件塊或打開現有文件進行追加時,HDFS寫入操作將創建一個DataNodes管道以接收和存儲副本(複製因子通常確定該管道中DataNode的數量)。隨後對該塊的寫入將通過管道(圖1)。

圖1. HDFS寫管道

對於讀取操作,客戶端選擇保存該塊副本的DataNode之一,並請求從中進行數據傳輸。

要深入瞭解此背景信息,請閱讀本文的第1部分。

管道恢復

寫管道

HDFS客戶端寫入文件時,數據將按順序塊寫入。爲了寫入或構造一個塊,HDFS將該塊分解爲數據包(實際上不是網絡數據包,而是消息;術語“ 數據包”指代體現這些消息的類),並將其傳播到寫入管道中的DataNodes,如圖所示。 2。

 

圖2. HDFS寫入管道階段

寫管道包括三個階段:

  1. 管道設置。客戶端沿着管道發送Write_Block請求,最後一個DataNode發回確認。收到確認後,管道即可進行寫入。
  2. 數據流。數據以數據包的形式通過管道發送。客戶端緩衝數據,直到數據包填滿爲止,然後將數據包發送到管道。如果客戶端調用hflush(),則即使數據包未滿,它也將被髮送到管道,並且直到客戶端接收到對先前hflush數據包的確認後,纔會發送下一個數據包。
  3. 關閉(完成副本並關閉管道)。客戶端等待,直到所有數據包都已確認,然後發送關閉請求。管道中的所有DataNode將相應的副本更改爲FINALIZED狀態,並報告回NameNode。如果至少已配置的最小數據複製數量報告了其對應副本的FINALIZED狀態,則NameNode會將塊的狀態更改爲COMPLETE。

管道恢復

當在寫入塊時,管道中的一個或多個DataNode在三個階段中的任何一個階段遇到錯誤時,都會啓動管道恢復。

從管道設置故障中恢復

  1. 如果爲新塊創建了管道,則客戶端將放棄該塊,並向NameNode請求一個新塊和一個新的DataNode列表。爲新塊重新初始化管道。
  2. 如果創建了管道以附加到塊,則客戶端將使用剩餘的DataNode重建管道,並增加塊的生成標記。

從數據流故障中恢復

  1. 當管道中的DataNode檢測到錯誤(例如,校驗和錯誤或寫入磁盤失敗)時,該DataNode將通過關閉所有TCP / IP連接將自身從管道中移出。如果認爲數據未損壞,它還會將緩衝的數據寫入相關的塊和校驗和(METADATA)文件。
  2. 當客戶端檢測到故障時,它將停止向管道發送數據,並使用剩餘的良好DataNode重建新的管道。結果,該塊的所有副本都被碰撞到新的GS。
  3. 客戶端將繼續使用此新GS發送數據包。如果發送的數據已被某些DataNode接收,則它們只是忽略該數據包並將其傳遞到管道的下游。

從關閉失敗中恢復

  1. 當客戶端在關閉狀態下檢測到故障時,它將使用剩餘的DataNode重建管道。如果尚未確定副本,則每個DataNode都會提高該塊的GS並確定副本。

當一個DataNode損壞時,它將自己從管道中刪除。在管道恢復過程中,客戶端可能需要使用剩餘的DataNode重建新的管道。(根據下一節中描述的DataNode替換策略,它可能會也可能不會用新的DataNode替換壞的DataNode。)複製監視器將負責複製該塊以滿足配置的複製因子。

失敗時的DataNode替換策略

關於建立與其餘DataNode的恢復管道時是否添加其他DataNode來替換不良DataNode,有四種可配置的策略:

  1. DISABLE:禁用DataNode替換並引發錯誤(在服務器上);這就像從來沒有在客戶端一樣。
  2. 永不:當管道發生故障時(通常不是理想的操作),切勿替換DataNode。
  3. 默認:根據以下條件進行更換:
    1. 令r爲配置的複製號。
    2. 令n爲現有副本數據節點的數量。
    3. 僅在r> = 3且僅此時添加一個新的DataNode
      •   floor(r / 2)> = n; 要麼
      •   r> n,並且該塊被填充/附加。
  4. 總是:當現有DataNode發生故障時,請始終添加新的DataNode。如果無法替換DataNode,此操作將失敗。

要禁用使用這些策略中的任何一個,可以將以下配置屬性設置爲false(默認值爲true):

dfs.client.block.write.replace-datanode-on-failure.enable

啓用後,默認策略爲DEFAULT。以下配置屬性更改了策略:

dfs.client.block.write.replace-datanode-on-failure.policy

使用DEFAULT或ALWAYS時,如果只有一個DataNode在管道中成功,則恢復將永遠不會成功,並且客戶端將無法執行寫入。此問題通過以下配置屬性解決:

dfs.client.block.write.replace-datanode-on-failure.best-effort

默認爲false。使用默認設置,客戶端將繼續嘗試直到滿足指定的策略。當將此屬性設置爲true時,即使無法滿足​​指定的策略(例如,管道中只有一個成功的DataNode成功,小於策略要求),仍將允許客戶端繼續來寫。

一些已解決的問題

  • HDFS-5016詳細介紹了管道恢復中的死鎖情形,該死鎖情形導致DataNode被標記爲已死(重複HDFS-3655 “ Datanode recoveryRbw可能會掛起”和HDFS-4851 “管道恢復中的死鎖”)。發生的情況是:恢復正在進行時,它將導致一些相關的線程互相等待,從而導致死鎖。由於FSDataset鎖保持在此死鎖中,因此心跳線程和數據收發器線程被阻塞,等待FSDataset鎖。解決方案是引入超時機制以打破僵局。
  • HDFS-4882報告了一個情況,即NameNode的LeaseManager在checkLeases中永遠循環。硬限制到期後,如果倒數第二個塊爲COMMITTED,而最後一個塊爲COMPLETE,則LeaseManager嘗試恢復租約,internalReleaseLease()將在不釋放租約的情況下返回,並且LeaseManager將繼續嘗試釋放相同的租約,因此無限循環 由於FSNamesystem.writeLock保留在循環中,因此實質上使NameNode無響應。解決方法是僅嘗試定期而不是連續釋放租賃。
  • HDFS-5557詳細介紹了以下情況:由於處理塊報告時錯誤的GS記錄,導致塊中最後一個數據包的寫管道恢復可能導致拒絕有效副本。最壞的情況是,所有好的副本都將被拒絕,而壞的副本將被接受。在這種情況下,相應的塊將完成,但是隻有在收到包含有效副本之一的下一個完整塊報告之後,才能讀取數據。解決方案是修復GS記錄。
  • HDFS-5558報告了以下情況:如果最後一個塊已完成,而倒數第二個塊未完成,則LeaseManager監視線程可能崩潰。如果文件的最後一個和倒數第二個塊均未處於COMPLETE狀態,並且試圖關閉該文件,則最後一個塊可能會更改爲COMPLETE,而倒數第二個可能不會。如果這種情況持續很長時間並且文件被放棄,LeaseManager將嘗試恢復租約並在塊上進行塊恢復。但是internalReleaseLease()這種文件將因無效的強制轉換異常而失敗。解決方案是在關閉文件之前,確保倒數第二個塊處於COMPLETE狀態。

已知的未解決問題

  • 隨着的引入dfs.client.block.write.replace-datanode-on-failure.best-effort,即使只有一個DataNode,客戶端也將能夠繼續寫入。發生這種情況時,一個塊可能只有一個副本,並且如果在複製之前對該單個副本進行任何操作,則將發生數據丟失。爲了緩解該問題,HDFS-6867提出了一個後臺線程來在客戶端向單個副本進行寫操作時進行管道恢復。
  • HDFS-4504  詳細介紹了  DFSOutputStream#close並非總是釋放資源(例如租賃)的情況。在某些情況下,DFSOutputStream#close可以拋出IOException。一個示例是如果發生管道錯誤,然後管道恢復失敗。不幸的是,在這種情況下,所使用的某些資源DFSOutputStream被泄漏了。一個特別重要的資源是文件租用,因此,壽命長的HDFS客戶端(例如Apache Flume)可能會向文件寫入許多塊,但隨後無法關閉它。但是,客戶端中的LeaseRenewer線程將繼續爲“ undead”文件續訂租約。將來嘗試關閉文件只會重新拋出先前的異常,客戶端無法取得任何進展。
  • HDFS-6937詳細介紹了由於校驗和錯誤導致的管道恢復問題。中間DataNode上的數據(假設複製因子3)以某種方式被破壞,但未被檢測到。最後一個DataNode發現了校驗和錯誤,並將自己從管道中取出。恢復過程一直在嘗試用新的替換新的管道中的最後一個DataNode,並將數據從中間的DataNode複製到新的DataNode。每次由於校驗和錯誤而導致複製失敗(由於中間DataNode處的副本已損壞),並且新的DataNode被標記爲不良並被丟棄,即使它不是很糟糕。最終,在耗盡所有數據節點後,恢復將失敗。
  • HDFS-7342報告了以下情況:當倒數第二個塊爲COMMITTED且最後一個塊爲COMPLETE時,租賃恢復無法成功。一個建議的解決方案是強制收回租約,這與在最後一個塊被提交時的處理方式類似。可以看到,HDFS-7342,HDFS-4882和HDFS-5558的相關性在於倒數第二個塊處於COMMITTED狀態。問題的微妙性目前仍在調查中。

結論

租用恢復,塊恢復和管道恢復對於HDFS容錯都是必不可少的。他們共同確保即使在存在網絡和節點故障的情況下,HDFS中的寫入操作也是持久且一致的。

希望在閱讀這些文章之後,您可以更好地瞭解何時,爲什麼調用這些過程以及它們的作用。如果您想了解更多信息,則可以通讀一些鏈接,包括設計規範,此處引用的JIRA或相關代碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章