• 關於 Milvus
  • 開始使用
  • 概念
  • 使用者指南
  • 資料匯入
  • AI 工具
  • 管理指南
  • 工具
  • 整合功能
  • 教學指南
  • 常見問題
  • API Reference

管理資源群組

在 Milvus 中,您可以透過資源群組將某些查詢節點與其他節點進行物理隔離。本指南將引導您了解如何建立和管理自訂資源群組,以及如何在不同資源群組之間移轉節點。

何謂資源群組

一個資源群組可以包含 Milvus 叢集中的部分或所有查詢節點。 您可以根據自身需求,決定如何將查詢節點分配至各資源群組。例如,在多集合的場景中,您可以將適當數量的查詢節點分配給每個資源群組,並將集合載入至不同的資源群組,使每個集合內的操作在物理上獨立於其他集合的操作。

請注意,Milvus 實例在啟動時會維護一個預設資源群組來容納所有查詢節點,並將其命名為__default_resource_group

自 2.4.1 版本起,Milvus 提供宣告式資源群組 API,而舊版資源群組 API 已宣告為過時。新的宣告式 API 讓使用者能夠實現冪等性,並更輕鬆地在雲原生環境中進行次要開發。

資源群組的概念

資源群組由資源群組配置來定義:

{
    "requests": { "nodeNum": 1 },
    "limits": { "nodeNum": 1 },
    "transfer_from": [{ "resource_group": "rg1" }],
    "transfer_to": [{ "resource_group": "rg2" }]
}
  • requests屬性指定資源群組必須滿足的條件。
  • limits屬性指定資源群組的最大限制。
  • transfer_fromtransfer_to屬性分別描述該資源群組應優先從哪些資源群組獲取資源,以及應將資源轉移至哪些資源群組。

一旦資源群組的配置發生變更,Milvus 將根據新配置盡可能調整當前的查詢節點資源,以確保所有資源群組最終皆符合以下條件:

.requests.nodeNum < nodeNumOfResourceGroup < .limits.nodeNum.

但以下情況除外:

  • 當 Milvus 叢集中的 QueryNodes 數量不足時,即NumOfQueryNode < sum(.requests.nodeNum) ,總會存在某些資源群組的 QueryNodes 數量不足。
  • 當 Milvus 叢集中的查詢節點數量過多時,即NumOfQueryNode > sum(.limits.nodeNum) ,多餘的查詢節點將始終優先分配至__default_resource_group

當然,若叢集中的 QueryNodes 數量發生變化,Milvus 會持續嘗試進行調整以符合最終條件。因此,您可以先套用資源群組的配置變更,然後再執行 QueryNode 的擴展。

使用宣告式 API 管理資源群組

