Compactação de clusters
A compactação de clusters foi concebida para melhorar o desempenho da pesquisa e reduzir os custos em grandes colecções. Este guia ajudá-lo-á a compreender a compactação de clusters e a forma como esta funcionalidade pode melhorar o desempenho da pesquisa.
Visão geral
Milvus armazena entidades de entrada em segmentos dentro de uma coleção e sela um segmento quando ele está cheio. Se isso acontecer, um novo segmento é criado para acomodar entidades adicionais. Como resultado, as entidades são distribuídas arbitrariamente entre os segmentos. Esta distribuição requer que o Milvus pesquise múltiplos segmentos para encontrar os vizinhos mais próximos de um determinado vetor de consulta.
Sem compactação de agrupamento
Se Milvus pode distribuir entidades entre segmentos com base nos valores de um campo específico, o âmbito da pesquisa pode ser restringido dentro de um segmento, melhorando assim o desempenho da pesquisa.
Clustering Compaction é um recurso do Milvus que redistribui entidades entre segmentos em uma coleção com base nos valores de um campo escalar. Para ativar esse recurso, primeiro é necessário selecionar um campo escalar como a chave de agrupamento. Isso permite que o Milvus redistribua entidades em um segmento quando seus valores de chave de agrupamento estiverem dentro de um intervalo específico. Quando o usuário aciona uma compactação de clustering, Milvus gera/atualiza um índice global chamado PartitionStats, que registra a relação de mapeamento entre segmentos e valores de chave de clustering.
Compactação de clustering
Usando o PartitionStats como referência, o Milvus pode eliminar dados irrelevantes ao receber uma solicitação de pesquisa/consulta que carrega um valor de chave de clustering e restringir o escopo da pesquisa dentro dos segmentos que mapeiam para o valor, melhorando assim o desempenho da pesquisa. Para obter detalhes sobre a melhoria do desempenho, consulte Testes de benchmark.
Usar compactação de clustering
O recurso de Compactação de Clustering no Milvus é altamente configurável. Você pode optar por acioná-lo manualmente ou configurá-lo para ser acionado automaticamente em intervalos pelo Milvus. Para ativar a compactação de cluster, faça o seguinte:
Configuração global
É necessário modificar o ficheiro de configuração do Milvus, conforme indicado abaixo.
dataCoord:
compaction:
clustering:
enable: true
autoEnable: false
triggerInterval: 600
minInterval: 3600
maxInterval: 259200
newDataSizeThreshold: 512m
timeout: 7200
queryNode:
enableSegmentPrune: true
datanode:
clusteringCompaction:
memoryBufferRatio: 0.1
workPoolSize: 8
common:
usePartitionKeyAsClusteringKey: true
Configurar Item |
Descrição |
Valor predefinido |
|---|---|---|
|
||
|
Especifica se a compactação de clusters deve ser activada. Definir este valor para |
false |
|
Especifica se a compactação é activada automaticamente. Definir este valor para |
false |
|
Especifica o intervalo em milissegundos em que o Milvus inicia a compactação do clustering. Isso se aplica apenas quando você define |
|
|
Especifica o intervalo mínimo em milissegundos. Isso se aplica apenas quando você define Definir isso como um número inteiro maior que |
|
|
Especifica o intervalo máximo em milissegundos. Isto aplica-se apenas quando define Quando o Milvus detecta que uma coleção não foi compactada por um período superior a este valor, força uma compactação por clustering. |
|
|
Especifica o limite superior para acionar uma compactação de clustering. Isso se aplica apenas quando você define Quando o Milvus detecta que o volume de dados de uma coleção excede este valor, inicia um processo de compactação em cluster. |
|
|
Especifica a duração do tempo limite para uma compactação de clustering. Uma compactação de agrupamento falha se o tempo de execução exceder esse valor. |
|
|
||
|
Especifica se o Milvus remove os dados consultando o PartitionStats ao receber pedidos de pesquisa/consulta. Defina este valor como |
|
|
||
|
Especifica a taxa de buffer de memória para tarefas de compactação de cluster. O Milvus descarrega os dados quando o tamanho dos dados excede o tamanho do buffer alocado calculado usando essa proporção. |
|
|
Especifica o tamanho do pool de trabalhadores para uma tarefa de compactação de cluster. |
|
|
||
|
Especifica se a chave de partição nas colecções deve ser utilizada como chave de agrupamento. Definir esta opção como true faz com que o Milvus trate as chaves de partição nas colecções como a chave de agrupamento. É sempre possível substituir essa configuração em uma coleção definindo explicitamente uma chave de clustering. |
|
Para aplicar as alterações acima ao seu cluster Milvus, siga os passos em Configurar Milvus com Helm e Configurar Milvus com Milvus Operators.
Configuração da coleção
Para a compactação de clusters numa coleção específica, deve selecionar um campo escalar da coleção como a chave de clustering.
from pymilvus import MilvusClient, DataType
CLUSTER_ENDPOINT="http://localhost:19530"
TOKEN="root:Milvus"
client = MilvusClient(
uri=CLUSTER_ENDPOINT,
token=TOKEN
)
schema = MilvusClient.create_schema()
schema.add_field("id", DataType.INT64, is_primary=True, auto_id=False)
schema.add_field("key", DataType.INT64, is_clustering_key=True)
schema.add_field("var", DataType.VARCHAR, max_length=1000)
schema.add_field("vector", DataType.FLOAT_VECTOR, dim=5)
client.create_collection(
collection_name="clustering_test",
schema=schema
)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.DataType;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("http://localhost:19530")
.token("root:Milvus")
.build());
CreateCollectionReq.CollectionSchema schema = client.createSchema();
schema.addField(AddFieldReq.builder()
.fieldName("id")
.dataType(DataType.Int64)
.isPrimaryKey(true)
.autoID(false)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("key")
.dataType(DataType.Int64)
.isClusteringKey(true)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("var")
.dataType(DataType.VarChar)
.maxLength(1000)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("vector")
.dataType(DataType.FloatVector)
.dimension(5)
.build());
CreateCollectionReq requestCreate = CreateCollectionReq.builder()
.collectionName("clustering_test")
.collectionSchema(schema)
.build();
client.createCollection(requestCreate);
// go
import { MilvusClient, DataType } from '@zilliz/milvus2-sdk-node';
const CLUSTER_ENDPOINT = 'http://localhost:19530';
const TOKEN = 'root:Milvus';
const client = new MilvusClient({
address: CLUSTER_ENDPOINT,
token: TOKEN,
});
const schema = [
{
name: 'id',
type: DataType.Int64,
is_primary_key: true,
autoID: false,
},
{
name: 'key',
type: DataType.Int64,
is_clustering_key: true,
},
{
name: 'var',
type: DataType.VarChar,
max_length: 1000,
is_primary_key: false,
},
{
name: 'vector',
type: DataType.FloatVector,
dim: 5,
},
];
await client.createCollection({
collection_name: 'clustering_test',
schema: schema,
});
# restful
Pode utilizar os campos escalares dos seguintes tipos de dados como chave de agrupamento: Int8, Int16, Int32, Int64, Float, Double, e VarChar.
Acionar Compactação de Clustering
Se tiver ativado a compactação automática do clustering, o Milvus desencadeia automaticamente a compactação no intervalo especificado. Em alternativa, pode desencadear manualmente a compactação da seguinte forma:
# trigger a manual compaction
job_id = client.compact(
collection_name="clustering_test",
is_clustering=True
)
# get the compaction state
client.get_compaction_state(
job_id=job_id,
)
import io.milvus.v2.service.utility.request.CompactReq;
import io.milvus.v2.service.utility.request.GetCompactionStateReq;
import io.milvus.v2.service.utility.response.CompactResp;
import io.milvus.v2.service.utility.response.GetCompactionStateResp;
CompactResp compactResp = client.compact(CompactReq.builder()
.collectionName("clustering_test")
.isClustering(true)
.build());
GetCompactionStateResp stateResp = client.getCompactionState(GetCompactionStateReq.builder()
.compactionID(compactResp.getCompactionID())
.build());
System.out.println(stateResp.getState());
// go
// trigger a manual compaction
const {compactionID} = await client.compact({
collection_name: "clustering_test",
is_clustering: true
});
// get the compaction state
await client.getCompactionState({
compactionID: compactionID,
});
# restful
Teste de benchmark
O volume de dados e os padrões de consulta combinados determinam a melhoria de desempenho que a compactação de clustering pode trazer. Um teste de benchmark interno demonstra que a compactação de clustering produz uma melhoria de até 25 vezes nas consultas por segundo (QPS).
O teste de referência é feito numa coleção que contém entidades de um conjunto de dados LAION de 20 milhões e 768 dimensões, com o campo key designado como a chave de agrupamento. Depois que a compactação de clustering é acionada na coleção, pesquisas simultâneas são enviadas até que o uso da CPU atinja um nível alto de água.
Filtro de pesquisa |
Rácio de poda |
Latência |
Reqs/s |
||||
|---|---|---|---|---|---|---|---|
Média |
Mínimo |
Máximo |
Mediana |
TP99 |
|||
N/A |
0% |
1685 |
672 |
2294 |
1710 |
2291 |
17.75 |
tecla>200 e tecla < 800 |
40.2% |
1045 |
47 |
1828 |
1085 |
1617 |
28.38 |
tecla>200 e tecla < 600 |
59.8% |
829 |
45 |
1483 |
882 |
1303 |
35.78 |
chave>200 e chave < 400 |
79.5% |
550 |
100 |
985 |
584 |
898 |
54.00 |
chave==1000 |
99% |
68 |
24 |
1273 |
70 |
246 |
431.41 |
À medida que o intervalo de pesquisa é reduzido nos filtros de pesquisa, o rácio de poda aumenta. Isto significa que mais entidades são ignoradas durante o processo de pesquisa. Ao comparar as estatísticas na primeira e na última linha, pode ver que as pesquisas sem compactação de clusters requerem a pesquisa de toda a coleção. Por outro lado, as pesquisas com compactação de clusters utilizando uma chave específica podem alcançar uma melhoria de até 25 vezes.
Melhores práticas
Aqui estão algumas dicas para usar a compactação de clustering de forma eficiente:
Habilite-o para coleções com grandes volumes de dados.
O desempenho da pesquisa melhora com volumes de dados maiores em uma coleção. É uma boa opção ativar esta funcionalidade para colecções com mais de 1 milhão de entidades.
Escolha uma chave de agrupamento adequada.
Pode utilizar campos escalares normalmente empregues como condições de filtragem como chave de agrupamento. Para uma coleção que contém dados de vários inquilinos, pode utilizar o campo que distingue um inquilino de outro como chave de agrupamento.
Usar a chave de partição como a chave de clustering.
Pode definir
common.usePartitionKeyAsClusteringKeyparatruese pretender ativar esta funcionalidade para todas as colecções na sua instância Milvus ou se continuar a ter problemas de desempenho numa coleção grande com uma chave de partição. Ao fazê-lo, terá uma chave de agrupamento e uma chave de partição quando escolher um campo escalar numa coleção como chave de partição.Note que esta definição não impede a escolha de outro campo escalar como chave de agrupamento. A chave de clustering explicitamente designada tem sempre precedência.