Clustering-Verdichtung
Clustering Compaction wurde entwickelt, um die Suchleistung zu verbessern und die Kosten in großen Sammlungen zu reduzieren. In diesem Handbuch erfahren Sie, wie Sie die Clustering-Verdichtung nutzen können, um die Suchleistung zu verbessern.
Überblick
Milvus speichert eingehende Entitäten in Segmenten innerhalb einer Sammlung und versiegelt ein Segment, wenn es voll ist. Wenn dies der Fall ist, wird ein neues Segment erstellt, um zusätzliche Entitäten unterzubringen. Infolgedessen sind die Entitäten willkürlich über die Segmente verteilt. Diese Verteilung erfordert, dass Milvus mehrere Segmente durchsucht, um die nächsten Nachbarn für einen bestimmten Abfragevektor zu finden.
Ohne Clustering-Verdichtung
Wenn Milvus die Entitäten auf der Grundlage der Werte in einem bestimmten Feld auf die Segmente verteilen kann, lässt sich der Suchbereich innerhalb eines Segments einschränken, wodurch die Suchleistung verbessert wird.
Clustering Compaction ist eine Funktion in Milvus, die Entitäten zwischen Segmenten in einer Sammlung basierend auf den Werten in einem skalaren Feld umverteilt. Um diese Funktion zu aktivieren, müssen Sie zunächst ein skalares Feld als Clustering-Schlüssel auswählen. Dies ermöglicht Milvus, Entitäten in ein Segment umzuverteilen, wenn ihre Clustering-Schlüsselwerte in einen bestimmten Bereich fallen. Wenn Sie eine Clustering Compaction auslösen, generiert/aktualisiert Milvus einen globalen Index namens PartitionStats, der die Zuordnungsbeziehung zwischen Segmenten und Clustering-Schlüsselwerten aufzeichnet.
Clustering-Verdichtung
Unter Verwendung von PartitionStats als Referenz kann Milvus beim Empfang einer Such-/Abfrageanfrage, die einen Clustering-Schlüsselwert enthält, irrelevante Daten entfernen und den Suchbereich innerhalb der Segmente, die dem Wert zugeordnet sind, einschränken, wodurch die Suchleistung verbessert wird. Einzelheiten zur Leistungsverbesserung finden Sie unter Benchmark-Tests.
Clustering-Verdichtung verwenden
Die Clustering Compaction Funktion in Milvus ist in hohem Maße konfigurierbar. Sie können sie manuell auslösen oder sie so einstellen, dass sie automatisch in bestimmten Abständen von Milvus ausgelöst wird. Um die Clustering Compaction zu aktivieren, gehen Sie wie folgt vor:
Globale Konfiguration
Sie müssen Ihre Milvus-Konfigurationsdatei wie unten gezeigt ändern.
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
Konfigurieren Element |
Beschreibung |
Standardwert |
|---|---|---|
|
||
|
Gibt an, ob die Clustering-Verdichtung aktiviert werden soll. Setzen Sie dies auf |
false |
|
Legt fest, ob die automatisch ausgelöste Verdichtung aktiviert werden soll. Wenn Sie diesen Wert auf |
false |
|
Gibt das Intervall in Millisekunden an, in dem Milvus die Clustering-Kompaktierung startet. Dies gilt nur, wenn Sie |
|
|
Legt das Mindestintervall in Millisekunden fest. Dies gilt nur, wenn Sie Wenn Sie diesen Wert auf eine ganze Zahl größer als |
|
|
Legt das maximale Intervall in Millisekunden fest. Dies gilt nur, wenn Sie Sobald Milvus feststellt, dass eine Sammlung länger als diesen Wert nicht verdichtet wurde, erzwingt es eine Clusterverdichtung. |
|
|
Gibt den oberen Schwellenwert für die Auslösung einer Clustering-Kompaktierung an. Dies gilt nur, wenn Sie Sobald Milvus feststellt, dass das Datenvolumen in einer Sammlung diesen Wert überschreitet, wird ein Clustering-Compaction-Prozess eingeleitet. |
|
|
Gibt die Timeout-Dauer für eine Clustering-Compaction an. Eine Clustering-Compaction schlägt fehl, wenn ihre Ausführungszeit diesen Wert überschreitet. |
|
|
||
|
Gibt an, ob Milvus beim Empfang von Such-/Abfrageanfragen Daten durch Verweis auf PartitionStats bereinigt. Setzen Sie diesen Wert auf |
|
|
||
|
Legt das Speicherpufferverhältnis für Clustering-Verdichtungsaufgaben fest. Milvus löscht Daten, wenn die Datengröße die zugewiesene Puffergröße überschreitet, die mit diesem Verhältnis berechnet wurde. |
|
|
Legt die Größe des Worker-Pools für eine Clustering-Compaction-Task fest. |
|
|
||
|
Legt fest, ob der Partitionsschlüssel in Sammlungen als Clustering-Schlüssel verwendet werden soll. Wenn Sie dies auf true setzen, behandelt Milvus die Partitionsschlüssel in Sammlungen als Clustering-Schlüssel. Sie können diese Einstellung in einer Sammlung jederzeit außer Kraft setzen, indem Sie explizit einen Clustering-Schlüssel festlegen. |
|
Um die oben genannten Änderungen auf Ihren Milvus-Cluster anzuwenden, folgen Sie bitte den Schritten in Konfigurieren von Milvus mit Helm und Konfigurieren von Milvus mit Milvus Operators.
Konfiguration der Sammlung
Für die Clusterverdichtung in einer bestimmten Sammlung sollten Sie ein skalares Feld aus der Sammlung als Clustering-Schlüssel auswählen.
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
Sie können die Skalarfelder der folgenden Datentypen als Clustering-Schlüssel verwenden: Int8, Int16, Int32, Int64, Float, Double, und VarChar.
Clustering-Verdichtung auslösen
Wenn Sie die automatische Clustering-Verdichtung aktiviert haben, löst Milvus die Verdichtung automatisch in dem angegebenen Intervall aus. Alternativ dazu können Sie die Verdichtung wie folgt manuell auslösen:
# 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
Benchmark-Test
Das Datenvolumen und die Abfragemuster zusammen bestimmen die Leistungsverbesserung, die die Clusterverdichtung bringen kann. Ein interner Benchmark-Test zeigt, dass die Clustering-Kompaktierung eine bis zu 25-fache Verbesserung der Abfragen pro Sekunde (QPS) ermöglicht.
Der Benchmark-Test wird mit einer Sammlung von Entitäten aus einem 20 Millionen, 768-dimensionalen LAION-Datensatz durchgeführt, wobei das Feld key als Clustering-Schlüssel dient. Nachdem die Clustering-Verdichtung in der Sammlung ausgelöst wurde, werden gleichzeitige Suchanfragen gesendet, bis die CPU-Auslastung einen hohen Pegel erreicht.
Suchfilter |
Prune-Verhältnis |
Latenz |
Anfragen/s |
||||
|---|---|---|---|---|---|---|---|
Avg |
Min |
Max |
Median |
TP99 |
|||
N/A |
0% |
1685 |
672 |
2294 |
1710 |
2291 |
17.75 |
Schlüssel>200 und Schlüssel < 800 |
40.2% |
1045 |
47 |
1828 |
1085 |
1617 |
28.38 |
Schlüssel>200 und Schlüssel < 600 |
59.8% |
829 |
45 |
1483 |
882 |
1303 |
35.78 |
Schlüssel>200 und Schlüssel < 400 |
79.5% |
550 |
100 |
985 |
584 |
898 |
54.00 |
Schlüssel==1000 |
99% |
68 |
24 |
1273 |
70 |
246 |
431.41 |
Je enger der Suchbereich in den Suchfiltern ist, desto höher ist die Prune-Rate. Das bedeutet, dass mehr Entitäten während des Suchvorgangs übersprungen werden. Ein Vergleich der Statistiken in der ersten und letzten Zeile zeigt, dass bei einer Suche ohne Clustering-Verdichtung die gesamte Sammlung durchsucht werden muss. Andererseits kann eine Suche mit Clustering-Verdichtung unter Verwendung eines bestimmten Schlüssels eine bis zu 25-fache Verbesserung erzielen.
Beste Praktiken
Im Folgenden finden Sie einige Tipps zur effizienten Nutzung der Clustering-Kompaktierung:
Aktivieren Sie diese Funktion für Sammlungen mit großen Datenmengen.
Die Suchleistung verbessert sich mit größeren Datenmengen in einer Sammlung. Es ist eine gute Wahl, diese Funktion für Sammlungen mit mehr als 1 Million Entitäten zu aktivieren.
Wählen Sie einen geeigneten Clustering-Schlüssel.
Sie können skalare Felder, die üblicherweise als Filterbedingungen verwendet werden, als Clustering-Schlüssel verwenden. Für eine Sammlung, die Daten von mehreren Tenants enthält, können Sie das Feld, das einen Tenant von einem anderen unterscheidet, als Clustering-Schlüssel verwenden.
Verwenden Sie den Partitionsschlüssel als Clustering-Schlüssel.
Sie können
common.usePartitionKeyAsClusteringKeyauftruesetzen, wenn Sie diese Funktion für alle Sammlungen in Ihrer Milvus-Instanz aktivieren möchten oder wenn Sie in einer großen Sammlung mit einem Partitionsschlüssel immer noch Leistungsprobleme haben. Auf diese Weise haben Sie einen Clustering-Schlüssel und einen Partitionsschlüssel, wenn Sie ein skalares Feld in einer Sammlung als Partitionsschlüssel wählen.Beachten Sie, dass diese Einstellung Sie nicht daran hindert, ein anderes skalares Feld als Clustering-Schlüssel zu wählen. Der explizit angegebene Clustering-Schlüssel hat immer Vorrang.