本頁所有程式碼範例均基於 PyMilvus 3.0.1。執行前請先升級您的 PyMilvus 安裝版本。

  1. 建立資源群組。

    要建立資源群組,請在連線至 Milvus 實例後執行以下指令。以下程式碼片段假設default 是您的 Milvus 連線別名。

    import pymilvus
    
    # A resource group name should be a string of 1 to 255 characters, starting with a letter or an underscore (_) and containing only numbers, letters, and underscores (_).
    name = "rg"
    node_num = 0
    
    # create a resource group that exactly hold no query node.
    try:
        milvus_client.create_resource_group(name, config=ResourceGroupConfig(
            requests={"node_num": node_num},
            limits={"node_num": node_num},
        ))
        print(f"Succeeded in creating resource group {name}.")
    except Exception:
        print("Failed to create the resource group.")
    
  2. 列出資源群組。

    建立資源群組後,您即可在資源群組清單中看到該群組。

    若要檢視 Milvus 實例中的資源群組清單,請依下列步驟操作:

    rgs = milvus_client.list_resource_groups()
    print(f"Resource group list: {rgs}")
    
    # Resource group list: ['__default_resource_group', 'rg']
    
  3. 描述資源群組。

    您可以透過以下方式讓 Milvus 描述特定資源群組:

    info = milvus_client.describe_resource_group(name)
    print(f"Resource group description: {info}")
    
    # Resource group description: 
    # ResourceGroupInfo:
    #   <name:rg1>,     // resource group name
    #   <capacity:0>,   // resource group capacity
    #   <num_available_node:1>,  // resource group node num
    #   <num_loaded_replica:{}>, // collection loaded replica num in resource group
    #   <num_outgoing_node:{}>, // node num which still in use by replica in other resource group
    #   <num_incoming_node:{}>, // node num which is in use by replica but belong to other resource group 
    #   <config:{}>,            // resource group config
    #   <nodes:[]>              // node detail info
    
  4. 在資源群組之間移動節點。

    您可能會注意到,該資源群組目前尚未包含任何查詢節點。請依照以下步驟,將部分節點從預設資源群組移至您所建立的資源群組: 假設叢集的__default_resource_group中目前有 1 個 QueryNode,且我們希望將其中一個節點移至已建立的資源群組中update_resource_groups 可確保多項配置變更的原子性,因此 Milvus 不會看到任何中間狀態。

    source = '__default_resource_group'
    target = 'rg'
    expected_num_nodes_in_default = 0
    expected_num_nodes_in_rg = 1
    
    try:
        milvus_client.update_resource_groups({
            source: ResourceGroupConfig(
                requests={"node_num": expected_num_nodes_in_default},
                limits={"node_num": expected_num_nodes_in_default},
            ),
            target: ResourceGroupConfig(
                requests={"node_num": expected_num_nodes_in_rg},
                limits={"node_num": expected_num_nodes_in_rg},
            )
        })
        print(f"Succeeded in move 1 node(s) from {source} to {target}.")
    except Exception:
        print("Something went wrong while moving nodes.")
    
    # After a while, succeeded in moving 1 node(s) from __default_resource_group to rg.
    
  5. 將集合與分區載入至資源群組。

    一旦資源群組中存在查詢節點,即可將集合載入至該資源群組。以下程式碼片段假設已存在一個名為demo 的集合。

    from pymilvus import Collection
    
    collection_name = "demo"
    
    # Milvus loads the collection to the default resource group.
    milvus_client.load_collection(collection_name, replica_number=2)
    
    # Or, you can ask Milvus load the collection to the desired resource group.
    # make sure that query nodes num should be greater or equal to replica_number
    resource_groups = ['rg']
    milvus_client.load_collection(replica_number=2, _resource_groups=resource_groups) 
    

    此外,您也可以僅將一個分區載入至資源群組,並讓其副本分散於多個資源群組中。以下範例假設已存在名為Books 的集合,且該集合包含一個名為Novels 的分區。

    collection = "Books"
    partition = "Novels"
    
    # Use the load method of a collection to load one of its partition
    milvus_client.load_partitions(collection, [partition], replica_number=2, _resource_groups=resource_groups)
    

    請注意,_resource_groups 為可選參數;若未指定此參數,Milvus 會將副本載入至預設資源群組中的查詢節點上。

    若要讓 Milvus 將集合的每個副本載入至不同的資源群組中,請確保資源群組的數量等於副本的數量。

  6. 在資源群組之間傳輸副本。

    Milvus 透過副本在分佈於多個查詢節點的區段之間實現負載平衡。您可以依照以下步驟,將集合的特定副本從一個資源群組移至另一個資源群組:

    source = '__default_resource_group'
    target = 'rg'
    collection_name = 'c'
    num_replicas = 1
    
    try:
        milvus_client.transfer_replica(source, target, collection_name, num_replicas)
        print(f"Succeeded in moving {num_replicas} replica(s) of {collection_name} from {source} to {target}.")
    except Exception:
        print("Something went wrong while moving replicas.")
    
    # Succeeded in moving 1 replica(s) of c from __default_resource_group to rg.
    
  7. 刪除資源群組。

    您可以隨時刪除未包含任何查詢節點的資源群組(limits.node_num = 0 )。在本指南中,資源群組rg 目前包含一個查詢節點。您需要先將該資源群組的配置limits.node_num 修改為零。

    resource_group = "rg
    try:
        milvus_client.update_resource_groups({
            resource_group: ResourceGroupConfig(
                requests={"node_num": 0},
                limits={"node_num": 0},
            ),
        })
        milvus_client.drop_resource_group(resource_group)
        print(f"Succeeded in dropping {resource_group}.")
    except Exception:
        print(f"Something went wrong while dropping {resource_group}.")
    

更多詳細資訊,請參閱pymilvus 中的相關範例

管理叢集擴展的良好實務

