milvus-logo
LFAI
首页
  • 用户指南

管理分区

本指南将指导您如何在集合中创建和管理分区。

分区概述

Milvus 中的分区表示对集合的细分。该功能允许将集合的物理存储划分为多个部分,通过将焦点缩小到较小的数据子集而不是整个集合,从而提高查询性能。

创建数据集时,至少会自动创建一个名为_default的默认分区。在一个数据集中最多可以创建 1,024 个分区。

注释

Milvus 引入了一项名为 "Partition Key"(Partition Key)的功能,可利用底层分区根据特定字段的散列值来存储实体。该功能有助于实现多租户,提高搜索性能。有关详细信息,请阅读使用Partition Key

如果在集合中开启了Partition Key功能,Milvus 就会负责管理所有分区,从而减轻你的责任。

准备工作

下面的代码片段是对现有代码的重新利用,以建立与 Milvus 的连接,并在快速设置模式下创建数据集,表明数据集在创建时已加载。

对于准备工作,使用 MilvusClient连接到 Milvus,并使用 create_collection()在快速设置模式下创建程序集。

对于准备工作,使用 MilvusClientV2连接到 Milvus,并使用 createCollection()以快速设置模式创建采集。

对于准备工作,使用 MilvusClient连接到 Milvus createCollection()以快速设置模式创建集合。

from pymilvus import MilvusClient, DataType

# 1. Set up a Milvus client
client = MilvusClient(
uri="http://localhost:19530"
)

# 2. Create a collection
client.create_collection(
collection_name="quick_setup",
dimension=5,
)

import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.collection.request.CreateCollectionReq;

String CLUSTER_ENDPOINT = "http://localhost:19530";

// 1. Connect to Milvus server
ConnectConfig connectConfig = ConnectConfig.builder()
    .uri(CLUSTER_ENDPOINT)
    .build();

MilvusClientV2 client = new MilvusClientV2(connectConfig);

// 2. Create a collection in quick setup mode
CreateCollectionReq quickSetupReq = CreateCollectionReq.builder()
    .collectionName("quick_setup")
    .dimension(5)
    .build();

client.createCollection(quickSetupReq);
const address = "http://localhost:19530"

// 1. Set up a Milvus Client
client = new MilvusClient({address});

// 2. Create a collection in quick setup mode
await client.createCollection({
    collection_name: "quick_setup",
    dimension: 5,
});  

注释

在上述代码片段中,集合的索引已与集合一起创建,表明集合在创建时已加载。

列出分区

一旦集合准备就绪,就可以列出其分区。

要列出分区,请使用 list_partitions().

要列出分区,请使用 listPartitions().

要列出分区,请使用 listPartitions().

# 3. List partitions
res = client.list_partitions(collection_name="quick_setup")
print(res)

# Output
#
# ["_default"]
import io.milvus.v2.service.partition.request.ListPartitionsReq;

// 3. List all partitions in the collection
ListPartitionsReq listPartitionsReq = ListPartitionsReq.builder()
    .collectionName("quick_setup")
    .build();

List<String> partitionNames = client.listPartitions(listPartitionsReq);

System.out.println(partitionNames);

// Output:
// ["_default"]
// 3. List partitions
res = await client.listPartitions({
    collection_name: "quick_setup"
})

console.log(res.partition_names)

// Output
// 
// [ '_default' ]
// 

上述代码片段的输出包括指定集合中分区的名称。

注释

如果在集合中将某个字段设为分区键,Milvus 会在创建集合的同时创建至少64 个分区。在列出分区时,结果可能与上述代码片段的输出不同。

详情请参阅使用分区键

创建分区

您可以向集合添加更多分区。一个数据集最多可有 1,024 个分区。

要创建分区,请使用 create_partition().

要创建分区,请使用 createPartition().

要创建分区,请使用 createPartition().

# 4. Create more partitions
client.create_partition(
    collection_name="quick_setup",
    partition_name="partitionA"
)

client.create_partition(
collection_name="quick_setup",
partition_name="partitionB"
)

res = client.list_partitions(collection_name="quick_setup")
print(res)

# Output
#
# ["_default", "partitionA", "partitionB"]
import io.milvus.v2.service.partition.request.CreatePartitionReq;

// 4. Create more partitions
CreatePartitionReq createPartitionReq = CreatePartitionReq.builder()
    .collectionName("quick_setup")
    .partitionName("partitionA")
    .build();

client.createPartition(createPartitionReq);

createPartitionReq = CreatePartitionReq.builder()
    .collectionName("quick_setup")
    .partitionName("partitionB")
    .build();

client.createPartition(createPartitionReq);

