解析分佈式應用框架 Ray 架構源碼

​​​​摘要:Ray 的定位是分佈式應用框架,主要目標是使能分佈式應用的開發和運行。

Ray 是 UC Berkeley 大學 RISE lab(前 AMP lab)2017 年 12 月 開源的新一代分佈式應用框架(剛發佈的時候定位是高性能分佈式計算框架,20 年中修改定位爲分佈式應用框架),通過一套引擎解決複雜場景問題,通過動態計算及狀態共享提高效率,實現研發、運行時、容災一體化。

業務目標

Ray 的定位是分佈式應用框架,主要目標是使能分佈式應用的開發和運行。

業務場景

具體的粗粒度使用場景包括

Ray 的 API 讓開發者可以輕鬆的在單個分佈式應用中組合多個 libraries,例如,Ray 的 tasks 和 Actors 可能會 call into 或 called from 在 Ray 上運行的分佈式訓練(e.g. torch.distributed)或者在線服務負載; 在這種場景下, Ray 是作爲一個 “分佈式膠水” 系統,因爲它提供通用 API 接口並且性能足以支撐許多不同工作負載類型。

系統設計目標

相關係統上下文

系統設計

邏輯架構:

領域模型

集羣設計

如上圖所示,Ray 集羣包括一組同類的 worker 節點和一個集中的全局控制存儲(GCS)實例。

部分系統元數據由 GCS 管理,GCS 是基於可插拔數據存儲的服務,這些元數據也由 worker 本地緩存,例如 Actor 的地址。 GCS 管理的元數據訪問頻率較低,但可能被羣集中的大多數或所有 worker 使用,例如,羣集的當前節點成員身份。這是爲了確保 GCS 性能對於應用程序性能影響不大。

Ownership

  1. 低任務延遲(〜1 RTT,<200us)。經常訪問的系統元數據對於必須對其進行更新的過程而言是本地的。

  2. 高吞吐量(每個客戶端約 10k 任務 / 秒;線性擴展到集羣中數百萬個任務 / 秒),因爲系統元數據通過嵌套的遠程函數調用自然分佈在多個 worker 進程中。

  3. 簡化的架構。owner 集中了安全垃圾收集對象和系統元數據所需的邏輯。

  4. 提高了可靠性。可以根據應用程序結構將工作程序故障彼此隔離,例如,一個遠程調用的故障不會影響另一個。

  1. 要解析 “ObjectRef”,對象的 owner 必須是可及的。這意味着對象必須與其 owner 綁定。有關對象恢復和持久性的更多信息,請參見 object 故障和 object 溢出。

  2. 目前無法轉讓 ownership。

核心組件

  1. 一個或多個工作進程,負責任務的提交和執行。工作進程要麼是無狀態的(可以執行任何 @ray.remote 函數),要麼是 Actor(只能根據其 @ray.remote 類執行方法)。每個 worker 進程都與特定的作業關聯。初始工作線程的默認數量等於計算機上的 CPU 數量。每個 worker 存儲 ownership 表和小對象:
    a. Ownership 表。工作線程具有引用的對象的系統元數據,例如,用於存儲引用計數。
    b. in-process store,用於存儲小對象。

2.Raylet。raylet 在同一羣集上的所有作業之間共享。raylet 有兩個主線程:
a. 調度器。負責資源管理和滿足存儲在分佈式對象存儲中的任務參數。羣集中的單個調度程序包括 Ray 分佈式調度程序。
b. 共享內存對象存儲(也稱爲 Plasma Object Store)。負責存儲和傳輸大型對象。集羣中的單個對象存儲包括 Ray 分佈式對象存儲。

每個工作進程和 raylet 都被分配了一個唯一的 20 字節標識符以及一個 IP 地址和端口。相同的地址和端口可以被後續組件重用(例如,如果以前的工作進程死亡),但唯一 ID 永遠不會被重用(即,它們在進程死亡時被標記爲墓碑)。工作進程與其本地 raylet 進程共享命運。

  1. 全局控制存儲 (GCS)。GCS 是一個鍵值服務器,包含系統級元數據,如對象和參與者的位置。GCS 目前還不支持高可用,後續版本中 GCS 可以在任何和多個節點上運行,而不是指定的頭節點上運行。

2.Driver 進程 (es)。Driver 是一個特殊的工作進程,它執行頂級應用程序(例如,Python 中的__main__)。它可以提交任務,但不能執行任何任務本身。Driver 進程可以在任何節點上運行。

交互設計

