使用 Hadoop 服務註冊

Hadoop 服務註冊可以使用在許多方面:-

  1. 使用與 YARN 應用程式生命週期相符的項目來註冊動態 YARN 部署的應用程式。服務記錄可以設定在 YARN 應用程式、應用程式嘗試或個別容器完成時刪除。
  2. 查詢靜態或動態應用程式,以及與它們通訊的機制。這些機制可以包括:HTTP(S) URL、Zookeeper 路徑、主機名稱和埠,甚至 Hadoop 檔案系統中指向組態資料的路徑。
  3. 在安全叢集中,驗證服務繫結是否已由特定使用者或系統帳戶發布。這可以透過查看項目放置的路徑來完成。
  4. 註冊靜態應用程式。這些應用程式會保留在註冊中,直到刪除為止。它們可以視需要更新。

註冊表的使用者可以同時是條目(服務記錄)的發佈者,也可以是透過其服務記錄找到的其他服務的使用者。分散式應用程式的不同部分也可以將其用於不同的目的。舉例來說,YARN 應用程式的應用程式主控程式可以發佈繫結,供其工作人員容器使用。然後,在容器中執行的程式碼可以查詢繫結,以與該管理員進行通訊,即使該管理員已在叢集的不同節點上重新啟動。用戶端應用程式可以查詢外部服務端點,以透過公開 API 與 AM 進行互動。

註冊表無法用於:-

註冊表應用程式設計模式

註冊其公開服務端點的短期 YARN 應用程式主控程式。

  1. 部署 YARN 應用程式。在安全叢集中,會提供 kerberos 令牌,以便寫入註冊表。
  2. 啟動時,它會在已知路徑建立服務記錄
  3. 此記錄可能有應用程式嘗試持續性政策和應用程式嘗試的 ID
    yarn:persistence = "application_attempt"
    yarn:id = ${application_attemptId}
    

    這表示,即使建立新的嘗試,此記錄也會在應用程式嘗試完成時刪除。每個應用程式嘗試都必須重新註冊端點,而這可能是找到服務所需要的。

  4. 或者,此記錄可能有「應用程式」的持續性政策
    yarn:persistence = "application_attempt"
    yarn:id = application_attemptId
    

    這表示,此記錄會持續存在,即使在應用程式嘗試之間也是如此,儘管端點資訊已過時。

  5. 用戶端應用程式透過路徑查詢服務。

路徑的選擇是應用程式特定的。對於保證 YARN 應用程式名稱唯一的服務,我們建議採用以下慣例

/users/${username}/applications/${service-class}/${instance-name}

或者,可以在路徑中使用應用程式 ID

/users/${username}/applications/${service-class}/${applicationId}

後者使得將 YARN 應用程式清單條目對應到服務記錄變得非常簡單。

用戶端應用程式可以找到服務

  • 透過列舉服務類別的所有執行個體,並根據特定標準選取一個。
  • 從提供的服務類別和執行個體名稱
  • 如果依應用程式 ID 列出,則從服務類別和應用程式 ID

找到服務記錄後,用戶端可以列舉外部繫結,並找到具有所需 API 的條目。

註冊其公開服務端點的 YARN 容器

這裡 YARN 應用程式中的所有容器都發佈服務端點,供公開使用。

  1. 已部署的容器會傳遞它們應註冊其下的基本路徑。
  2. 長駐容器必須傳遞一個 id:password 配對,讓它們有權限在沒有使用者的 kerberos 認證資料的情況下更新這些條目。這讓容器可以在授予 AM 寫入權限至登錄路徑的使用者權杖過期後,更新它們的條目。
  3. 容器會使用 id:password 配對建立登錄作業實例。
  4. 然後它們會在包含下列的路徑上註冊服務記錄
    ${base-path} + "/" + RegistryPathUtils.encodeYarnID(containerId)
    

    此記錄應具有容器持久性政策和容器 ID

    yarn:persistence = "container"
    yarn:id = containerId
    

    當容器終止時,條目會自動刪除。

  5. 此容器已部署服務的已匯出服務端點應列在服務記錄的 external 端點清單中。

  6. 用戶端可以透過列出 ${base-path} 下的條目,列舉 YARN 應用程式匯出的所有容器。

註冊靜態叢集服務。

通常固定在叢集中的服務,但需要發佈繫結和組態資訊的服務,可以發佈在登錄中。範例:Apache Oozie 服務。已部署應用程式可能也發佈至叢集外部的服務。範例:Amazon Dynamo 實例。

這些服務可以註冊在屬於執行服務的使用者路徑下,例如 /users/oozie/users/hbase。用戶端應用程式會使用此路徑。雖然這可以驗證服務記錄的有效性,但它依賴於用戶端應用程式知道服務已部署的使用者名稱,或已組態完整路徑。