listPartitionsReq = ListPartitionsReq.builder()
    .collectionName("quick_setup")
    .build();

partitionNames = client.listPartitions(listPartitionsReq);

System.out.println(partitionNames);

// Output:
// [
//     "_default",
//     "partitionA",
//     "partitionB"
// ]
// 4. Create more partitions
await client.createPartition({
    collection_name: "quick_setup",
    partition_name: "partitionA"
})

await client.createPartition({
    collection_name: "quick_setup",
    partition_name: "partitionB"
})

res = await client.listPartitions({
    collection_name: "quick_setup"
})

console.log(res.partition_names)

// Output
// 
// [ '_default', 'partitionA', 'partitionB' ]
// 

上面的代码片段在一个集合中创建了一个分区,并列出了该集合的分区。

注释

如果将某个字段设置为集合中的分区键,Milvus 将负责管理集合中的分区。因此,在尝试创建分区时可能会遇到提示错误。

有关详细信息,请参阅使用Partition Key

检查特定分区

您还可以检查特定分区是否存在。

要检查特定分区,请使用 has_partition().

要检查特定分区,请使用 hasPartition().

要检查特定分区,请使用 hasPartition().

# 5. Check whether a partition exists
res = client.has_partition(
    collection_name="quick_setup",
    partition_name="partitionA"
)
print(res)

# Output
#
# True

res = client.has_partition(
collection_name="quick_setup",
partition_name="partitionC"
)
print(res)

# Output
#
# False
import io.milvus.v2.service.partition.request.HasPartitionReq;

// 5. Check whether a partition exists
HasPartitionReq hasPartitionReq = HasPartitionReq.builder()
    .collectionName("quick_setup")
    .partitionName("partitionA")
    .build();

boolean exists = client.hasPartition(hasPartitionReq);

System.out.println(exists);

// Output:
// true

hasPartitionReq = HasPartitionReq.builder()
    .collectionName("quick_setup")
    .partitionName("partitionC")
    .build();

exists = client.hasPartition(hasPartitionReq);

System.out.println(exists);

// Output:
// false
// 5. Check whether a partition exists
res = await client.hasPartition({
    collection_name: "quick_setup",
    partition_name: "partitionA"
})

console.log(res.value)

// Output
// 
// true
// 

res = await client.hasPartition({
    collection_name: "quick_setup",
    partition_name: "partitionC"
})

console.log(res.value)

// Output
// 
// false
// 

上面的代码片段检查集合是否有名为partitionApartitionC 的分区。

加载和释放分区

您可以加载和释放特定分区,使其对搜索和查询可用或不可用。

获取加载状态

要检查集合及其分区的加载状态,请使用 get_load_state().

要检查某个集合及其分区的加载状态,请使用 getLoadState().

要检查数据集及其分区的负载状态,请使用 getLoadState().

# Release the collection
client.release_collection(collection_name="quick_setup")

# Check the load status
res = client.get_load_state(collection_name="quick_setup")
print(res)

# Output
#
# {
# "state": "<LoadState: Loaded>"
# }

res = client.get_load_state(
collection_name="quick_setup",
partition_name="partitionA"
)

print(res)

# Output
#
# {
# "state": "<LoadState: Loaded>"
# }

res = client.get_load_state(
collection_name="quick_setup",
partition_name="partitionB"
)

print(res)

# Output
#
# {
# "state": "<LoadState: NotLoad>"
# }

import io.milvus.v2.service.collection.request.GetLoadStateReq;
import io.milvus.v2.service.collection.request.ReleaseCollectionReq;
import io.milvus.v2.service.partition.request.LoadPartitionsReq;
import io.milvus.v2.service.partition.request.ReleasePartitionsReq;

// 6. Load a partition independantly
// 6.1 Release the collection
ReleaseCollectionReq releaseCollectionReq = ReleaseCollectionReq.builder()
    .collectionName("quick_setup")
    .build();

client.releaseCollection(releaseCollectionReq);

// 6.2 Load partitionA
LoadPartitionsReq loadPartitionsReq = LoadPartitionsReq.builder()
    .collectionName("quick_setup")
    .partitionNames(List.of("partitionA"))
    .build();

client.loadPartitions(loadPartitionsReq);

Thread.sleep(3000);

// 6.3 Check the load status of the collection and its partitions
GetLoadStateReq getLoadStateReq = GetLoadStateReq.builder()
    .collectionName("quick_setup")
    .build();

boolean state = client.getLoadState(getLoadStateReq);

System.out.println(state);

// Output:
// true

getLoadStateReq = GetLoadStateReq.builder()
    .collectionName("quick_setup")
    .partitionName("partitionA")
    .build();