應用的 Driver 可以通過以下方式之一連接到 Ray:

  1. 調用 `ray.init()’,沒有參數。這將啓動一個嵌入式單節點 Ray 實例,應用可以立即使用該實例。

  2. 通過指定 ray.init(地址 =)連接到現有的 Ray 集羣。在後端,Driver 將以指定的地址連接到 GCS,並查找羣集其他組件的地址,例如其本地 raylet 地址。Driver 必須與 Ray 羣集的現有節點之一合部。這是因爲 Ray 的共享內存功能,所以合部是必要的前提。

  3. 使用 Ray 客戶端 `ray.util.connect()'從遠程計算機(例如筆記本電腦)連接。默認情況下,每個 Ray 羣集都會在可以接收遠程客戶端連接的頭節點上啓動一個 Ray ClientServer,用來接收遠程 client 連接。但是由於網絡延遲,直接從客戶端運行的某些操作可能會更慢。

Runtime

所有 Ray 核心組件都是用 C++ 實現的。Ray 通過一個名爲 “coreworker” 的通用嵌入式 C++ 庫支持 Python 和 Java。此庫實現 ownership 表、進程內存儲,並管理與其他工作器和 Raylet 的 gRPC 通信。由於庫是用 C++ 實現的,所有語言運行時都共享 Ray 工作協議的通用高性能實現。

Task 的 lifetime

Owner 負責確保提交的 Task 的執行,並促進將返回的 ObjectRef 解析爲其基礎值。如下圖,提交 Task 的進程被視爲結果的 Owner,並負責從 raylet 獲取資源以執行 Task,Driver 擁有 A 的結果,Worker 1 擁有 B 的結果。

  1. 應用程序級。這是工作進程處於活動狀態,但任務以錯誤結束的任何場景。例如,在 Python 中拋出 IndexError 的任務。

  2. 系統級。這是工作進程意外死亡的任何場景。例如,隔離故障的進程,或者如果工作程序的本地 raylet 死亡。

1.src/ray/core_worker/core_worker.cc

2.src/ray/common/task/task_spec.h

3.src/ray/core_worker/transport/direct_task_transport.cc

4.src/ray/core_worker/transport / 依賴關係_解析器. cc

5.src/ray/core_worker/task_manager.cc

6.src/ray/protobuf/common.proto

Object 的 lifetime

下圖 Ray 中的分佈式內存管理。worker 可以創建和獲取對象。owner 負責確定對象何時安全釋放。

  1. 將 ObjectRef 或包含 ObjectRef 的對象作爲參數傳遞給 Task。

  2. 從 Task 中返回 ObjectRef 或包含 ObjectRef 的對象。

  1. 在 ObjectRef 上調用 ray.get。

  2. 將 ObjectRef 作爲參數傳遞給任務。執行工作程序將解析 ObjectRefs,並將任務參數替換爲解析的值。

1.src/ray/core_worker/store_Provider/memory_store/memory_store.cc

2.src/ray/core_worker/store_Provider/plasma_store_provider.cc

3.src/ray/core_worker/reference_count.cc

4.src/ray/object_manager/object_manager.cc

Actor 的 lifetime

Actor 的 lifetimes 和 metadata (如 IP 和端口) 是由 GCS service 管理的. 每一個 Actor 的 Client 都會在本地緩存 metadata,使用 metadata 通過 gRPC 將 task 發送給 Actor.

如上圖,與 Task 提交不同,Task 提交完全分散並由 Task Owner 管理,Actor lifetime 由 GCS 服務集中管理。

  1. 執行 Actor 任務不需要從調度器獲取資源。這是因爲在計劃其創建任務時,參與者已在其生命週期內獲得資源。

  2. 對於 Actor 的每個調用者,任務的執行順序與提交順序相同。

1.Core worker 源碼: src/ray/core_worker/core_worker.h. 此代碼是任務調度、Actor 任務調度、進程內存儲和內存管理中涉及的各種協議的主幹。

2.Python: python/ray/includes/libcoreworker.pxd

3.Java: src/ray/core_worker/lib/java

4.src/ray/core_worker/core_worker.cc

5.src/ray/core_worker/transport/direct_actor_transport.cc

6.src/ray/gcs/gcs_server/gcs_actor_manager.cc

7.src/ray/gcs/gcs_server/gcs_actor_scheduler.cc

8.src/ray/protobuf/core_worker.proto

本文分享自華爲雲社區《分佈式應用框架 Ray 架構源碼解析》,原文作者:Leo Xiao 。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://juejin.cn/post/6939762041913606152?utm_source=gold_browser_extension