【深入淺出 Yarn 架構與實現】6-3 NodeManager 分散式快取

2023-05-08 21:00:28

不要跳過這部分知識,對了解 NodeManager 本地目錄結構,和熟悉 Container 啟動流程有幫助。

一、分散式快取介紹

主要作用就是將使用者應用程式執行時,所需的外部檔案資源下載快取到各個節點。
YARN 分散式快取工作流程如下:

  1. 使用者端將應用程式所需的檔案資源 (外部字典、JAR 包、二進位制檔案) 提交到 HDFS 上。
  2. 使用者端將應用程式提交到 RM 上。
  3. RM 將與某個 NM 進行通訊,啟動應用程式 AM,NM 收到命令後,首先從 HDFS 上下載檔案 (快取),然後啟動 AM。
  4. AM 與 RM 通訊,以請求和獲取計算資源。
  5. AM 收到新分配到的計算資源後,與對應的 NM 通訊,以啟動任務。
  6. 如果應用程式第一次在該節點上啟動任務,NM 首先從 HDFS 上下載檔案快取到本地,然後啟動任務。
  7. NM 後續收到啟動任務請求後,如果檔案已在本地快取,則直接執行任務,否則等待檔案快取完成後再啟動。
  8. 各個節點上的快取檔案由對應的 NM 管理和維護。在 Hadoop 中,分散式快取並不是將檔案快取到叢集中各個節點的記憶體中,而是將檔案快取到各個節點的磁碟上,以便執行任務時直接從磁碟上讀取檔案。

二、特性介紹

一)資源可見性和分類

分散式快取機制是由各個 NM 實現的,主要功能是將應用程式所需的檔案資源快取到本地,以便後續任務的使用。
資源快取是使用時觸發的,也就是第一個用到該資源的任務觸發。後續任務無需再進行快取,直接使用即可。
根據可見性,NM將資源分為三類:

  • Public:節點上所有的使用者都可以共用該資源,只要有一個使用者的應用程式將著這些資源快取到本地,其他所有使用者的所有應用程式都可以使用;
  • Private:節點上同一使用者的所有應用程式共用該資源,只要該使用者其中一個應用程式將資源快取到本地,該使用者的所有應用程式都可以使用;
  • Application:節點上同一應用程式的所有Container共用該資源。

YARN是通過比較 resource、type、timestamp 和 pattern四個欄位是否相同來判斷兩個資源請求是否相同的。如果一個已經被快取到各個節點上的檔案被使用者修改了,則下次使用時會自動觸發一次快取更新,以重新從HDFS上下載檔案。
分散式快取完成的主要功能是檔案下載,涉及大量的磁碟讀寫,因此整個過程採用了非同步並行模型加快檔案下載速度,以避免同步模型帶來的效能開銷。

二)分散式快取實現

NodeManager 採用輪詢的分配策略將這三類資源存放在 yarn.nodemanager.local-dirs 指定的目錄列表中,在每個目錄中,資源按照以下方式存放:

  • PUBLIC 資源:存放在 ${yarn.nodemanager.local-dirs}/filecache/ 目錄下,每個資源將單獨存放在以一個隨機整數命名的目錄中,且目錄的存取許可權均為 0755。
  • PRIVATE 資源:存放在 ${yarn.nodemanager.local-dirs}/usercache/${user}/filecache/ 目錄下,每個資源將單獨存放在以一個隨機整數命名的目錄中,且目錄的存取許可權均為 0710。
  • APPLICATION 資源:存放在 ${yarn.nodemanager.local-dirs}/usercache/${user}/${appcache}/${appid}/filecache/ 目錄下,每個資源將單獨存放在以一個隨機整數命名的目錄中,且目錄的存取許可權均為 0710。

其中 Container 的工作目錄位於 ${yarn.nodemanager.local-dirs}/usercache/${user}/${appcache}/${appid}/${containerid} 目錄下,其主要儲存 jar 包檔案、字典檔案對應的軟連結。
目錄結構如下所示:

./nm-local-dir/
|-- filecache		// PUBLIC資源
|   `-- 10			// 每個資源將單獨存放在以一個隨機整數命名的目錄中
|-- nmPrivate
|   |-- application_xxxx_xxx
|   |   |-- container_xxx_xxx_xxx_xx_xxxx
|   |   |-- container_xxx_xxx_xxx_xx_xxxx	// 私有目錄資料(執行指令碼、token檔案、pid檔案)
|   |   |   |-- container_xxx_xxx_xxx_xx_xxxx.pid
|   |   |   |-- container_xxx_xxx_xxx_xx_xxxx.tokens
|   |   |   `-- launch_container.sh
|   |-- application_xxxx_xxx
|   `-- application_xxxx_xxx
`-- usercache
    |-- userXxx
    |   |-- appcache		// APPLICATION資源
    |   `-- filecache		// PRIVATE資源
    |-- userXxx
    |   |-- appcache
    |   `-- filecache

三、清理策略

1、Container 執行結束清理
2、清理過期快取
NodeManager 為了避免快取的檔案過多導致磁碟「撐爆」,其會定期清理過期的快取檔案,具體方法如下:

  • 每隔一定時間 yarn.nodemanager.localizer.cache.cleanup.interval-ms(單位是毫秒,預設值是 10×60×1000,即 10 分鐘)啟動一次清理工作,確保每個快取目錄中檔案容量小於 yarn.nodemanager.localizer.cache.target-size-mb(單位是 MB,預設是 10240,即 10GB)
  • 如果超過該值,則採用 LRU(Least Recently Used)演演算法清除已不再使用的快取檔案,直至檔案容量低於設定值。

四、小結

本篇介紹了 NodeManager 分散式快取,當你需要看 NM 本地目錄,需要了解各目錄中儲存內容時,本篇提供了對應的幫助。同時也對 Container 啟動流程做了簡要的講解,對後面瞭解 Container 生命週期提供了一定的前置知識。