state = client.getLoadState(getLoadStateReq);

System.out.println(state);

// Output:
// true

getLoadStateReq = GetLoadStateReq.builder()
    .collectionName("quick_setup")
    .partitionName("partitionB")
    .build();

state = client.getLoadState(getLoadStateReq);

System.out.println(state);

// Output:
// false
// 6. Load a partition indenpendantly
await client.releaseCollection({
    collection_name: "quick_setup"
})

res = await client.getLoadState({
    collection_name: "quick_setup"
})

console.log(res.state)

// Output
// 
// LoadStateNotLoad
// 

await client.loadPartitions({
    collection_name: "quick_setup",
    partition_names: ["partitionA"]
})

await sleep(3000)

res = await client.getLoadState({
    collection_name: "quick_setup"
})

console.log(res.state)

// Output
// 
// LoadStateLoaded
// 

res = await client.getLoadState({
    collection_name: "quick_setup",
    partition_name: "partitionA"
})

console.log(res.state)

// Output
// 
// LoadStateLoaded
// 

res = await client.getLoadState({
    collection_name: "quick_setup",
    partition_name: "partitionB"
})

console.log(res.state)

// Output
// 
// LoadStateLoaded
// 

可能的加载状态如下

  • 已加载

    如果一个集合的至少一个分区已加载,则该集合被标记为Loaded

  • 未加载

    如果一个集合的任何分区都未加载,则该集合被标记为NotLoad

  • 加载中

    如果集合中至少有一个分区处于加载过程中,则该集合被标记为正在加载。

加载分区

要加载集合的所有分区,只需调用 load_collection().要加载集合的特定分区,可使用 load_partitions().

要加载集合的所有分区,只需调用 loadCollection().要加载集合的特定分区,可使用 loadPartitions().

要加载集合的所有分区,只需调用 loadCollection().要加载集合的特定分区,可使用 loadPartitions().

client.load_partitions(
    collection_name="quick_setup",
    partition_names=["partitionA"]
)

res = client.get_load_state(collection_name="quick_setup")
print(res)

# Output
#
# {
# "state": "<LoadState: Loaded>"
# }
LoadPartitionsReq loadPartitionsReq = LoadPartitionsReq.builder()
    .collectionName("quick_setup")
    .partitionNames(List.of("partitionA"))
    .build();

client.loadPartitions(loadPartitionsReq);

getLoadStateReq = GetLoadStateReq.builder()
    .collectionName("quick_setup")
    .partitionName("partitionA")
    .build();

state = client.getLoadState(getLoadStateReq);

System.out.println(state);

// Output:
// true
await client.loadPartitions({
    collection_name: "quick_setup",
    partition_names: ["partitionA"]
})

res = await client.getLoadState({
    collection_name: "quick_setup",
    partition_name: "partitionA"
})

console.log(res.state)

// Output
// 
// LoadStateLoaded
//

要一次加载多个分区,请按以下步骤操作:

client.load_partitions(
    collection_name="quick_setup",
    partition_names=["partitionA", "partitionB"]
)

res = client.get_load_status(
collection_name="quick_setup",
partition_name="partitionA"
)

# Output
#
# {
# "state": "<LoadState: Loaded>"
# }

res = client.get_load_status(
collection_name="quick_setup",
partition_name="partitionB"
)

# Output
#
# {
# "state": "<LoadState: Loaded>"
# }
LoadPartitionsReq loadPartitionsReq = LoadPartitionsReq.builder()
    .collectionName("quick_setup")
    .partitionNames(List.of("partitionA", "partitionB"))
    .build();

client.loadPartitions(loadPartitionsReq);

getLoadStateReq = GetLoadStateReq.builder()
    .collectionName("quick_setup")
    .partitionName("partitionA")
    .build();

state = client.getLoadState(getLoadStateReq);

System.out.println(state);

// Output:
// true

getLoadStateReq = GetLoadStateReq.builder()
    .collectionName("quick_setup")
    .partitionName("partitionB")
    .build();

state = client.getLoadState(getLoadStateReq);

System.out.println(state);

// Output:
// true
await client.loadPartitions({
    collection_name: "quick_setup",
    partition_names: ["partitionA", "partitionB"]
})

res = await client.getLoadState({
    collection_name: "quick_setup",
    partition_name: "partitionA"
})

console.log(res)

// Output
// 
// LoadStateLoaded
// 

res = await client.getLoadState({
    collection_name: "quick_setup",
    partition_name: "partitionB"
})

console.log(res)

// Output
// 
// LoadStateLoaded
// 

释放分区

