在近期更新的 Milvus 2.x 版本中,我們上線了在社群中呼聲一直很高的【資源組功能】。有了這個功能,使用者再也不需要“為每個 collection 部署一套 Milvus 服務”的方案,輕鬆實現對 Query Node 資源進行分組管理,達到物理資源隔離的效果。
本文將從需求、方案以及實操層面出發,帶你詳細解讀資源組功能。
01.源自使用者需求
上線資源組功能的契機來自和使用者的一次溝通。
某次,在社群交流活動中,Milvus 的社群使用者提出了這樣一個問題: 基於 Milvus 部署了多個應用場景,根據資料來源和應用場景將資料劃分成了多個 Collection。不過,由於向量搜尋具備著高度的 CPU 密集型特徵,所以在業務的高峰時間段,多個 Collection 的同時查詢會爭搶 CPU 資源,彼此影響。
為了滿足場景需要,使用者選擇了為每個 Collection 部署一套 Milvus 服務,從資料庫的層面來避免查詢過程中 Collection 之間的影響。這也是在沒有資源組功能時一個比較標準的方案。儘管這套方案完美解決了使用者的問題,卻也帶來了 Milvus 服務運維的開——使用者需要同時運維多個 Milvus 叢集。因此,在溝通中,使用者提出了在一個 Milvus 服務中去實現這個場景的需求。
02.資源隔離方案
Milvus 在提供查詢前,需要對 Collection 執行 load 操作,以加速後續查詢的速度,實現更好的查詢效能。結合 Milvus 使用者的使用習慣,我們設計了一套 Milvus 的資源組方案。
Milvus 服務中維護了名為一個 __default_resource_group 的資源組,在 Milvus 啟動後,預設所有的 QueryNode 都會加入到這個資源組進行管理,後續的 load 操作也會將 Collection 在這個資源組中進行載入。對於不需要感知物理資源的使用者,所有的操作、系統表現沒有發生任何變化。
如果使用者有物理資源隔離的需求,那麼可以建立多個自定義資源組,然後將預設資源組中的節點分配轉移到自定義的資源組中,實現對 Milvus 叢集中 QueryNode 資源的劃分和物理隔離。隨後在 load 操作中,可以去指定每一個 Collection 要載入到哪個資源組中。在載入 Collection 的同時,可實現資源的使用限制。
03.實現 Collection 資源隔離
在介紹完 Milvus 資源隔離的背景和方案後,我們可以透過一個例子來講述實現 Collection 級別資源隔離的完整步驟。
下面的所有操作是基於使用者部署了一個 6 個 QueryNode 的 Milvus 服務,所以會有 6 個 QueryNode 參與資源隔離過程中的劃分和分配。
- 建立兩個自定義資源組和
rg1
和rg2
,用於承載 QueryNode 資源。
import pymilvus
utility.create_resource_group("rg1", using='default')
utility.create_resource_group("rg2", using='default')
rgs = utility.list_resource_groups(using='default')
print(f"Resource group list: {rgs}")
# Resource group list: ['__default_resource_group', 'rg1', 'rg2']
- 分別從 __default_resource_group 中向
rg1
和rg2
轉移 3 個節點,實現所有 QueryNode 資源的隔離劃分。
utility.transfer_node("__default_resource_group", "rg1", 3, using="default")
utility.transfer_node("__default_resource_group", "rg2", 3, using="default")
- 假定使用者有兩個需要載入的 Collection, 分別為
Collection A
和Collection B
, 這裡透過將Collection A
載入到rg1
, 將Collection B
載入到rg2
, 以此實現Collection A
和Collection B
的資源隔離。
# ask Milvus load the collection to the desired resource group.
# make sure that query nodes num should be greater or equal to replica_number
collection = Collection('collectionA')
collection.load(replica_number=3, _resource_group=['rg1'])
collection = Collection('collectionB')
collection.load(replica_number=3, _resource_group=['rg2'])
透過上述 3 個步驟,我們實現了 Collection 級別的資源隔離,每個 Collection 使用了 3 個獨立的 QueryNode, 後續發生在 Collection 上的查詢將會使用各自獨立的 QueryNode, 彼此之間物理隔離,互不影響。
Milvus 透過資源組提供對 QueryNode 資源劃分的能力,使用者可以根據自身的需求靈活安排 Collection 的載入方案,實現各種級別的資源隔離,應對不同的場景和需求。更多關於 Milvus 資源組功能的使用細節,可以點選連結參考 Milvus Doc。
(本文作者劉偉系 Zilliz 高階研發工程師 )
本文由mdnice多平臺釋出