Кластерное уплотнение
Функция уплотнения кластеров предназначена для повышения производительности поиска и снижения затрат в больших коллекциях. Это руководство поможет вам понять, что такое уплотнение кластеров и как эта функция может повысить производительность поиска.
Обзор
Milvus хранит входящие сущности в сегментах коллекции и уплотняет сегмент, когда он переполнен. Если это происходит, создается новый сегмент для размещения дополнительных сущностей. В результате сущности произвольно распределяются по сегментам. Такое распределение требует от Milvus поиска в нескольких сегментах ближайших соседей для заданного вектора запроса.
Без уплотнения кластеризации
Если Milvus может распределить сущности между сегментами на основе значений в определенном поле, область поиска может быть ограничена одним сегментом, что повышает производительность поиска.
Clustering Compaction - это функция в Milvus, которая перераспределяет сущности между сегментами в коллекции на основе значений в скалярном поле. Чтобы включить эту функцию, сначала нужно выбрать скалярное поле в качестве ключа кластеризации. Это позволит Milvus перераспределять сущности в сегмент, если значения их ключа кластеризации попадают в определенный диапазон. Когда вы запускаете уплотнение кластеризации, Milvus генерирует/обновляет глобальный индекс PartitionStats, который записывает отношения сопоставления между сегментами и значениями ключей кластеризации.
Компактизация кластеризации
Используя PartitionStats в качестве ссылки, Milvus может отсеивать нерелевантные данные при получении запроса на поиск/запрос, содержащего значение ключа кластеризации, и ограничивать область поиска сегментами, сопоставленными с этим значением, тем самым повышая производительность поиска. Подробнее об улучшении производительности см. в разделе "Бенчмарк-тесты".
Использование уплотнения кластеров
Функция Clustering Compaction в Milvus является очень настраиваемой. Вы можете запустить ее вручную или настроить ее автоматическое включение через определенные промежутки времени с помощью Milvus. Чтобы включить уплотнение кластеров, выполните следующие действия:
Глобальная конфигурация
Вам необходимо изменить конфигурационный файл Milvus, как показано ниже.
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
Конфигурация Элемент |
Описание |
Значение по умолчанию |
|---|---|---|
|
||
|
Указывает, включать ли уплотнение кластеризации. Установите значение |
false |
|
Указывает, следует ли включать автоматически запускаемое уплотнение. Значение |
false |
|
Указывает интервал в миллисекундах, через который Milvus начинает уплотнение кластеров. Это применимо, только если вы установили |
|
|
Указывает минимальный интервал в миллисекундах. Применяется только при задании Установка целого числа, большего, чем |
|
|
Указывает максимальный интервал в миллисекундах. Применяется только при установке значений Если Milvus обнаруживает, что коллекция не была уплотнена в течение периода, превышающего это значение, он принудительно выполняет уплотнение. |
|
|
Указывает верхний порог для запуска кластерного уплотнения. Это применимо только в том случае, если вы установили значение Как только Milvus обнаружит, что объем данных в коллекции превышает это значение, он инициирует процесс кластерного уплотнения. |
|
|
Указывает длительность таймаута для кластерного уплотнения. Кластерное уплотнение завершается неудачей, если время его выполнения превышает это значение. |
|
|
||
|
Указывает, будет ли Milvus обрезать данные, обращаясь к PartitionStats при получении запросов поиска/запроса. Установите значение |
|
|
||
|
Указывает соотношение буферов памяти для задач уплотнения кластеризации. Milvus удаляет данные, когда размер данных превышает размер выделенного буфера, рассчитанный с помощью этого соотношения. |
|
|
Указывает размер рабочего пула для задачи кластерного уплотнения. |
|
|
||
|
Указывает, использовать ли ключ раздела в коллекциях в качестве ключа кластеризации. Если установить значение true, Milvus будет использовать ключи разделов в коллекциях в качестве ключа кластеризации. Вы всегда можете отменить эту настройку в коллекции, явно задав ключ кластеризации. |
|
Чтобы применить вышеуказанные изменения к кластеру Milvus, выполните шаги в разделах Настройка Milvus с помощью Helm и Настройка Milvus с помощью Milvus Operators.
Конфигурация коллекции
Для уплотнения кластера в определенной коллекции необходимо выбрать скалярное поле из коллекции в качестве ключа кластеризации.
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
В качестве ключа кластеризации можно использовать скалярные поля следующих типов данных: Int8, Int16, Int32, Int64, Float, Double и VarChar.
Запуск уплотнения кластеризации
Если вы включили автоматическое уплотнение кластеризации, Milvus автоматически запускает уплотнение через указанный интервал времени. В качестве альтернативы вы можете вручную запустить уплотнение следующим образом:
# 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
Тест бенчмарка
Объем данных и шаблоны запросов в совокупности определяют повышение производительности кластерного уплотнения. Внутренний эталонный тест демонстрирует, что уплотнение кластеризации дает 25-кратное улучшение запросов в секунду (QPS).
Эталонный тест проводился на коллекции, содержащей сущности из 20-миллионного 768-мерного набора данных LAION с полем key, назначенным в качестве ключа кластеризации. После запуска кластерного уплотнения в коллекции отправляются одновременные запросы до тех пор, пока загрузка процессора не достигнет высокого уровня.
Фильтр поиска |
Коэффициент отсева |
Латентность |
Запросы/с |
||||
|---|---|---|---|---|---|---|---|
Avg |
Min |
Max |
Медиана |
TP99 |
|||
N/A |
0% |
1685 |
672 |
2294 |
1710 |
2291 |
17.75 |
ключ>200 и ключ < 800 |
40.2% |
1045 |
47 |
1828 |
1085 |
1617 |
28.38 |
ключ>200 и ключ < 600 |
59.8% |
829 |
45 |
1483 |
882 |
1303 |
35.78 |
ключ>200 и ключ < 400 |
79.5% |
550 |
100 |
985 |
584 |
898 |
54.00 |
ключ==1000 |
99% |
68 |
24 |
1273 |
70 |
246 |
431.41 |
По мере сужения диапазона поиска в фильтрах поиска коэффициент обрезки увеличивается. Это означает, что в процессе поиска пропускается больше сущностей. Сравнивая статистику в первой и последней строках, можно заметить, что поиск без уплотнения кластеров требует сканирования всей коллекции. С другой стороны, поиск с уплотнением кластеризации по определенному ключу позволяет добиться 25-кратного улучшения.
Лучшие практики
Вот несколько советов по эффективному использованию кластерного уплотнения:
Включите эту функцию для коллекций с большими объемами данных.
Производительность поиска повышается при увеличении объема данных в коллекции. Лучше всего включать эту функцию для коллекций, содержащих более 1 миллиона сущностей.
Выберите подходящий ключ кластеризации.
В качестве ключа кластеризации можно использовать скалярные поля, обычно используемые в качестве условий фильтрации. Для коллекции, содержащей данные от нескольких арендаторов, в качестве ключа кластеризации можно использовать поле, которое отличает одного арендатора от другого.
Используйте ключ раздела в качестве ключа кластеризации.
Вы можете установить
common.usePartitionKeyAsClusteringKeyнаtrue, если хотите включить эту функцию для всех коллекций в вашем экземпляре Milvus или если вы все еще сталкиваетесь с проблемами производительности в большой коллекции с ключом раздела. В этом случае у вас будет ключ кластеризации и ключ раздела, когда вы выбираете скалярное поле в коллекции в качестве ключа раздела.Обратите внимание, что эта настройка не мешает выбрать другое скалярное поле в качестве ключа кластеризации. Явно указанный ключ кластеризации всегда имеет приоритет.