目前,Milvus 無法在雲原生環境中獨立進行擴展與縮減。然而,透過結合使用宣告式資源群組 API與容器調度,Milvus 能夠輕鬆實現 QueryNodes 的資源隔離與管理。 以下是在雲端環境中管理 QueryNodes 的最佳實務:

  1. 預設情況下,Milvus 會建立一個__default_resource_group。此資源群組無法刪除,同時也作為所有集合的預設載入資源群組,且冗餘的 QueryNodes 總是會被指派至該群組。 因此,我們可以建立一個「待處理」資源群組來存放閒置的 QueryNode 資源,防止這些資源被__default_resource_group 佔用。

    此外,若嚴格執行sum(.requests.nodeNum) <= queryNodeNum 此限制條件,即可精確控制叢集內 QueryNodes 的分配。假設叢集中目前僅有一台 QueryNode,並初始化該叢集。 以下為設定範例:

    from pymilvus.client.types import ResourceGroupConfig
    
    _PENDING_NODES_RESOURCE_GROUP="__pending_nodes"
    
    def init_cluster(node_num: int):
        print(f"Init cluster with {node_num} nodes, all nodes will be put in default resource group")
        # create a pending resource group, which can used to hold the pending nodes that do not hold any data.
        milvus_client.create_resource_group(name=_PENDING_NODES_RESOURCE_GROUP, config=ResourceGroupConfig(
            requests={"node_num": 0}, # this resource group can hold 0 nodes, no data will be load on it.
            limits={"node_num": 10000}, # this resource group can hold at most 10000 nodes 
        ))
    
        # update default resource group, which can used to hold the nodes that all initial node in it.
        milvus_client.update_resource_groups({
            "__default_resource_group": ResourceGroupConfig(
                requests={"node_num": node_num},
                limits={"node_num": node_num},
                transfer_from=[{"resource_group": _PENDING_NODES_RESOURCE_GROUP}], # recover missing node from pending resource group at high priority.
                transfer_to=[{"resource_group": _PENDING_NODES_RESOURCE_GROUP}], # recover redundant node to pending resource group at low priority.
            )})
        milvus_client.create_resource_group(name="rg1", config=ResourceGroupConfig(
            requests={"node_num": 0},
            limits={"node_num": 0},
            transfer_from=[{"resource_group": _PENDING_NODES_RESOURCE_GROUP}], 
            transfer_to=[{"resource_group": _PENDING_NODES_RESOURCE_GROUP}],
        ))
        milvus_client.create_resource_group(name="rg2", config=ResourceGroupConfig(
            requests={"node_num": 0},
            limits={"node_num": 0},
            transfer_from=[{"resource_group": _PENDING_NODES_RESOURCE_GROUP}], 
            transfer_to=[{"resource_group": _PENDING_NODES_RESOURCE_GROUP}],
        ))
    
    init_cluster(1)
    

    利用上述範例程式碼,我們建立了一個名為__pending_nodes 的資源群組,用以存放額外的 QueryNode。我們也建立兩個名為rg1rg2 的使用者專用資源群組。此外,我們確保其他資源群組會優先從__pending_nodes 中恢復缺失或冗餘的 QueryNode。

  2. 叢集水平擴展

    假設我們有以下擴展函式:

    
    def scale_to(node_num: int):
        # scale the querynode number in Milvus into node_num.
        pass
    

    我們可以透過 API 將特定資源群組擴展至指定數量的 QueryNodes,且不會影響其他資源群組。

    # scale rg1 into 3 nodes, rg2 into 1 nodes
    milvus_client.update_resource_groups({
        "rg1": ResourceGroupConfig(
            requests={"node_num": 3},
            limits={"node_num": 3},
            transfer_from=[{"resource_group": _PENDING_NODES_RESOURCE_GROUP}],
            transfer_to=[{"resource_group": _PENDING_NODES_RESOURCE_GROUP}],
        ),
        "rg2": ResourceGroupConfig(
            requests={"node_num": 1},
            limits={"node_num": 1},
            transfer_from=[{"resource_group": _PENDING_NODES_RESOURCE_GROUP}],
            transfer_to=[{"resource_group": _PENDING_NODES_RESOURCE_GROUP}],
        ),
    })
    scale_to(5)
    # rg1 has 3 nodes, rg2 has 1 node, __default_resource_group has 1 node.
    
  3. 叢集縮減

    同樣地,我們可以建立縮減規則,優先從__pending_nodes資源群組中選取查詢節點。此資訊可透過describe_resource_group API 取得,藉此達成縮減指定資源群組的目標。

    # scale rg1 from 3 nodes into 2 nodes
    milvus_client.update_resource_groups({
        "rg1": ResourceGroupConfig(
            requests={"node_num": 2},
            limits={"node_num": 2},
            transfer_from=[{"resource_group": _PENDING_NODES_RESOURCE_GROUP}],
            transfer_to=[{"resource_group": _PENDING_NODES_RESOURCE_GROUP}],
        ),
    })
    
    # rg1 has 2 nodes, rg2 has 1 node, __default_resource_group has 1 node, __pending_nodes has 1 node.
    scale_to(4)
    # scale the node in __pending_nodes
    

資源群組與多個複本的互動方式

  • 單一集合的副本與資源群組之間具有 N 對 N 的關係。
  • 當單一集合的多個副本被載入到同一個資源群組時,該資源群組的 QueryNodes 會均勻分佈於各副本之間,確保每個副本擁有的 QueryNodes 數量差異不超過 1。

下一步

若要部署多租戶 Milvus 實例,請參閱以下內容:

翻譯者DeepL

免費嘗試托管的 Milvus

Zilliz Cloud 無縫接入,由 Milvus 提供動力,速度提升 10 倍。

開始使用
反饋

這個頁面有幫助嗎?