Использование mmap
Сопоставление памяти (Mmap) обеспечивает прямой доступ из памяти к большим файлам на диске, позволяя Milvus хранить индексы и данные как в памяти, так и на жестких дисках. Такой подход помогает оптимизировать политику размещения данных на основе частоты доступа, увеличивая емкость хранения коллекций без существенного влияния на производительность поиска. Эта страница поможет вам понять, как Milvus использует mmap для обеспечения быстрого и эффективного хранения и извлечения данных.
Обзор
Milvus использует коллекции для организации векторных вкраплений и их метаданных, и каждая строка в коллекции представляет собой объект. Как показано на левом рисунке ниже, в поле vector хранятся векторные вкрапления, а в полях scalar - их метаданные. Когда вы создали индексы по определенным полям и загрузили коллекцию, Milvus загружает созданные индексы и исходные данные полей в память.
Иллюстрация Mmap
Milvus - это система баз данных, занимающая много памяти, и объем доступной памяти определяет емкость коллекции. Загрузка в память полей, содержащих большой объем данных, невозможна, если размер данных превышает объем памяти, что обычно бывает в приложениях, управляемых искусственным интеллектом.
Для решения подобных проблем Milvus вводит mmap для балансировки загрузки "горячих" и "холодных" данных в коллекции. Как показано на правом рисунке выше, вы можете настроить Milvus на отображение в памяти исходных данных в определенных полях вместо их полной загрузки в память. Таким образом, можно получить прямой доступ к полям, не беспокоясь о проблемах с памятью, и расширить емкость коллекции.
Сравнивая процедуры размещения данных на левом и правом рисунках, можно заметить, что на левом рисунке использование памяти гораздо выше, чем на правом. При включенной функции mmap данные, которые должны были быть загружены в память, выгружаются на жесткий диск и кэшируются в страничном кэше операционной системы, что уменьшает занимаемую память. Однако сбои при попадании в кэш могут привести к снижению производительности. Подробности см. в этой статье.
При настройке mmap на Milvus всегда нужно придерживаться одного принципа: Всегда держите часто используемые данные и индексы полностью загруженными в память и используйте mmap для оставшихся полей.
Использование mmap в Milvus
Milvus предоставляет иерархические настройки mmap на глобальном, полевом, индексном и коллекционном уровнях, где индексный и полевой уровни имеют приоритет над коллекционным, а коллекционный - над глобальным.
Глобальные настройки mmap
Настройка на уровне кластера является глобальной и имеет наименьший приоритет. Milvus предоставляет несколько настроек, связанных с mmap, в разделе milvus.yaml. Эти настройки будут применяться ко всем коллекциям в кластере.
...
queryNode:
mmap:
scalarField: false
scalarIndex: false
vectorField: false
vectorIndex: false
# The following should be a path on a high-performance disk
mmapDirPath: any/valid/path
....
Конфигурация Элемент |
Описание |
Значение по умолчанию |
|---|---|---|
|
Указывает, следует ли отображать в память исходные данные всех скалярных полей. Установка этого значения в |
|
|
Указывает, следует ли отображать все индексы скалярных полей в память. Установка этого значения в В настоящее время поддерживаются только скалярные поля со следующим типом индекса:
|
|
|
Указывает, следует ли отображать в память исходные данные всех векторных полей. Установка этого значения в |
|
|
Указывает, следует ли отображать все индексы векторных полей в память. Установка этого значения в В настоящее время поддерживаются только векторные поля, использующие следующие типы индексов:
|
|
|
Указывает путь к файлам с отображением памяти. Если это значение не указано, применяется значение по умолчанию. Место |
|
Чтобы применить вышеуказанные настройки к вашему кластеру Milvus, выполните действия, описанные в разделах "Настройка Milvus с помощью Helm" и "Настройка Milvus с помощью Milvus Operators".
Иногда глобальные настройки mmap не являются гибкими при решении конкретных задач. Чтобы применить альтернативные настройки к конкретной коллекции или ее индексам, рассмотрите возможность настройки mmap для коллекции, поля или индекса. Чтобы изменения настроек mmap вступили в силу, необходимо выпустить и загрузить коллекцию.
Настройки mmap для конкретного поля
Чтобы настроить mmap для конкретного поля, необходимо включить параметр mmap_enabled при добавлении поля. Вы можете включить mmap для этого конкретного поля, установив для этого параметра значение True.
В следующем примере показано, как настроить mmap для конкретного поля при добавлении поля.
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("vector", DataType.FLOAT_VECTOR, dim=5)
schema = MilvusClient.create_schema()
# Add a scalar field and enable mmap
schema.add_field(
field_name="doc_chunk",
datatype=DataType.INT64,
is_primary=True,
mmap_enabled=True,
)
# Alter mmap settings on a specific field
# The following assumes that you have a collection named `my_collection`
client.alter_collection_field(
collection_name="my_collection",
field_name="doc_chunk",
field_params={"mmap.enabled": True}
)
import io.milvus.param.Constant;
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.*;
import java.util.*;
String CLUSTER_ENDPOINT = "http://localhost:19530";
String TOKEN = "root:Milvus";
client = new MilvusClientV2(ConnectConfig.builder()
.uri(CLUSTER_ENDPOINT)
.token(TOKEN)
.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("vector")
.dataType(DataType.FloatVector)
.dimension(5)
.build());
Map<String, String> typeParams = new HashMap<String, String>() {{
put(Constant.MMAP_ENABLED, "false");
}};
schema.addField(AddFieldReq.builder()
.fieldName("doc_chunk")
.dataType(DataType.VarChar)
.maxLength(512)
.typeParams(typeParams)
.build());
CreateCollectionReq req = CreateCollectionReq.builder()
.collectionName("my_collection")
.collectionSchema(schema)
.build();
client.createCollection(req);
client.alterCollectionField(AlterCollectionFieldReq.builder()
.collectionName("my_collection")
.fieldName("doc_chunk")
.property(Constant.MMAP_ENABLED, "true")
.build());
import { MilvusClient, DataType } from '@zilliz/milvus2-sdk-node';
const CLUSTER_ENDPOINT="YOUR_CLUSTER_ENDPOINT";
const TOKEN="YOUR_TOKEN";
const client = await MilvusClient({
address: CLUSTER_ENDPOINT,
token: TOKEN
});
const schema = [
{
name: 'vector',
data_type: DataType.FloatVector
},
{
name: "doc_chunk",
data_type: DataType.VarChar,
max_length: 512,
'mmap.enabled': false,
}
];
await client.createCollection({
collection_name: "my_collection",
schema: schema
});
await client.alterCollectionFieldProperties({
collection_name: "my_collection",
field_name: "doc_chunk",
properties: {"mmap_enable": true}
});
// go
#restful
export TOKEN="root:Milvus"
export CLUSTER_ENDPOINT="http://localhost:19530"
export idField='{
"fieldName": "id",
"dataType": "Int64",
"elementTypeParams": {
"max_length": 512
},
"isPrimary": true,
"auto_id": false
}'
export vectorField='{
"fieldName": "vector",
"dataType": "FloatVector",
"elementTypeParams": {
"dim": 5
}
}'
export docChunkField='{
"fieldName": "doc_chunk",
"dataType": "Int64",
"elementTypeParams": {
"max_length": 512,
"mmap.enabled": false
}
}'
export schema="{
\"autoID\": false,
\"fields\": [
$idField,
$docChunkField,
$vectorField
]
}"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--data "{
\"collectionName\": \"my_collection\",
\"schema\": $schema
}"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/fields/alter_properties" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"collectionName": "my_collection",
"fieldName": "doc_chunk",
"fieldParams":{
"mmap.enabled": true
}
}'
Рассмотрите возможность включения mmap для полей, в которых хранятся данные большого объема. Поддерживаются как скалярные, так и векторные поля.
Затем вы можете создать коллекцию, используя созданную выше схему. При получении запроса на загрузку коллекции Milvus использует memory-map для размещения в памяти исходных данных поля doc_chunk.
Настройки mmap для конкретного индекса
Чтобы настроить mmap для конкретного индекса, необходимо включить свойство mmap.enable в параметры индекса при добавлении индекса. Вы можете включить mmap для этого конкретного индекса, установив для свойства значение true.
В следующем примере показано, как настроить mmap для конкретного индекса при добавлении индекса.
# Add a varchar field
schema.add_field(
field_name="title",
datatype=DataType.VARCHAR,
max_length=512
)
index_params = MilvusClient.prepare_index_params()
# Create index on the varchar field with mmap settings
index_params.add_index(
field_name="title",
index_type="AUTOINDEX",
params={ "mmap.enabled": "false" }
)
# Change mmap settings for an index
# The following assumes that you have a collection named `my_collection`
client.alter_index_properties(
collection_name="my_collection",
index_name="title",
properties={"mmap.enabled": True}
)
schema.addField(AddFieldReq.builder()
.fieldName("title")
.dataType(DataType.VarChar)
.maxLength(512)
.build());
List<IndexParam> indexParams = new ArrayList<>();
Map<String, Object> extraParams = new HashMap<String, Object>() {{
put(Constant.MMAP_ENABLED, false);
}};
indexParams.add(IndexParam.builder()
.fieldName("title")
.indexType(IndexParam.IndexType.AUTOINDEX)
.extraParams(extraParams)
.build());
client.alterIndexProperties(AlterIndexPropertiesReq.builder()
.collectionName("my_collection")
.indexName("title")
.property(Constant.MMAP_ENABLED, "true")
.build());
// Create index on the varchar field with mmap settings
await client.createIndex({
collection_name: "my_collection",
field_name: "title",
params: { "mmap.enabled": false }
});
// Change mmap settings for an index
// The following assumes that you have a collection named `my_collection`
await client.alterIndexProperties({
collection_name: "my_collection",
index_name: "title",
properties:{"mmap.enabled": true}
});
// go
# restful
export TOKEN="root:Milvus"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/indexes/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"collectionName": "my_collection",
"indexParams": [
{
"fieldName": "doc_chunk",
"params": {
"index_type": "AUTOINDEX",
"mmap.enabled": true
}
}
]
}'
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/indexes/alter_properties" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"collectionName": "my_collection",
"indexName": "doc_chunk",
"properties": {
"mmap.enabled": false
}
}'
Это относится к индексам как векторных, так и скалярных полей.
Затем вы можете ссылаться на параметры индекса в коллекции. При получении запроса на загрузку коллекции Milvus заносит в память индекс поля title.
Настройки mmap для конкретной коллекции
Чтобы настроить стратегию mmap для всей коллекции, необходимо включить свойство mmap.enabled в запрос на создание коллекции. Вы можете включить mmap для коллекции, установив для этого свойства значение true.
Следующий пример демонстрирует, как включить mmap в коллекции с именем my_collection при ее создании. Получив запрос на загрузку коллекции, Milvus отображает в памяти исходные данные всех полей.
# Enable mmap when creating a collection
client.create_collection(
collection_name="my_collection",
schema=schema,
properties={ "mmap.enabled": "true" }
)
CreateCollectionReq req = CreateCollectionReq.builder()
.collectionName("my_collection")
.collectionSchema(schema)
.property(Constant.MMAP_ENABLED, "false")
.build();
client.createCollection(req);
await client.createCollection({
collection_name: "my_collection",
scheme: schema,
properties: { "mmap.enabled": false }
});
// go
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--data "{
\"collectionName\": \"my_collection\",
\"schema\": $schema,
\"params\": {
\"mmap.enabled\": \"false\"
}
}"
Вы также можете изменить настройки mmap для существующей коллекции.
# Release collection before change mmap settings
client.release_collection("my_collection")
# Ensure that the collection has already been released
# and run the following
client.alter_collection_properties(
collection_name="my_collection",
properties={
"mmap.enabled": false
}
)
# Load the collection to make the above change take effect
client.load_collection("my_collection")
client.releaseCollection(ReleaseCollectionReq.builder()
.collectionName("my_collection")
.build());
client.alterCollectionProperties(AlterCollectionPropertiesReq.builder()
.collectionName("my_collection")
.property(Constant.MMAP_ENABLED, "false")
.build());
client.loadCollection(LoadCollectionReq.builder()
.collectionName("my_collection")
.build());
// Release collection before change mmap settings
await client.releaseCollection({
collection_name: "my_collection"
});
// Ensure that the collection has already been released
// and run the following
await client.alterCollectionProperties({
collection_name: "my_collection",
properties: {
"mmap.enabled": false
}
});
// Load the collection to make the above change take effect
await client.loadCollection({
collection_name: "my_collection"
});
// go
# restful
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/release" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"collectionName": "my_collection"
}'
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/alter_properties" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"collectionName": "my_collection",
"properties": {
"mmmap.enabled": false
}
}'
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/load" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"collectionName": "my_collection"
}'
Чтобы внести изменения в свойства коллекции, ее нужно освободить, а чтобы изменения вступили в силу - перезагрузить.