Ray 是一個功能強大的分散式計算框架,能夠有效處理大規模資料和複雜計算任務。它不僅提供簡潔易用的 Python API,更支援自動擴充套件計算資源,讓開發者無需管理伺服器,專注於程式碼邏輯。Ray 支援多種佈署環境,從本地開發到雲端,甚至 Kubernetes 和 Yarn 等資源管理工具,都能輕鬆執行。其核心技術包含 actors 模型、工作流程管理、高效能計算支援,以及針對機器學習的最佳化函式庫,例如 Ray Tune、Ray Train 和 RLlib。Ray 的物件儲存和分散式排程系統,使其在處理大規模資料和複雜計算任務時表現出色。相較於 Spark,Ray 更適合計算密集型任務,尤其在機器學習領域,其低任務開銷和分散式狀態管理更具優勢。Ray 也能與 Spark 互補,例如透過 RayDP 在 Ray 中使用 Spark DataFrames。此外,Ray 提供了 Serve 元件,專注於提升即時應用效能,並支援流式處理,可與 Kafka 整合作為資料來源和接收器。雖然 Ray 功能強大,但並非萬能,它不適合作為 SQL 引擎、資料儲存系統或在高要求環境中使用。理解 Ray 的優缺點和適用場景,才能更好地發揮其潛力。
Ray 及其應用場景
Ray 是一個快速且簡單的 Python 工具,專注於分散式計算。Ray 由加州大學伯克利分校的 RISELab 開發,這個實驗室早期也創造了 Apache Spark 的初始軟體。研究人員從 RISELab 創辦了 Anyscale 公司,繼續發展並提供 Ray 的產品與服務。除了 Python 外,Ray 也支援 Java 語言。在底層,Ray 應用了大量 C++ 和一些 Fortran,Ray 流處理還包含了部分 Java 元件。
Ray 的目標是在於解決更多元化的問題,支援多種可擴充套件的程式模型,包括從 actors(行為者)到機器學習(ML)再到資料平行。Ray 的遠端函式和 actors 模型使它成為一個真正通用的開發環境,而不是僅僅針對大資料。
Ray 的主要特點
-
自動擴充套件計算資源: Ray 自動根據需要擴充套件計算資源,讓開發者可以專注於程式碼本身,而不需要管理伺服器。除了傳統的水平擴充套件(如增加更多機器),Ray 還能將任務排程到不同大小的機器和加速器(如圖形處理單元, GPU)上。
-
無伺服器計算基礎: 自從 Amazon Web Services (AWS) Lambda 的引入,無伺服器計算模式的興趣急劇增加。在這種雲端運算模式下,雲端服務提供商根據需求分配機器資源,並代為管理伺服器。Ray 提供了強大的無伺服器平台基礎功能:
- 隱藏伺服器:Ray 自動根據應用需求管理伺服器。
- 支援 actors 模型:除了無狀態的程式模型(大多數無伺服器實作中常見),Ray 也支援有狀態的程式模型。
- 指定資源:可以指定硬體加速器等所需資源。
- 直接通訊:支援任務間的直接通訊,適合複雜分散式應用。
-
豐富的函式庫支援: Ray 提供多種函式庫來簡化應用開發,全面利用 Ray 的無伺服器能力。通常我們需要不同工具來進行資料處理、工作流程管理等操作。使用一個工具來處理更多應用部分能夠簡化開發和維運管理。
為什麼需要 Ray?
當我們面臨過於龐大的問題時,需要像 Ray 這樣的工具來協助處理。隨著問題規模變大,可能需要從多核心擴充套件到多機器環境中,而 Ray 支援這些需求。當我們面臨未來一個月內使用者量、資料量或複雜度增加時,考慮使用 Ray 是一個不錯的選擇。
Ray 不僅能夠擴充套件到多台電腦上執行,還能在不直接管理伺服器的情況下進行擴充套件。電腦科學家 Leslie Lamport 說過,「一個分散式系統是指你不知道哪台電腦壞掉都能使你自己的電腦無法使用」。儘管這樣的故障仍然可能發生,但 Ray 能夠自動還原許多型別的故障。
Ray 的操作環境
Ray 能夠在筆記型電腦和雲端環境中同樣運作良好,且 API 一致。這為使用者提供了一個簡單且不需要立即轉移到雲端環境進行測試的開始選項。當我們熟悉 API 和應用結構後,只需將程式碼轉移到雲端環境即可獲得更好的可擴充套件性而不需要修改程式碼。
此圖示
graph TD;
A[單機執行] --> B[同步API];
B --> C[分散式系統];
C --> D[自動擴充套件];
D --> E[雲端佈署];
內容解密:
- 單機執行:Ray 能夠在筆記型電腦上進行執行測試。
- 同步API:無論是單機還是分散式執行,API 操作一致。
- 分散式系統:當應用規模增加時,可以切換到分散式系統執行。
- 自動擴充套件:Ray 能夠根據需求自動擴充套件資源。
- 雲端佈署:最終可將應用佈署到雲端以獲得更好的可擴充套件性。
玄貓總結: Ray 是一個功能強大且靈活的分散式計算工具,適合處理從小規模到大規模的計算任務。其自動化功能和豐富的函式庫支援使得開發者可以專注於核心邏輯而不必過於關心基礎設施細節。無論是單機測試還是大規模佈署,Ray 都能提供穩定且高效的執行環境。
Ray 的佈署環境與架構解析
Ray 是一個強大的分散式計算框架,能夠在多種環境中執行,從本地開發到雲端環境,甚至是資源管理工具如 Kubernetes 或 Yarn,甚至可以在 Raspberry Pi 上執行。玄貓將探討 Ray 的佈署方式、架構設計及其在生態系統中的定位。
Ray 可執行的環境
Ray 的靈活性使其能夠在不同的計算環境中執行,從個人電腦到雲端伺服器,甚至是 Kubernetes 或 Yarn 等叢集管理工具。以下是 Ray 的幾種主要佈署方式:
-
本地模式: 使用本地模式時,啟動 Ray 可以簡單到只需使用
pip install安裝並呼叫ray.init。現代 Ray 會自動初始化上下文,讓開發者更容易上手。 -
Ray 叢集: Ray 叢集由一個頭節點(head node)和多個工作節點(worker nodes)組成。頭節點除了具有工作節點的所有功能外,還包含兩個額外的元件:全域控制儲存(GCS)和自動擴充套件器(Autoscaler)。
全域控制儲存(GCS)
GCS 包含叢集範圍內的資訊,包括物件表、任務表、函式表和事件記錄。這些資訊用於 Web UI、錯誤診斷、除錯和分析工具。
自動擴充套件器(Autoscaler)
自動擴充套件器負責啟動和終止工作節點,以確保工作負載有足夠的資源執行同時最小化閒置資源。
-
Ray 節點架構 每個 Ray 節點都包含一個 Raylet,內部有兩個主要元件:物件儲存(Object store)和排程器(Scheduler)。
- 物件儲存: 所有物件儲存互相連線,形成一個類別似 Memcached 的分散式快取系統。
- 排程器: 每個 Ray 節點都提供一個本地排程器,能夠與其他節點通訊,形成一個統一的分散式排程系統。
在 Kubernetes 上執行 Ray
在 Kubernetes 上執行 Ray 時,可以使用 ray up 命令或 Ray Kubernetes 操作員來建立叢集。ray up 命令會執行以下步驟:
- 根據組態提供者的 SDK 或存取物理機器來佈署新例項。
- 執行 Shell 命令來設定 Ray 並設定所需選項。
- 初始化 Ray 叢集。
- 如果需要,佈署自動擴充套件器。
在不同環境下執行 Ray
依據佈署選項不同,相同的 Ray 程式碼可能會有顯著的速度差異。例如,當需要特定函式庫或硬體時,情況會變得更加複雜。玄貓將在後續章節中探討如何在本地模式下執行 Ray。
##-Ray 的編碼與叢集連線
Ray 不僅僅是一個可匯入的函式庫;它也是一個叢集管理工具。除了匯入函式庫之外,還需要連線到 Ray 叢集。以下是連線方式:
-
呼叫 ray.init 無引數: 這會啟動一個內嵌的單節點 Ray 例項,立即可供應用程式使用。
-
使用 Ray Client ray.init(“ray://<head_node_host>:10001”): 預設情況下,每個 Ray 叢集都會啟動一個在頭節點上執行的 Ray Client Server,可以接收遠端客戶端連線。
-
使用 Ray 命令列 API:
ray submit命令可以在叢集上執行 Python 指令碼。這會將指定的檔案複製到頭節點並使用給定引數執行它。
在生態系統中的定位
Ray 跨越了多種問題領域:
-
資源管理: 雖然本身並不是叢集排程器或平行框架的一部分,但它可以與之整合來提升效能和擴充套件性。例如 Dask 和 Spark 在 Ray 上執行時可以達到更高效能。
-
高層次機器學習函式庫: Ray 提供了 Serve、Datasets、Tune、RLlib、Train 和 Workflows 等高層次函式庫,專門針對機器學習問題進行最佳化。這些函式庫使得具有資料科學背景的人也能輕鬆使用分散式系統。
-
彈性分散式系統: 雖然不像 Kubernetes 等工具那樣專注於容器排程,但它可以很好地與之整合以提升計算效率和資源管理。
跨平台運用與比較
- 叢集排程工具: 如 Kubernetes、Slurm 和 Yarn 用於排程容器和資源分配。Ray 可以利用這些工具來分配叢集節點。
- 平行框架: 與 multiprocessing 或 Celery 相比,Ray 提供了更一般化、高效能的 API。
- 資料處理框架: 雖然不像 Spark 或 Dask 本身那樣處理資料流或關係型表格資料,但它支援在其上執行這些框架。
跨平台運用舉例:
import ray
from ray import serve
@serve.deployment
class MyModel:
def __init__(self):
# 初始化模型
pass
def __call__(self, request):
# 模型推理邏輯
return {"result": "success"}
# 啟動服務
serve.start()
MyModel.deploy()
內容解密:
import ray:匯入 ray 函式庫。@serve.deployment:這是 decorator ,用於指示 Serve 函式庫將此類別視為服務佈署單元。MyModel.__init__:初始化方法中可以載入模型引數或進行必要組態。MyModel.__call__:這是類別似於 HTTP 介面的一種呼叫方式,當有請求進來時會觸發此方法。serve.start():啟動 Serve。MyModel.deploy():佈署服務到 Serve 中。
案例驗證
假設有一個需求需要處理大量影像分類別任務並且需要高效的資源管理和分散式計算能力。使用上述程式碼結合 Kubernetes 排程管理和 GPU 資源分配來實作這樣的需求。
Ray 核心技術及其在生態系統中的角色
目錄
- 活動者框架
- 工作流程
- 高效能計算系統
- 大資料 / 可擴充套件的 DataFrames
- Ray 與 Spark 的比較
- 機器學習
- 工作流程排程
- 流式處理
- 互動式應用
活動者框架
Ray 的活動者框架與專門化框架如 Erlang、Akka 和 Orleans 有所不同,因為 Ray 將活動者框架直接整合到程式語言中。此外,Ray 的分散式物件支援活動者之間的資料分享。
Ray 的活動者框架使得開發者可以更方便地進行分散式計算,因為它不需要額外的設定或組態。Ray 的活動者可以在不同的節點上執行,並且可以分享資料。這使得開發者可以更容易地開發和佈署分散式應用程式。
工作流程
當大多數人討論工作流程時,他們通常指的是根據 UI 或指令碼驅動的低程式碼開發。雖然這種方法對於非技術使用者可能有用,但它往往給軟體工程師帶來更多的痛苦而不是價值。Ray 使用類別似於 Cadence 的程式化工作流程實作,這種實作將 Ray 的動態工作任務圖與強大的永續性保證結合起來。
Ray Workflows 提供子秒級的任務啟動開銷,支援具有數十萬個步驟的工作流程。它還利用 Ray 物件儲存函式庫在步驟之間傳遞分散式資料集。
高效能計算系統
與 Ray 不同,大多數高效能計算(HPC)系統公開低層次的訊息傳遞 API,提供更大的應用彈性。此外,許多 HPC 實作提供最佳化的集體通訊原語。Ray 提供一個集體通訊函式庫,實作許多這些功能。
大資料 / 可擴充套件的 DataFrames
Ray 提供了幾個可擴充套件 DataFrames 的 API,這是大資料生態系統的根本。Ray 建立在 Apache Arrow 專案之上,提供一個(有限)分散式 DataFrame API,稱為 ray.data.Dataset。這主要用於最簡單的轉換和從雲端或分散式儲存讀取資料。
除了 ray.data.Dataset 外,Ray 還透過 Dask on Ray 提供支援一個更類別似於 pandas 的經驗,這利用了 Dask 介面在 Ray 上執行。
小段落標題1:Dask on Ray 的優勢
Dask on Ray 是一個非常強大的工具,因為它結合了 Dask 和 Ray 的優點。Dask 是一個 Python 函式庫,用於平行和分散式計算。它提供了一個高層次的介面,可以方便地進行資料處理和分析。而 Ray 則提供了一個低層次的介面,可以更靈活地進行分散式計算。
Ray 與 Spark 的比較
有些人會將 Ray 與 Apache Spark 進行比較,因為它們在某些抽象方式上是相似的。從使用者的角度來看,Spark 適合處理資料密集型任務,而 Ray 則更適合處理計算密集型任務。
Ray 擁有較低的任務開銷並支援分散式狀態,使其特別適合機器學習(ML)任務。Ray 的低層次 API 使其成為構建工具的更吸引人平台。
Spark 擁有更多的資料工具,但依賴中央排程和狀態管理。這種中央化使得實作強化學習(RL)和遞迴演算法變得具有挑戰性。對於分析使用案例,特別是在現有的大資料佈署中,Spark 可能是更好的選擇。
Ray 和 Spark 是互補的,可以一起使用。一個常見模式是使用 Spark 進行資料處理,然後使用 Ray 進行 ML。事實上,「RayDP」函式庫提供了一種在 Ray 中使用 Spark DataFrames 的方法。
小段落標題2:RayDP 的應用場景
RayDP 是一個非常強大的工具,因為它結合了 Spark 和 Ray 的優點。Spark 是一個非常強大的資料處理工具,而 Ray 則是一個非常強大的分散式計算工具。結合這兩者可以使你更靈活地進行資料處理和分散式計算。
機器學習
Ray 提供了多種機器學習(ML)函式庫,通常是將部分 ML 工作委派給現有工具如 PyTorch、scikit-learn 和 TensorFlow,同時利用 Ray 的分散式計算能力來擴充套件它們。例如:
- Ray Tune:實作超引數調整。
- Ray Train:實作 PyTorch 或 TensorFlow 的分散式訓練。
- RLlib:提供強化學習(RL)核心演算法。
小段落標題3:如何在 Ray 中實作自定義演算法
由於 Ray 擁有活動者模型來追蹤狀態和跨工作人員通訊等功能,你可以使用此模型來實作不屬於 Ray Core 的自定義演算法。然而其需求會複雜許多且相對高門檻;以下提供瞭解決問題邏輯與概念:
import ray
from ray import serve
ray.init()
@serve.deployment
class MyModel:
def __init__(self):
self.model = ...
def __call__(self, request):
return self.model.predict(request)
# Deploy the model.
MyModel.deploy()
# Make a request to the deployed model.
response = ray.get(MyModel.remote("input"))
print(response)
內容解密:
此範例展示瞭如何在 Ray 中佈署和呼叫自定義機器學習模型。
- 首先初始化
ray。 - 接著定義一個
MyModel裝飾器類別並加上serve.deployment裝飾器。 - 在初始化函式中載入機器學習模型。
- 在
__call__函式中預測輸入。 - 佈署模型並進行遠端呼叫以獲得預測結果。
工作流程排程
工作流程排程看似簡單,「工作流程只是完成所需工作的一張圖」。然而所有程式都可以表述為完成所需工作的一張圖。新推出的「Workflows」函式庫在版本2.0中允許簡單表達傳統商業邏輯工作流程或大規模(如 ML 模型訓練)工作流程。
Ray 在工作流程排程上獨特之處在於它允許任務排程其他任務而不需要呼叫回中央節點。這使得靈活性和吞吐量提升。
如果你覺得 Ray 的工作流程引擎過於底層化時可考慮使用 Apache Airflow,「Apache Airflow Provider for Ray」允許你使用 Ray 叢集作為 Airflow 工作者池。
流式處理
流式處理是指處理「即時」或「隨到隨取」資料;當你越接近即時資料時會增加額外層級複雜度;因為資料不會總是按順序到達或準時到達。Ray 提供了標準流式原語並支援 Kafka 作為流式資料來源和接收器;並利用其活動者模型 API 與流式資料互動。
然而與其他批次系統上的流派相比會有一些有趣之處;例如:Ray 流派有一部分邏輯以 Java 編寫而非其他元件;因此除錯與其他元件會稍微困難。
互動式應用
並非所有即時應用都是流派應用;例如:互動探索資料集或與使用者輸入互動(如服務模型)都被認為是互動應用而非批次處理但它被與流派元件區隔開來以 Serve 元件處理.
小段落標題4:Serve 元件如何提升應用效能?
Serve 元件主要專注於提升即時應用效能;透過以下方法:
from ray import serve
import numpy as np
import requests
serve.start()
@serve.deployment(name="hello")
class MyModel:
def __init__(self):
self.model = ...
async def __call__(self, request):
data = await request.json()
return self.model.predict(np.array(data))
# Deploy the model.
MyModel.deploy()
# Make a request to the deployed model.
response = requests.post("http://localhost:8000/hello", json={"data": [1, 2, 3]})
print(response.json())
內容解密:
此範例說明如何透過 serve 元件將模型佈署至伺服器以接受外部請求:
- 首先啟動
serve元件。 - 接著定義一個
MyModel裝飾器類別並加上@serve.deployment裝飾器。 - 在初始化函式中載入機器學習模型。
- 在
__call__函式中接受外部請求並預測輸入。 - 佈署模型並透過 HTTP 請求予以呼叫以獲得預測結果。
What Ray Is Not
儘管 Ray 是一個通用分散系統但仍有某些限制:
- 不適合作為結構化查詢語言 (SQL) 或分析引擎;
- 不適合作為資料儲存系統;
- 不適用於核電廠等高要求環境;
- 語言不完全獨立;
總結來說 Raymond 雖然在某些方面具有獨特優勢但仍有許多限制與挑戰等待克服;若能深入瞭解其內部運作機制及特性則能夠充分發揮其潛力達到更佳效果!