要释放集合的所有分区,只需调用 release_collection().要释放集合的特定分区,可使用 release_partitions().

要释放集合的所有分区,只需调用 releaseCollection().要释放集合的特定分区,可使用 releasePartitions().

要释放集合的所有分区,只需调用 releaseCollection().要释放集合的特定分区,可使用 releasePartitions().

# 7. Release a partition
client.release_partitions(
    collection_name="quick_setup",
    partition_names=["partitionA"]
)

res = client.get_load_state(
collection_name="quick_setup",
partition_name="partitionA"
)

print(res)

# Output
#
# {
# "state": "<LoadState: NotLoad>"
# }

import io.milvus.v2.service.partition.request.ReleasePartitionsReq;

// 7. Release a partition
ReleasePartitionsReq releasePartitionsReq = ReleasePartitionsReq.builder()
    .collectionName("quick_setup")
    .partitionNames(List.of("partitionA"))
    .build();

client.releasePartitions(releasePartitionsReq);

getLoadStateReq = GetLoadStateReq.builder()
    .collectionName("quick_setup")
    .partitionName("partitionA")
    .build();

state = client.getLoadState(getLoadStateReq);

System.out.println(state);

// Output:
// false
// 7. Release a partition
await client.releasePartitions({
    collection_name: "quick_setup",
    partition_names: ["partitionA"]
})

res = await client.getLoadState({
    collection_name: "quick_setup"
})

console.log(res.state)

// Output
// 
// LoadStateNotLoad
// 

要同时释放多个分区,请按以下步骤操作:

client.release_partitions(
    collection_name="quick_setup",
    partition_names=["_default", "partitionA", "partitionB"]
)

res = client.get_load_status(
collection_name="quick_setup",
)

# Output
#
# {
# "state": "<LoadState: NotLoad>"
# }

丢弃分区

释放分区后,如果不再需要该分区,可以将其丢弃。

要丢弃分区,请使用 drop_partition().

要放弃一个分区,请使用 dropPartition().

要下拉分区,请使用 dropPartition().

# 8. Drop a partition
client.drop_partition(
    collection_name="quick_setup",
    partition_name="partitionB"
)

res = client.list_partitions(collection_name="quick_setup")
print(res)

# Output
#
# ["_default", "partitionA"]
import io.milvus.v2.service.partition.request.ReleasePartitionsReq;

ReleasePartitionsReq releasePartitionsReq = ReleasePartitionsReq.builder()
    .collectionName("quick_setup")
    .partitionNames(List.of("_default", "partitionA", "partitionB"))
    .build();

client.releasePartitions(releasePartitionsReq);

getLoadStateReq = GetLoadStateReq.builder()
    .collectionName("quick_setup")
    .build();

state = client.getLoadState(getLoadStateReq);

System.out.println(state);

// Output:
// false

await client.releasePartitions({
    collection_name: "quick_setup",
    partition_names: ["_default", "partitionA", "partitionB"]
})

res = await client.getLoadState({
    collection_name: "quick_setup"
})

console.log(res)

// Output
// 
// {
//   status: {
//     error_code: 'Success',
//     reason: '',
//     code: 0,
//     retriable: false,
//     detail: ''
//   },
//   state: 'LoadStateNotLoad'
// }
// 

注意事项

在丢弃分区之前,需要将其从内存中释放。

常见问题

  • 分区中可以存储多少数据?

    建议在一个分区中存储少于 1B 的数据。

  • 最多可以创建多少个分区?

    默认情况下,Milvus 最多允许创建 4,096 个分区。您可以通过配置rootCoord.maxPartitionNum 来调整分区的最大数量。有关详情,请参阅系统配置

  • 如何区分分区和Partition Key?

    分区是物理存储单元,而Partition Key是逻辑概念,可根据指定列自动将数据分配到特定分区。

    例如,在 Milvus 中,如果你有一个定义了分区键为color 字段的集合,系统会根据每个实体的color 字段的散列值自动将数据分配到分区。这一自动化流程免除了用户在插入或搜索数据时手动指定分区的责任。

    另一方面,在手动创建分区时,需要根据分区键的标准为每个分区分配数据。如果你有一个带有color 字段的集合,你需要手动将color 值为red 的实体分配到partition A ,将color 值为blue 的实体分配到partition B 。这种手动管理需要更多的精力。

    总之,分区和分区键都是用来优化数据计算和提高查询效率的。必须认识到,启用Partition Key意味着放弃对分区数据插入和加载的人工管理控制,因为这些过程完全由 Milvus 自动处理。

翻译自DeepLogo

反馈

此页对您是否有帮助?