Gerir partições
Este guia explica-lhe como criar e gerir partições numa coleção.
Descrição geral
Uma partição no Milvus representa uma subdivisão de uma coleção. Esta funcionalidade permite que o armazenamento físico de uma coleção seja dividido em várias partes, contribuindo para melhorar o desempenho da consulta ao reduzir o foco para um subconjunto mais pequeno de dados em vez de toda a coleção.
Aquando da criação de uma coleção, é criada automaticamente pelo menos uma partição predefinida denominada _default. É possível criar um máximo de 1024 partições dentro de uma coleção.
notas
O Milvus introduz uma funcionalidade denominada Partition Key, que utiliza as partições subjacentes para armazenar entidades com base nos valores de hash de um campo específico. Esta funcionalidade facilita a implementação de multi-tenancy, melhorando o desempenho da pesquisa. Para obter detalhes, leia Usar chave de partição.
Se a funcionalidade Chave de partição estiver activada numa coleção, o Milvus encarrega-se de gerir todas as partições, libertando-o dessa responsabilidade.
Preparações
O trecho de código abaixo reaproveita o código existente para estabelecer uma ligação ao Milvus e criar uma coleção em modo de configuração rápida, indicando que a coleção é carregada aquando da criação.
Para as preparações, utilize MilvusClient
para estabelecer uma ligação ao Milvus e create_collection()
para criar uma coleção em modo de configuração rápida.
Para as preparações, utilizar MilvusClientV2
para se ligar ao Milvus e createCollection()
para criar uma coleção em modo de instalação rápida.
Para os preparativos, utilizar MilvusClient
para se ligar ao Milvus e createCollection()
para criar uma coleção em modo de instalação rápida.
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,
});
notas
No excerto de código acima, o índice da coleção foi criado juntamente com a coleção, indicando que a coleção é carregada aquando da criação.
Listar partições
Quando uma coleção estiver pronta, você pode listar suas partições.
Para listar partições, use list_partitions()
.
Para listar partições, use listPartitions()
.
Para listar partições, utilize 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' ]
//
A saída do trecho de código acima inclui os nomes das partições dentro da coleção especificada.
notas
Se tiver definido um campo como chave de partição numa coleção, o Milvus cria pelo menos 64 partições juntamente com a coleção. Ao listar as partições, os resultados podem diferir da saída dos trechos de código acima.
Para obter detalhes, consulte Usar chave de partição.
Criar partições
Pode adicionar mais partições à coleção. Uma coleção pode ter até 1.024 partições.
Para criar partições, use create_partition()
.
Para criar partições, utilize createPartition()
.
Para criar partições, utilize 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' ]
//
O trecho de código acima cria uma partição em uma coleção e lista as partições da coleção.
notas
Se tiver definido um campo como chave de partição numa coleção, o Milvus encarrega-se de gerir as partições na coleção. Por isso, poderá encontrar erros ao tentar criar partições.
Para obter detalhes, consulte Usar chave de partição.
Verificar a existência de uma partição específica
Você também pode verificar a existência de uma partição específica.
Para verificar a existência de uma partição específica, use has_partition()
.
Para verificar a existência de uma partição específica, utilize hasPartition()
.
Para verificar a existência de uma partição específica, utilize 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
//
O trecho de código acima verifica se a coleção tem uma partição chamada partitionA
e partitionC
.
Carregar e liberar partições
Você pode carregar e liberar partições específicas para torná-las disponíveis ou indisponíveis para pesquisas e consultas.
Obter o estado do carregamento
Para verificar o status de carregamento de uma coleção e suas partições, use get_load_state()
.
Para verificar o estado de carga de uma coleção e das suas partições, utilize getLoadState()
.
Para verificar o estado de carga de uma coleção e das suas partições, utilize 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
//
O estado de carregamento possível pode ser um dos seguintes
Carregada
Uma coleção é marcada como
Loaded
se pelo menos uma das suas partições tiver sido carregada.NotLoad
Uma coleção é marcada como
NotLoad
se nenhuma das suas partições tiver sido carregada.Carregando
Uma coleção é marcada como Em carregamento se pelo menos uma das suas partições estiver em processo de carregamento.
Carregar partições
Para carregar todas as partições de uma coleção, basta chamar load_collection()
. Para carregar partições específicas de uma coleção, utilize load_partitions()
.
Para carregar todas as partições de uma coleção, basta chamar loadCollection()
. Para carregar partições específicas de uma coleção, utilize loadPartitions()
.
Para carregar todas as partições de uma coleção, basta chamar loadCollection()
. Para carregar partições específicas de uma coleção, utilize 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
//
Para carregar várias partições de cada vez, faça o seguinte:
client.load_partitions(
collection_name="quick_setup",
partition_names=["partitionA", "partitionB"]
)
res = client.get_load_state(
collection_name="quick_setup",
partition_name="partitionA"
)
# Output
#
# {
# "state": "<LoadState: Loaded>"
# }
res = client.get_load_state(
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
//
Para carregar campos especificados numa ou mais partições, faça o seguinte:
client.load_partitions(
collection_name="quick_setup",
partition_names=["partitionA"],
load_fields=["id", "vector"],
skip_load_dynamic_field=True
)
Observe que apenas os campos listados em load_fields
podem ser usados como condições de filtragem e campos de saída em pesquisas e consultas. Deve incluir sempre a chave primária na lista. Os nomes de campo excluídos do carregamento não estarão disponíveis para filtragem ou saída.
Pode utilizar skip_load_dynamic_field=True
para saltar o carregamento do campo dinâmico. O Milvus trata o campo dinâmico como um único campo, portanto todas as chaves no campo dinâmico serão incluídas ou excluídas juntas.
Liberar partições
Para libertar todas as partições de uma coleção, basta chamar release_collection()
. Para liberar partições específicas de uma coleção, use release_partitions()
.
Para liberar todas as partições de uma coleção, basta chamar releaseCollection()
. Para libertar partições específicas de uma coleção, utilize releasePartitions()
.
Para libertar todas as partições de uma coleção, basta chamar releaseCollection()
. Para libertar partições específicas de uma coleção, utilize 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
//
Para liberar várias partições de uma vez, faça o seguinte:
client.release_partitions(
collection_name="quick_setup",
partition_names=["_default", "partitionA", "partitionB"]
)
res = client.get_load_state(
collection_name="quick_setup",
)
# Output
#
# {
# "state": "<LoadState: NotLoad>"
# }
Soltar partições
Depois de liberar uma partição, você pode soltá-la se ela não for mais necessária.
Para soltar uma partição, use drop_partition()
.
Para soltar uma partição, use dropPartition()
.
Para eliminar uma partição, utilize 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'
// }
//
notas
Antes de eliminar uma partição, é necessário libertá-la da memória.
FAQ
Quantos dados podem ser armazenados em uma partição?
Recomenda-se armazenar menos de 1B de dados em uma partição.
Qual é o número máximo de partições que podem ser criadas?
Por defeito, o Milvus permite a criação de um máximo de 1.024 partições. É possível ajustar o número máximo de partições configurando
rootCoord.maxPartitionNum
. Para obter detalhes, consulte Configurações do sistema.Como posso diferenciar entre partições e chaves de partição?
As partições são unidades de armazenamento físicas, enquanto as chaves de partição são conceitos lógicos que atribuem automaticamente dados a partições específicas com base numa coluna designada.
Por exemplo, no Milvus, se tiver uma coleção com uma chave de partição definida como o campo
color
, o sistema atribui automaticamente os dados às partições com base nos valores de hash do campocolor
para cada entidade. Este processo automatizado liberta o utilizador da responsabilidade de especificar manualmente a partição ao inserir ou pesquisar dados.Por outro lado, ao criar partições manualmente, é necessário atribuir dados a cada partição com base nos critérios da chave da partição. Se tiver uma coleção com um campo
color
, deve atribuir manualmente entidades com um valorcolor
dered
apartition A
e entidades com um valorcolor
deblue
apartition B
. Esta gestão manual exige mais esforço.Em resumo, tanto as partições como as chaves de partição são utilizadas para otimizar o cálculo dos dados e aumentar a eficiência da consulta. É essencial reconhecer que ativar uma chave de partição significa renunciar ao controlo sobre a gestão manual da inserção e carregamento de dados de partição, uma vez que estes processos são totalmente automatizados e geridos pelo Milvus.