另一種方式是讓服務部署在 /services 下的靜態服務路徑下。例如,/services/oozie 可以包含 Oozie 服務的註冊。由於此路徑的權限限制為預先組態的系統帳戶,因此在安全叢集上此路徑上的服務註冊的存在,確認它是由叢集管理工具註冊的。

  1. 此服務是由一些管理工具或直接由叢集操作員部署的。
  2. 已部署的應用程式可以在給予登錄繫結資訊的情況下,在自己的使用者名稱下註冊自己。
  3. 如果應用程式要註冊在 /services 下,且它是由其中一個系統使用者帳戶部署的,它可以自行註冊。
  4. 如果應用程式沒有這樣做的權限,叢集管理工具必須代替註冊服務。
  5. 用戶端應用程式可以透過解析其眾所周知/已設定路徑來尋找服務。
  6. 如果服務已停止,管理工具可能會刪除該項目,或保留該項目但刪除其所有服務端點。這是表示「服務已知但目前無法存取」的建議慣例。
  7. 當服務重新啟動時,其繫結資訊可能會更新,或其整個登錄項目可能會重新建立。

YARN 容器尋找其應用程式主控程式

在此,YARN 容器會向其 AM 註冊以接收工作,通常透過某種心跳機制,定期回報。如果 AM 已設定為容器在應用程式嘗試結束後繼續執行,則當 AM 發生故障時,容器會繼續執行。這些容器需要繫結至任何重新啟動的 AM。它們也可能希望得出結論,如果 AM 沒有重新啟動,它們最終應該逾時並自行終止。此類政策有助於應用程式對應網路分割。

  1. YARN AM 會發布其服務端點,例如 IPC 通訊所需的 FQDN 和 socket 埠,或 REST 通道所需的 HTTP/HTTPS URL。這些會發布在 internal 端點清單中,其中 api 欄位設定為容器使用的特定 API 的 URL。
  2. YARN 容器會在傳遞給它們的服務記錄路徑(某種方式)中啟動。環境變數或命令列參數是兩種可行的機制。共用機密也應該這樣傳遞:命令列參數會顯示在 unix ps 指令中。更安全的方法是將共用機密儲存在叢集檔案系統,將路徑傳遞給容器。此類路徑的 URI 可能會是應用程式的已註冊內部端點之一。
  3. YARN 容器會查詢服務登錄以識別通訊繫結。
  4. 如果找不到已註冊的服務項目,容器可能會執行下列其中一項:結束。以某個(抖動)重試期間旋轉,輪詢項目,直到項目重新出現。這表示已找到 AM。
  5. 如果找到服務項目,用戶端應該嘗試在其頻道上與 AM 通訊。共用驗證詳細資料可用於驗證用戶端與伺服器,反之亦然。
  6. 用戶端會回報給 AM,直到連線開始無法連線或驗證,或直到長駐連線中斷且無法重新啟動。
  7. 在這個時間點,客戶端可能會回到步驟 (3)。同樣地,某些具有抖動的退避政策有助於防止新重新啟動的 AM 過載。容器也可能在某些逾時時間後,得出 AM 沒有回來的結論並退出。
  8. 我們建議,除了 AM 可能對客戶端發出的功能命令外,也可以對容器發出「終止」命令。這允許系統處理 YARN 節點管理員終止而衍生的容器持續運作的特定情況。

YARN 應用程式和容器發布其管理和指標繫結

管理埠和繫結僅是其他要發布的端點。這些應發布為內部端點,因為它們不供公開使用。

客戶端應用程式透過端點 API 列舉服務

客戶端應用程式希望找出實作特定 API 的所有服務,例如 "classpath://org.apache.hbase"

  1. 客戶端從註冊表的路徑開始
  2. 客戶端呼叫 registryOperations.list(path) 以列出該路徑下所有節點,取得子節點的相對清單。
  3. 客戶端透過對每個子節點呼叫 stat() 來列舉子記錄狀態。
  4. 對於所有狀態項目,如果項目的大小大於 ServiceRecordHeader.getLength() 的值,它可能會包含服務記錄。
  5. 可以使用 resolve() 作業來擷取內容。如果成功,它確實包含服務記錄,因此客戶端可以列舉外部端點,並找出具有所需 API 的端點。
  6. 應檢查每個 RegistryPathStatus 狀態項目的 children 欄位。如果它大於或等於 0,應對該項目的路徑執行遞迴列舉。
  7. 作業最終會完成,並提供所有項目的清單。
  8. 可以選擇其中一個列舉的端點,並將其用作服務的繫結資訊

此演算法描述了註冊表樹的深度優先搜尋。當然,可以進行變更,包括廣度優先搜尋,或在找到單一進入點時立即停止搜尋。也可以選擇對不同的子樹進行平行搜尋,這可能會縮短搜尋時間,儘管是以增加註冊表基礎架構上的客戶端負載為代價。

一個工具類別 RegistryUtils 提供靜態工具方法,用於常見的登錄操作,特別是,RegistryUtils.listServiceRecords(registryOperations, path) 執行指定路徑的所有立即子記錄條目的列示和收集。

客戶端應用程式會遇到「當端點無效時該怎麼辦」的問題,特別是當服務未執行時,該怎麼辦?

有些傳輸假設中斷是暫時的,並且針對原始繫結進行旋轉重試是正確的策略。這是 Hadoop IPC 客户端的預設政策。

其他傳輸會快速失敗,立即透過例外或其他機制報告失敗。這對客戶端是直接可見的,但允許客戶端重新掃描登錄並重新繫結到應用程式。

最後,有些應用程式從一開始就設計為動態故障轉移:它們發布的繫結資訊實際上是一個 zookeeper 路徑。Apache HBase 和 Apache Accumulo 就是這種情況的範例。登錄用於繫結的初始查詢,之後客戶端會自然而然地對故障具有復原力。